Merge jdk9-b32
authorduke
Wed, 05 Jul 2017 20:01:50 +0200
changeset 26668 1b1ec4291abc
parent 26667 66b7d29b75f7 (diff)
parent 26543 89a653341cf2 (current diff)
child 26669 614ec4af7a80
child 26670 95afe8fb7581
child 26671 b214ab286ce9
child 26679 66ba197c2cd7
child 26710 e9c76272cd40
child 26713 632cd739f13b
child 26714 3caa40031b3f
child 26761 763f7ca2eadc
child 26763 62630474e088
child 26764 c777787a937d
child 26772 d82c879893c6
child 26774 9c411ee585b3
child 26775 810bea25280c
child 26778 1366778aa6f3
child 26779 5437f17cbf69
child 26790 d0a247d1f2a8
Merge
--- a/.hgtags-top-repo	Wed Jul 05 20:01:05 2017 +0200
+++ b/.hgtags-top-repo	Wed Jul 05 20:01:50 2017 +0200
@@ -273,3 +273,4 @@
 ea2f7981236f3812436958748ab3d26e80a35130 jdk9-b28
 9e6581aeda388a23fbee021fc33e6aa152a60657 jdk9-b29
 36e9bc875325813ac9c44ac0c617a463091fa9f5 jdk9-b30
+69a84c16d9c28e0e3d504b9c8766c24bafcd58f6 jdk9-b31
--- a/Makefile	Wed Jul 05 20:01:05 2017 +0200
+++ b/Makefile	Wed Jul 05 20:01:50 2017 +0200
@@ -70,8 +70,8 @@
   # Run the makefile with an arbitrary SPEC using -p -q (quiet dry-run and dump rules) to find
   # available PHONY targets. Use this list as valid targets to pass on to the repeated calls.
   all_phony_targets := $(sort $(filter-out $(global_targets), $(strip $(shell \
-      cd $(root_dir)/make && $(MAKE) -f Main.gmk -p -q FRC SPEC=$(firstword $(SPEC)) | \
-      grep "^.PHONY:" | head -n 1 | cut -d " " -f 2-))))
+      cd $(root_dir)/make && $(MAKE) -f Main.gmk -p -q FRC SPEC=$(firstword $(SPEC)) \
+      -I $(root_dir)/make/common | grep "^.PHONY:" | head -n 1 | cut -d " " -f 2-))))
 
   # Loop through the configurations and call the main-wrapper for each one. The wrapper
   # target will execute with a single configuration loaded.
@@ -115,12 +115,12 @@
 
     main-wrapper:
         ifneq ($(SEQUENTIAL_TARGETS), )
-	  (cd $(root_dir)/make && $(MAKE) -f Main.gmk SPEC=$(SPEC) -j 1 \
+	  (cd $(SRC_ROOT)/make && $(MAKE) -f Main.gmk SPEC=$(SPEC) -j 1 \
 	      $(VERBOSE) VERBOSE=$(VERBOSE) LOG_LEVEL=$(LOG_LEVEL) $(SEQUENTIAL_TARGETS))
         endif
         ifneq ($(PARALLEL_TARGETS), )
 	  @$(call AtMakeStart)
-	  (cd $(root_dir)/make && $(BUILD_LOG_WRAPPER) $(MAKE) -f Main.gmk SPEC=$(SPEC) -j $(JOBS) \
+	  (cd $(SRC_ROOT)/make && $(BUILD_LOG_WRAPPER) $(MAKE) -f Main.gmk SPEC=$(SPEC) -j $(JOBS) \
 	      $(VERBOSE) VERBOSE=$(VERBOSE) LOG_LEVEL=$(LOG_LEVEL) $(PARALLEL_TARGETS) \
 	      $(if $(filter true, $(OUTPUT_SYNC_SUPPORTED)), -O$(OUTPUT_SYNC)))
 	  @$(call AtMakeEnd)
--- a/common/autoconf/generated-configure.sh	Wed Jul 05 20:01:05 2017 +0200
+++ b/common/autoconf/generated-configure.sh	Wed Jul 05 20:01:50 2017 +0200
@@ -4327,7 +4327,7 @@
 #CUSTOM_AUTOCONF_INCLUDE
 
 # Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1410377275
+DATE_WHEN_GENERATED=1410791401
 
 ###############################################################################
 #
@@ -14642,7 +14642,7 @@
       FASTDEBUG="false"
       DEBUG_CLASSFILES="true"
       BUILD_VARIANT_RELEASE="-debug"
-      HOTSPOT_DEBUG_LEVEL="jvmg"
+      HOTSPOT_DEBUG_LEVEL="debug"
       HOTSPOT_EXPORT="debug"
       ;;
     optimized )
--- a/common/autoconf/hotspot-spec.gmk.in	Wed Jul 05 20:01:05 2017 +0200
+++ b/common/autoconf/hotspot-spec.gmk.in	Wed Jul 05 20:01:50 2017 +0200
@@ -97,8 +97,6 @@
 endif
 
 HOTSPOT_MAKE_ARGS:=@HOTSPOT_MAKE_ARGS@ @STATIC_CXX_SETTING@
-# This is used from the libjvm build for C/C++ code.
-HOTSPOT_BUILD_JOBS:=$(JOBS)
 # Control wether Hotspot runs Queens test after building
 TEST_IN_BUILD=@TEST_IN_BUILD@
 
--- a/common/autoconf/jdk-options.m4	Wed Jul 05 20:01:05 2017 +0200
+++ b/common/autoconf/jdk-options.m4	Wed Jul 05 20:01:50 2017 +0200
@@ -234,7 +234,7 @@
       FASTDEBUG="false"
       DEBUG_CLASSFILES="true"
       BUILD_VARIANT_RELEASE="-debug"
-      HOTSPOT_DEBUG_LEVEL="jvmg"
+      HOTSPOT_DEBUG_LEVEL="debug"
       HOTSPOT_EXPORT="debug"
       ;;
     optimized )
--- a/common/autoconf/spec.gmk.in	Wed Jul 05 20:01:05 2017 +0200
+++ b/common/autoconf/spec.gmk.in	Wed Jul 05 20:01:50 2017 +0200
@@ -245,6 +245,7 @@
 NASHORN_OUTPUTDIR=$(BUILD_OUTPUT)/nashorn
 IMAGES_OUTPUTDIR=$(BUILD_OUTPUT)/images
 TESTMAKE_OUTPUTDIR=$(BUILD_OUTPUT)/testmake
+MAKESUPPORT_OUTPUTDIR=$(BUILD_OUTPUT)/make-support
 
 LANGTOOLS_DIST=$(LANGTOOLS_OUTPUTDIR)/dist
 CORBA_DIST=$(CORBA_OUTPUTDIR)/dist
--- a/common/bin/unshuffle_list.txt	Wed Jul 05 20:01:05 2017 +0200
+++ b/common/bin/unshuffle_list.txt	Wed Jul 05 20:01:50 2017 +0200
@@ -1216,14 +1216,13 @@
 jdk/src/java.security.acl/share/classes/sun/security/acl : jdk/src/share/classes/sun/security/acl
 jdk/src/java.security.jgss/macosx/native/libosxkrb5/nativeccache.c : jdk/src/share/native/sun/security/krb5/nativeccache.c
 jdk/src/java.security.jgss/macosx/native/libosxkrb5/SCDynamicStoreConfig.m : jdk/src/macosx/native/sun/security/krb5/SCDynamicStoreConfig.m
-jdk/src/java.security.jgss/share/classes/com/sun/security/jgss : jdk/src/share/classes/com/sun/security/jgss
-jdk/src/java.security.jgss/share/classes/com/sun/security/sasl/gsskerb : jdk/src/share/classes/com/sun/security/sasl/gsskerb
 jdk/src/java.security.jgss/share/classes/javax/security/auth/kerberos : jdk/src/share/classes/javax/security/auth/kerberos
 jdk/src/java.security.jgss/share/classes/jgss-overview.html : jdk/src/share/classes/com/sun/security/jgss/jgss-overview.html
 jdk/src/java.security.jgss/share/classes/org/ietf/jgss : jdk/src/share/classes/org/ietf/jgss
 jdk/src/java.security.jgss/share/classes/sun/net/www/protocol/http/spnego : jdk/src/share/classes/sun/net/www/protocol/http/spnego
 jdk/src/java.security.jgss/share/classes/sun/security/jgss : jdk/src/share/classes/sun/security/jgss
 jdk/src/java.security.jgss/share/classes/sun/security/krb5 : jdk/src/share/classes/sun/security/krb5
+jdk/src/java.security.jgss/windows/classes/sun/security/krb5 : jdk/src/windows/classes/sun/security/krb5
 jdk/src/java.security.jgss/share/classes/sun/security/ssl/krb5 : jdk/src/share/classes/sun/security/ssl/krb5
 jdk/src/java.security.jgss/share/native/libj2gss : jdk/src/share/native/sun/security/jgss/wrapper
 jdk/src/java.security.jgss/unix/native/libj2gss : jdk/src/solaris/native/sun/security/jgss/wrapper
@@ -1477,6 +1476,8 @@
 jdk/src/jdk.security.auth/share/classes/jaas-overview.html : jdk/src/share/classes/com/sun/security/auth/jaas-overview.html
 jdk/src/jdk.security.auth/unix/native/libjaas : jdk/src/solaris/native/com/sun/security/auth/module
 jdk/src/jdk.security.auth/windows/native/libjaas : jdk/src/windows/native/com/sun/security/auth/module
+jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss : jdk/src/share/classes/com/sun/security/jgss
+jdk/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb : jdk/src/share/classes/com/sun/security/sasl/gsskerb
 jdk/src/jdk.snmp/share/classes/com/sun/jmx/snmp : jdk/src/share/classes/com/sun/jmx/snmp
 jdk/src/jdk.snmp/share/classes/sun/management/snmp : jdk/src/share/classes/sun/management/snmp
 jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs : jdk/src/share/classes/jdk/nio/zipfs
--- a/corba/.hgtags	Wed Jul 05 20:01:05 2017 +0200
+++ b/corba/.hgtags	Wed Jul 05 20:01:50 2017 +0200
@@ -273,3 +273,4 @@
 a00b04ef067e39f50b9a0fea6f1904e35d632a73 jdk9-b28
 163a9cd806fd09970baf1f5f42b92a3cfe7ee945 jdk9-b29
 98967ae6ae53ebf15615e07cd5a6b1ae04dfd84c jdk9-b30
+c432b80aadd0cb2b2361b02add4d671957d4cec9 jdk9-b31
--- a/hotspot/.hgtags	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/.hgtags	Wed Jul 05 20:01:50 2017 +0200
@@ -433,3 +433,4 @@
 657294869d7ff063e055f5492cab7ce5612ca851 jdk9-b28
 deb29e92f68ace2808a36ecfa18c7d61dcb645bb jdk9-b29
 5c722dffbc0f34eb8d903dca7b261e52248fa17e jdk9-b30
+9f7d155d28e519f3e4645dc21cf185c25f3176ed jdk9-b31
--- a/hotspot/agent/src/os/win32/windbg/sawindbg.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/agent/src/os/win32/windbg/sawindbg.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -112,7 +112,9 @@
  return;}
 
 static void throwNewDebuggerException(JNIEnv* env, const char* errMsg) {
-  env->ThrowNew(env->FindClass("sun/jvm/hotspot/debugger/DebuggerException"), errMsg);
+  jclass clazz = env->FindClass("sun/jvm/hotspot/debugger/DebuggerException");
+  CHECK_EXCEPTION;
+  env->ThrowNew(clazz, errMsg);
 }
 
 /*
@@ -310,15 +312,18 @@
 static bool setImageAndSymbolPath(JNIEnv* env, jobject obj) {
   jboolean isCopy;
   jclass clazz = env->GetObjectClass(obj);
+  CHECK_EXCEPTION_(false);
   jstring path;
   const char* buf;
 
   path = (jstring) env->GetStaticObjectField(clazz, imagePath_ID);
+  CHECK_EXCEPTION_(false);
   buf = env->GetStringUTFChars(path, &isCopy);
   CHECK_EXCEPTION_(false);
   AutoJavaString imagePath(env, path, buf);
 
   path = (jstring) env->GetStaticObjectField(clazz, symbolPath_ID);
+  CHECK_EXCEPTION_(false);
   buf = env->GetStringUTFChars(path, &isCopy);
   CHECK_EXCEPTION_(false);
   AutoJavaString symbolPath(env, path, buf);
--- a/hotspot/make/Makefile	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/make/Makefile	Wed Jul 05 20:01:50 2017 +0200
@@ -95,6 +95,7 @@
 COMMON_VM_PRODUCT_TARGETS=product product1 docs export_product
 COMMON_VM_FASTDEBUG_TARGETS=fastdebug fastdebug1 docs export_fastdebug
 COMMON_VM_DEBUG_TARGETS=debug debug1 docs export_debug
+COMMON_VM_OPTIMIZED_TARGETS=optimized optimized1 docs export_optimized
 
 # JDK directory list
 JDK_DIRS=bin include jre lib demo
@@ -111,20 +112,21 @@
 all_product:   product1 docs export_product
 all_fastdebug: fastdebug1 docs export_fastdebug
 all_debug:     debug1 docs export_debug
+all_optimized: optimized1 docs export_optimized
 else
 ifeq ($(MACOSX_UNIVERSAL),true)
 all_product:   universal_product
 all_fastdebug: universal_fastdebug
 all_debug:     universal_debug
+all_optimized: universal_optimized
 else
 all_product:   $(COMMON_VM_PRODUCT_TARGETS)
 all_fastdebug: $(COMMON_VM_FASTDEBUG_TARGETS)
 all_debug:     $(COMMON_VM_DEBUG_TARGETS)
+all_optimized: $(COMMON_VM_OPTIMIZED_TARGETS)
 endif
 endif
 
-all_optimized: optimized optimized1 docs export_optimized
-
 allzero:           all_productzero all_fastdebugzero
 all_productzero:   productzero docs export_product
 all_fastdebugzero: fastdebugzero docs export_fastdebug
@@ -890,3 +892,5 @@
 	create_jdk copy_jdk update_jdk test_jdk \
 	copy_product_jdk copy_fastdebug_jdk copy_debug_jdk  \
 	$(HS_ALT_MAKE)/Makefile.make remove_old_debuginfo
+
+.NOTPARALLEL:
--- a/hotspot/make/aix/Makefile	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/make/aix/Makefile	Wed Jul 05 20:01:50 2017 +0200
@@ -256,36 +256,36 @@
 
 $(SUBDIRS_TIERED): $(BUILDTREE_MAKE)
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-	$(BUILDTREE) VARIANT=tiered
+	+$(BUILDTREE) VARIANT=tiered
 
 $(SUBDIRS_C2): $(BUILDTREE_MAKE)
 ifeq ($(FORCE_TIERED),1)
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-		$(BUILDTREE) VARIANT=tiered FORCE_TIERED=1
+	+$(BUILDTREE) VARIANT=tiered FORCE_TIERED=1
 else
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-		$(BUILDTREE) VARIANT=compiler2
+	+$(BUILDTREE) VARIANT=compiler2
 endif
 
 $(SUBDIRS_C1): $(BUILDTREE_MAKE)
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-	$(BUILDTREE) VARIANT=compiler1
+	+$(BUILDTREE) VARIANT=compiler1
 
 $(SUBDIRS_CORE): $(BUILDTREE_MAKE)
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-	$(BUILDTREE) VARIANT=core
+	+$(BUILDTREE) VARIANT=core
 
 $(SUBDIRS_ZERO): $(BUILDTREE_MAKE) platform_zero
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-	$(BUILDTREE) VARIANT=zero VARIANTARCH=$(VARIANTARCH)
+	+$(BUILDTREE) VARIANT=zero VARIANTARCH=$(VARIANTARCH)
 
 $(SUBDIRS_SHARK): $(BUILDTREE_MAKE) platform_zero
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-	$(BUILDTREE) VARIANT=shark VARIANTARCH=$(VARIANTARCH)
+	+$(BUILDTREE) VARIANT=shark VARIANTARCH=$(VARIANTARCH)
 
 $(SUBDIRS_MINIMAL1): $(BUILDTREE_MAKE)
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-	$(BUILDTREE) VARIANT=minimal1
+	+$(BUILDTREE) VARIANT=minimal1
 
 
 platform_zero: $(GAMMADIR)/make/$(OSNAME)/platform_zero.in
@@ -379,3 +379,5 @@
 .PHONY: all compiler1 compiler2 core zero shark
 .PHONY: clean clean_compiler1 clean_compiler2 clean_core clean_zero clean_shark docs clean_docs
 .PHONY: checks check_os_version check_j2se_version
+
+.NOTPARALLEL:
--- a/hotspot/make/aix/makefiles/buildtree.make	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/make/aix/makefiles/buildtree.make	Wed Jul 05 20:01:50 2017 +0200
@@ -173,7 +173,7 @@
 # Run make in each subdirectory recursively.
 $(SUBMAKE_DIRS): $(SIMPLE_DIRS) FORCE
 	$(QUIETLY) [ -d $@ ] || { mkdir -p $@; }
-	$(QUIETLY) cd $@ && $(BUILDTREE) TARGET=$(@F)
+	+$(QUIETLY) cd $@ && $(BUILDTREE) TARGET=$(@F)
 	$(QUIETLY) touch $@
 
 $(SIMPLE_DIRS):
@@ -364,3 +364,5 @@
 FORCE:
 
 .PHONY:  all FORCE
+
+.NOTPARALLEL:
--- a/hotspot/make/aix/makefiles/top.make	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/make/aix/makefiles/top.make	Wed Jul 05 20:01:50 2017 +0200
@@ -69,7 +69,13 @@
 
 # Wierd argument adjustment for "gnumake -j..."
 adjust-mflags   = $(GENERATED)/adjust-mflags
-MFLAGS-adjusted = -r `$(adjust-mflags) "$(MFLAGS)" "$(HOTSPOT_BUILD_JOBS)"`
+# If SPEC is set, it's from configure and it's already controlling concurrency
+# for us. Skip setting -j with HOTSPOT_BUILD_JOBS.
+ifeq ($(SPEC), )
+  MFLAGS-adjusted = -r `$(adjust-mflags) "$(MFLAGS)" "$(HOTSPOT_BUILD_JOBS)"`
+else
+  MFLAGS-adjusted = -r $(MFLAGS)
+endif
 
 
 # default target: update lists, make vm
@@ -116,7 +122,7 @@
 	@+mv $@+ $@
 
 the_vm: vm_build_preliminaries $(adjust-mflags)
-	@$(UpdatePCH)
+	+@$(UpdatePCH)
 	@$(MAKE) -f vm.make $(MFLAGS-adjusted)
 
 install gamma: the_vm
@@ -125,7 +131,7 @@
 # next rules support "make foo.[ois]"
 
 %.o %.i %.s:
-	$(UpdatePCH)
+	+$(UpdatePCH)
 	$(MAKE) -f vm.make $(MFLAGS) $@
 	#$(MAKE) -f vm.make $@
 
@@ -142,3 +148,5 @@
 .PHONY: default vm_build_preliminaries
 .PHONY: lists ad_stuff jvmti_stuff sa_stuff the_vm clean realclean
 .PHONY: checks check_os_version install
+
+.NOTPARALLEL:
--- a/hotspot/make/bsd/Makefile	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/make/bsd/Makefile	Wed Jul 05 20:01:50 2017 +0200
@@ -250,36 +250,36 @@
 
 $(SUBDIRS_TIERED): $(BUILDTREE_MAKE)
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-	$(BUILDTREE) VARIANT=tiered
+	+$(BUILDTREE) VARIANT=tiered
 
 $(SUBDIRS_C2): $(BUILDTREE_MAKE)
 ifeq ($(FORCE_TIERED),1)
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-		$(BUILDTREE) VARIANT=tiered FORCE_TIERED=1
+	+$(BUILDTREE) VARIANT=tiered FORCE_TIERED=1
 else
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-		$(BUILDTREE) VARIANT=compiler2
+	+$(BUILDTREE) VARIANT=compiler2
 endif
 
 $(SUBDIRS_C1): $(BUILDTREE_MAKE)
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-	$(BUILDTREE) VARIANT=compiler1
+	+$(BUILDTREE) VARIANT=compiler1
 
 $(SUBDIRS_CORE): $(BUILDTREE_MAKE)
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-	$(BUILDTREE) VARIANT=core
+	+$(BUILDTREE) VARIANT=core
 
 $(SUBDIRS_ZERO): $(BUILDTREE_MAKE) platform_zero
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-	$(BUILDTREE) VARIANT=zero VARIANTARCH=$(VARIANTARCH)
+	+$(BUILDTREE) VARIANT=zero VARIANTARCH=$(VARIANTARCH)
 
 $(SUBDIRS_SHARK): $(BUILDTREE_MAKE) platform_zero
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-	$(BUILDTREE) VARIANT=shark VARIANTARCH=$(VARIANTARCH)
+	+$(BUILDTREE) VARIANT=shark VARIANTARCH=$(VARIANTARCH)
 
 $(SUBDIRS_MINIMAL1): $(BUILDTREE_MAKE)
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-	$(BUILDTREE) VARIANT=minimal1
+	+$(BUILDTREE) VARIANT=minimal1
 
 platform_zero: $(GAMMADIR)/make/$(OSNAME)/platform_zero.in
 	$(SED) 's/@ZERO_ARCHDEF@/$(ZERO_ARCHDEF)/g;s/@ZERO_LIBARCH@/$(ZERO_LIBARCH)/g;' < $< > $@
@@ -392,3 +392,5 @@
 .PHONY: clean clean_compiler1 clean_compiler2 clean_core clean_zero clean_shark docs clean_docs
 .PHONY: checks check_os_version check_j2se_version
 .PHONY: $(HS_ALT_MAKE)/$(OSNAME)/Makefile.make
+
+.NOTPARALLEL:
--- a/hotspot/make/bsd/makefiles/buildtree.make	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/make/bsd/makefiles/buildtree.make	Wed Jul 05 20:01:50 2017 +0200
@@ -178,7 +178,7 @@
 # Run make in each subdirectory recursively.
 $(SUBMAKE_DIRS): $(SIMPLE_DIRS) FORCE
 	$(QUIETLY) [ -d $@ ] || { mkdir -p $@; }
-	$(QUIETLY) cd $@ && $(BUILDTREE) TARGET=$(@F)
+	+$(QUIETLY) cd $@ && $(BUILDTREE) TARGET=$(@F)
 	$(QUIETLY) touch $@
 
 $(SIMPLE_DIRS):
@@ -378,3 +378,5 @@
 FORCE:
 
 .PHONY:  all FORCE
+
+.NOTPARALLEL:
--- a/hotspot/make/bsd/makefiles/top.make	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/make/bsd/makefiles/top.make	Wed Jul 05 20:01:50 2017 +0200
@@ -69,7 +69,13 @@
 
 # Wierd argument adjustment for "gnumake -j..."
 adjust-mflags   = $(GENERATED)/adjust-mflags
-MFLAGS-adjusted = -r `$(adjust-mflags) "$(MFLAGS)" "$(HOTSPOT_BUILD_JOBS)"`
+# If SPEC is set, it's from configure and it's already controlling concurrency
+# for us. Skip setting -j with HOTSPOT_BUILD_JOBS.
+ifeq ($(SPEC), )
+  MFLAGS-adjusted = -r `$(adjust-mflags) "$(MFLAGS)" "$(HOTSPOT_BUILD_JOBS)"`
+else
+  MFLAGS-adjusted = -r $(MFLAGS)
+endif
 
 
 # default target: update lists, make vm
@@ -125,7 +131,7 @@
 	@+mv $@+ $@
 
 the_vm: vm_build_preliminaries $(adjust-mflags)
-	@$(UpdatePCH)
+	+@$(UpdatePCH)
 	@$(MAKE) -f vm.make $(MFLAGS-adjusted)
 
 install : the_vm
@@ -134,7 +140,7 @@
 # next rules support "make foo.[ois]"
 
 %.o %.i %.s:
-	$(UpdatePCH)
+	+$(UpdatePCH)
 	$(MAKE) -f vm.make $(MFLAGS) $@
 	#$(MAKE) -f vm.make $@
 
@@ -151,3 +157,5 @@
 .PHONY: default vm_build_preliminaries
 .PHONY: lists ad_stuff jvmti_stuff sa_stuff the_vm clean realclean
 .PHONY: checks check_os_version install
+
+.NOTPARALLEL:
--- a/hotspot/make/bsd/makefiles/universal.gmk	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/make/bsd/makefiles/universal.gmk	Wed Jul 05 20:01:50 2017 +0200
@@ -25,6 +25,8 @@
 # macosx universal builds
 universal_product:
 	$(MAKE) MACOSX_UNIVERSAL=true all_product_universal
+universal_optimized:
+	$(MAKE) MACOSX_UNIVERSAL=true all_optimized_universal
 universal_fastdebug:
 	$(MAKE) MACOSX_UNIVERSAL=true all_fastdebug_universal
 universal_debug:
@@ -36,6 +38,10 @@
 #	$(QUIETLY) $(MAKE) ARCH_DATA_MODEL=32 $(COMMON_VM_PRODUCT_TARGETS)
 	$(QUIETLY) $(MAKE) ARCH_DATA_MODEL=64 $(COMMON_VM_PRODUCT_TARGETS)
 	$(QUIETLY) $(MAKE) BUILD_FLAVOR=product EXPORT_SUBDIR= universalize
+all_optimized_universal:
+#	$(QUIETLY) $(MAKE) ARCH_DATA_MODEL=32 $(COMMON_VM_OPTIMIZED_TARGETS)
+	$(QUIETLY) $(MAKE) ARCH_DATA_MODEL=64 $(COMMON_VM_OPTIMIZED_TARGETS)
+	$(QUIETLY) $(MAKE) BUILD_FLAVOR=optimized EXPORT_SUBDIR=/optimized universalize
 all_fastdebug_universal:
 #	$(QUIETLY) $(MAKE) ARCH_DATA_MODEL=32 $(COMMON_VM_FASTDEBUG_TARGETS)
 	$(QUIETLY) $(MAKE) ARCH_DATA_MODEL=64 $(COMMON_VM_FASTDEBUG_TARGETS)
@@ -98,13 +104,15 @@
 export_product_jdk::
 	$(MAKE) EXPORT_SUBDIR=           export_universal
 export_optimized_jdk::
-	$(MAKE) EXPORT_SUBDIR=           export_universal
+	$(MAKE) EXPORT_SUBDIR=/optimized export_universal
 export_fastdebug_jdk::
 	$(MAKE) EXPORT_SUBDIR=/fastdebug export_universal
 export_debug_jdk::
 	$(MAKE) EXPORT_SUBDIR=/debug     export_universal
 copy_product_jdk::
 	$(MAKE) COPY_SUBDIR=             copy_universal
+copy_optimized_jdk::
+	$(MAKE) COPY_SUBDIR=/optimized   copy_universal
 copy_fastdebug_jdk::
 	$(MAKE) COPY_SUBDIR=/fastdebug   copy_universal
 copy_debug_jdk::
@@ -112,5 +120,6 @@
 
 .PHONY:	universal_product universal_fastdebug universal_debug \
 	all_product_universal all_fastdebug_universal all_debug_universal \
+	universal_optimized all_optimized_universal \
 	universalize export_universal copy_universal \
 	$(UNIVERSAL_LIPO_LIST) $(UNIVERSAL_COPY_LIST)
--- a/hotspot/make/linux/Makefile	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/make/linux/Makefile	Wed Jul 05 20:01:50 2017 +0200
@@ -256,36 +256,36 @@
 
 $(SUBDIRS_TIERED): $(BUILDTREE_MAKE)
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-	$(BUILDTREE) VARIANT=tiered
+	+$(BUILDTREE) VARIANT=tiered
 
 $(SUBDIRS_C2): $(BUILDTREE_MAKE)
 ifeq ($(FORCE_TIERED),1)
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-		$(BUILDTREE) VARIANT=tiered FORCE_TIERED=1
+	+$(BUILDTREE) VARIANT=tiered FORCE_TIERED=1
 else
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-		$(BUILDTREE) VARIANT=compiler2
+	+$(BUILDTREE) VARIANT=compiler2
 endif
 
 $(SUBDIRS_C1): $(BUILDTREE_MAKE)
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-	$(BUILDTREE) VARIANT=compiler1
+	+$(BUILDTREE) VARIANT=compiler1
 
 $(SUBDIRS_CORE): $(BUILDTREE_MAKE)
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-	$(BUILDTREE) VARIANT=core
+	+$(BUILDTREE) VARIANT=core
 
 $(SUBDIRS_ZERO): $(BUILDTREE_MAKE) platform_zero
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-	$(BUILDTREE) VARIANT=zero VARIANTARCH=$(VARIANTARCH)
+	+$(BUILDTREE) VARIANT=zero VARIANTARCH=$(VARIANTARCH)
 
 $(SUBDIRS_SHARK): $(BUILDTREE_MAKE) platform_zero
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-	$(BUILDTREE) VARIANT=shark VARIANTARCH=$(VARIANTARCH)
+	+$(BUILDTREE) VARIANT=shark VARIANTARCH=$(VARIANTARCH)
 
 $(SUBDIRS_MINIMAL1): $(BUILDTREE_MAKE)
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-	$(BUILDTREE) VARIANT=minimal1
+	+$(BUILDTREE) VARIANT=minimal1
 
 
 platform_zero: $(GAMMADIR)/make/$(OSNAME)/platform_zero.in
@@ -399,3 +399,5 @@
 .PHONY: clean clean_compiler1 clean_compiler2 clean_core clean_zero clean_shark docs clean_docs
 .PHONY: checks check_os_version check_j2se_version
 .PHONY: $(HS_ALT_MAKE)/$(OSNAME)/Makefile.make
+
+.NOTPARALLEL:
--- a/hotspot/make/linux/makefiles/buildtree.make	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/make/linux/makefiles/buildtree.make	Wed Jul 05 20:01:50 2017 +0200
@@ -172,7 +172,7 @@
 # Run make in each subdirectory recursively.
 $(SUBMAKE_DIRS): $(SIMPLE_DIRS) FORCE
 	$(QUIETLY) [ -d $@ ] || { mkdir -p $@; }
-	$(QUIETLY) cd $@ && $(BUILDTREE) TARGET=$(@F)
+	+$(QUIETLY) cd $@ && $(BUILDTREE) TARGET=$(@F)
 	$(QUIETLY) touch $@
 
 $(SIMPLE_DIRS):
@@ -377,3 +377,5 @@
 FORCE:
 
 .PHONY:  all FORCE
+
+.NOTPARALLEL:
--- a/hotspot/make/linux/makefiles/top.make	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/make/linux/makefiles/top.make	Wed Jul 05 20:01:50 2017 +0200
@@ -69,7 +69,13 @@
 
 # Wierd argument adjustment for "gnumake -j..."
 adjust-mflags   = $(GENERATED)/adjust-mflags
-MFLAGS-adjusted = -r `$(adjust-mflags) "$(MFLAGS)" "$(HOTSPOT_BUILD_JOBS)"`
+# If SPEC is set, it's from configure and it's already controlling concurrency
+# for us. Skip setting -j with HOTSPOT_BUILD_JOBS.
+ifeq ($(SPEC), )
+  MFLAGS-adjusted = -r `$(adjust-mflags) "$(MFLAGS)" "$(HOTSPOT_BUILD_JOBS)"`
+else
+  MFLAGS-adjusted = -r $(MFLAGS)
+endif
 
 
 # default target: update lists, make vm
@@ -119,7 +125,7 @@
 	@+mv $@+ $@
 
 the_vm: vm_build_preliminaries $(adjust-mflags)
-	@$(UpdatePCH)
+	+@$(UpdatePCH)
 	@$(MAKE) -f vm.make $(MFLAGS-adjusted)
 
 install: the_vm
@@ -128,7 +134,7 @@
 # next rules support "make foo.[ois]"
 
 %.o %.i %.s:
-	$(UpdatePCH)
+	+$(UpdatePCH)
 	$(MAKE) -f vm.make $(MFLAGS) $@
 	#$(MAKE) -f vm.make $@
 
@@ -145,3 +151,5 @@
 .PHONY: default vm_build_preliminaries
 .PHONY: lists ad_stuff jvmti_stuff sa_stuff the_vm clean realclean
 .PHONY: checks check_os_version install
+
+.NOTPARALLEL:
--- a/hotspot/make/solaris/Makefile	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/make/solaris/Makefile	Wed Jul 05 20:01:50 2017 +0200
@@ -200,24 +200,24 @@
 
 $(SUBDIRS_TIERED): $(BUILDTREE_MAKE)
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-	$(BUILDTREE) VARIANT=tiered
+	+$(BUILDTREE) VARIANT=tiered
 
 $(SUBDIRS_C2): $(BUILDTREE_MAKE)
 ifeq ($(FORCE_TIERED),1)
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-		$(BUILDTREE) VARIANT=tiered FORCE_TIERED=1
+	+$(BUILDTREE) VARIANT=tiered FORCE_TIERED=1
 else
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-		$(BUILDTREE) VARIANT=compiler2
+	+$(BUILDTREE) VARIANT=compiler2
 endif
 
 $(SUBDIRS_C1): $(BUILDTREE_MAKE)
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-	$(BUILDTREE) VARIANT=compiler1
+	+$(BUILDTREE) VARIANT=compiler1
 
 $(SUBDIRS_CORE): $(BUILDTREE_MAKE)
 	$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
-	$(BUILDTREE) VARIANT=core
+	+$(BUILDTREE) VARIANT=core
 
 # Define INSTALL=y at command line to automatically copy JVM into JAVA_HOME
 
@@ -292,3 +292,5 @@
 .PHONY: all compiler1 compiler2 core
 .PHONY: clean clean_compiler1 clean_compiler2 clean_core docs clean_docs
 .PHONY: checks check_os_version check_j2se_version
+
+.NOTPARALLEL:
--- a/hotspot/make/solaris/makefiles/buildtree.make	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/make/solaris/makefiles/buildtree.make	Wed Jul 05 20:01:50 2017 +0200
@@ -165,7 +165,7 @@
 # Run make in each subdirectory recursively.
 $(SUBMAKE_DIRS): $(SIMPLE_DIRS) FORCE
 	$(QUIETLY) [ -d $@ ] || { mkdir -p $@; }
-	$(QUIETLY) cd $@ && $(BUILDTREE) TARGET=$(@F)
+	+$(QUIETLY) cd $@ && $(BUILDTREE) TARGET=$(@F)
 	$(QUIETLY) touch $@
 
 $(SIMPLE_DIRS):
@@ -364,3 +364,5 @@
 FORCE:
 
 .PHONY:  all FORCE
+
+.NOTPARALLEL:
--- a/hotspot/make/solaris/makefiles/top.make	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/make/solaris/makefiles/top.make	Wed Jul 05 20:01:50 2017 +0200
@@ -62,7 +62,13 @@
 
 # Wierd argument adjustment for "gnumake -j..."
 adjust-mflags   = $(GENERATED)/adjust-mflags
-MFLAGS-adjusted = -r `$(adjust-mflags) "$(MFLAGS)" "$(HOTSPOT_BUILD_JOBS)"`
+# If SPEC is set, it's from configure and it's already controlling concurrency
+# for us. Skip setting -j with HOTSPOT_BUILD_JOBS.
+ifeq ($(SPEC), )
+  MFLAGS-adjusted = -r `$(adjust-mflags) "$(MFLAGS)" "$(HOTSPOT_BUILD_JOBS)"`
+else
+  MFLAGS-adjusted = -r $(MFLAGS)
+endif
 
 
 # default target: update lists, make vm
@@ -136,3 +142,5 @@
 .PHONY: default vm_build_preliminaries
 .PHONY: lists ad_stuff jvmti_stuff trace_stuff sa_stuff the_vm clean realclean
 .PHONY: checks check_os_version install
+
+.NOTPARALLEL:
--- a/hotspot/make/solaris/makefiles/vm.make	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/make/solaris/makefiles/vm.make	Wed Jul 05 20:01:50 2017 +0200
@@ -143,7 +143,7 @@
 LIBS += -lsocket -lsched -ldl $(LIBM) -lthread -lc -ldemangle
 endif # sparcWorks
 
-LIBS += -lkstat
+LIBS += -lkstat -lpicl
 
 # By default, link the *.o into the library, not the executable.
 LINK_INTO$(LINK_INTO) = LIBJVM
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -32,6 +32,7 @@
 
 int VM_Version::_features = VM_Version::unknown_m;
 const char* VM_Version::_features_str = "";
+unsigned int VM_Version::_L2_cache_line_size = 0;
 
 void VM_Version::initialize() {
   _features = determine_features();
@@ -192,7 +193,7 @@
   }
 
   assert(BlockZeroingLowLimit > 0, "invalid value");
-  if (has_block_zeroing()) {
+  if (has_block_zeroing() && cache_line_size > 0) {
     if (FLAG_IS_DEFAULT(UseBlockZeroing)) {
       FLAG_SET_DEFAULT(UseBlockZeroing, true);
     }
@@ -202,7 +203,7 @@
   }
 
   assert(BlockCopyLowLimit > 0, "invalid value");
-  if (has_block_zeroing()) { // has_blk_init() && is_T4(): core's local L2 cache
+  if (has_block_zeroing() && cache_line_size > 0) { // has_blk_init() && is_T4(): core's local L2 cache
     if (FLAG_IS_DEFAULT(UseBlockCopy)) {
       FLAG_SET_DEFAULT(UseBlockCopy, true);
     }
@@ -252,49 +253,6 @@
   // buf is started with ", " or is empty
   _features_str = os::strdup(strlen(buf) > 2 ? buf + 2 : buf);
 
-  // There are three 64-bit SPARC families that do not overlap, e.g.,
-  // both is_ultra3() and is_sparc64() cannot be true at the same time.
-  // Within these families, there can be more than one chip, e.g.,
-  // is_T4() and is_T7() machines are also is_niagara().
-  if (is_ultra3()) {
-    assert(_L1_data_cache_line_size == 0, "overlap with Ultra3 family");
-    // Ref: UltraSPARC III Cu Processor
-    _L1_data_cache_line_size = 64;
-  }
-  if (is_niagara()) {
-    assert(_L1_data_cache_line_size == 0, "overlap with niagara family");
-    // All Niagara's are sun4v's, but not all sun4v's are Niagaras, e.g.,
-    // Fujitsu SPARC64 is sun4v, but we don't want it in this block.
-    //
-    // Ref: UltraSPARC T1 Supplement to the UltraSPARC Architecture 2005
-    // Appendix F.1.3.1 Cacheable Accesses
-    // -> 16-byte L1 cache line size
-    //
-    // Ref: UltraSPARC T2: A Highly-Threaded, Power-Efficient, SPARC SOC
-    // Section III: SPARC Processor Core
-    // -> 16-byte L1 cache line size
-    //
-    // Ref: Oracle's SPARC T4-1, SPARC T4-2, SPARC T4-4, and SPARC T4-1B Server Architecture
-    // Section SPARC T4 Processor Cache Architecture
-    // -> 32-byte L1 cache line size (no longer see that info on this ref)
-    //
-    // XXX - still need a T7 reference here
-    //
-    if (is_T7()) {  // T7 or newer
-      _L1_data_cache_line_size = 64;
-    } else if (is_T4()) {  // T4 or newer (until T7)
-      _L1_data_cache_line_size = 32;
-    } else {  // T1 or newer (until T4)
-      _L1_data_cache_line_size = 16;
-    }
-  }
-  if (is_sparc64()) {
-    guarantee(_L1_data_cache_line_size == 0, "overlap with SPARC64 family");
-    // Ref: Fujitsu SPARC64 VII Processor
-    // Section 4 Cache System
-    _L1_data_cache_line_size = 64;
-  }
-
   // UseVIS is set to the smallest of what hardware supports and what
   // the command line requires.  I.e., you cannot set UseVIS to 3 on
   // older UltraSparc which do not support it.
@@ -401,6 +359,7 @@
 #ifndef PRODUCT
   if (PrintMiscellaneous && Verbose) {
     tty->print_cr("L1 data cache line size: %u", L1_data_cache_line_size());
+    tty->print_cr("L2 cache line size: %u", L2_cache_line_size());
     tty->print("Allocation");
     if (AllocatePrefetchStyle <= 0) {
       tty->print_cr(": no prefetching");
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp	Wed Jul 05 20:01:50 2017 +0200
@@ -96,6 +96,9 @@
   static int  _features;
   static const char* _features_str;
 
+  static unsigned int _L2_cache_line_size;
+  static unsigned int L2_cache_line_size() { return _L2_cache_line_size; }
+
   static void print_features();
   static int  determine_features();
   static int  platform_features(int features);
@@ -167,9 +170,8 @@
 
   static const char* cpu_features()     { return _features_str; }
 
-  static intx prefetch_data_size()  {
-    return is_T4() && !is_T7() ? 32 : 64;  // default prefetch block size on sparc
-  }
+  // default prefetch block size on sparc
+  static intx prefetch_data_size()      { return L2_cache_line_size();  }
 
   // Prefetch
   static intx prefetch_copy_interval_in_bytes() {
--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp	Wed Jul 05 20:01:50 2017 +0200
@@ -26,6 +26,7 @@
 #define CPU_X86_VM_ASSEMBLER_X86_HPP
 
 #include "asm/register.hpp"
+#include "vm_version_x86.hpp"
 
 class BiasedLockingCounters;
 
@@ -1292,14 +1293,34 @@
       if (order_constraint & StoreLoad) {
         // All usable chips support "locked" instructions which suffice
         // as barriers, and are much faster than the alternative of
-        // using cpuid instruction. We use here a locked add [esp],0.
+        // using cpuid instruction. We use here a locked add [esp-C],0.
         // This is conveniently otherwise a no-op except for blowing
-        // flags.
+        // flags, and introducing a false dependency on target memory
+        // location. We can't do anything with flags, but we can avoid
+        // memory dependencies in the current method by locked-adding
+        // somewhere else on the stack. Doing [esp+C] will collide with
+        // something on stack in current method, hence we go for [esp-C].
+        // It is convenient since it is almost always in data cache, for
+        // any small C.  We need to step back from SP to avoid data
+        // dependencies with other things on below SP (callee-saves, for
+        // example). Without a clear way to figure out the minimal safe
+        // distance from SP, it makes sense to step back the complete
+        // cache line, as this will also avoid possible second-order effects
+        // with locked ops against the cache line. Our choice of offset
+        // is bounded by x86 operand encoding, which should stay within
+        // [-128; +127] to have the 8-byte displacement encoding.
+        //
         // Any change to this code may need to revisit other places in
         // the code where this idiom is used, in particular the
         // orderAccess code.
+
+        int offset = -VM_Version::L1_line_size();
+        if (offset < -128) {
+          offset = -128;
+        }
+
         lock();
-        addl(Address(rsp, 0), 0);// Assert the lock# signal here
+        addl(Address(rsp, offset), 0);// Assert the lock# signal here
       }
     }
   }
--- a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -820,14 +820,10 @@
 }
 
 address InterpreterGenerator::generate_native_entry(bool synchronized) {
-  assert(synchronized == false, "should be");
-
   return generate_entry((address) CppInterpreter::native_entry);
 }
 
 address InterpreterGenerator::generate_normal_entry(bool synchronized) {
-  assert(synchronized == false, "should be");
-
   return generate_entry((address) CppInterpreter::normal_entry);
 }
 
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -1644,8 +1644,20 @@
   return true;
 }
 
+int _print_dll_info_cb(const char * name, address base_address, address top_address, void * param) {
+  outputStream * out = (outputStream *) param;
+  out->print_cr(PTR_FORMAT " \t%s", base_address, name);
+  return 0;
+}
+
 void os::print_dll_info(outputStream *st) {
   st->print_cr("Dynamic libraries:");
+  if (get_loaded_modules_info(_print_dll_info_cb, (void *)st)) {
+    st->print_cr("Error: Cannot print dynamic libraries.");
+  }
+}
+
+int os::get_loaded_modules_info(os::LoadedModulesCallbackFunc callback, void *param) {
 #ifdef RTLD_DI_LINKMAP
   Dl_info dli;
   void *handle;
@@ -1654,36 +1666,41 @@
 
   if (dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli) == 0 ||
       dli.dli_fname == NULL) {
-    st->print_cr("Error: Cannot print dynamic libraries.");
-    return;
+    return 1;
   }
   handle = dlopen(dli.dli_fname, RTLD_LAZY);
   if (handle == NULL) {
-    st->print_cr("Error: Cannot print dynamic libraries.");
-    return;
+    return 1;
   }
   dlinfo(handle, RTLD_DI_LINKMAP, &map);
   if (map == NULL) {
-    st->print_cr("Error: Cannot print dynamic libraries.");
-    return;
+    dlclose(handle);
+    return 1;
   }
 
   while (map->l_prev != NULL)
     map = map->l_prev;
 
   while (map != NULL) {
-    st->print_cr(PTR_FORMAT " \t%s", map->l_addr, map->l_name);
+    // Value for top_address is returned as 0 since we don't have any information about module size
+    if (callback(map->l_name, (address)map->l_addr, (address)0, param)) {
+      dlclose(handle);
+      return 1;
+    }
     map = map->l_next;
   }
 
   dlclose(handle);
 #elif defined(__APPLE__)
   for (uint32_t i = 1; i < _dyld_image_count(); i++) {
-    st->print_cr(PTR_FORMAT " \t%s", _dyld_get_image_header(i),
-        _dyld_get_image_name(i));
+    // Value for top_address is returned as 0 since we don't have any information about module size
+    if (callback(_dyld_get_image_name(i), (address)_dyld_get_image_header(i), (address)0, param)) {
+      return 1;
+    }
   }
+  return 0;
 #else
-  st->print_cr("Error: Cannot print dynamic libraries.");
+  return 1;
 #endif
 }
 
--- a/hotspot/src/os/linux/vm/os_linux.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/os/linux/vm/os_linux.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -2120,6 +2120,40 @@
    }
 }
 
+int os::get_loaded_modules_info(os::LoadedModulesCallbackFunc callback, void *param) {
+  FILE *procmapsFile = NULL;
+
+  // Open the procfs maps file for the current process
+  if ((procmapsFile = fopen("/proc/self/maps", "r")) != NULL) {
+    // Allocate PATH_MAX for file name plus a reasonable size for other fields.
+    char line[PATH_MAX + 100];
+
+    // Read line by line from 'file'
+    while (fgets(line, sizeof(line), procmapsFile) != NULL) {
+      u8 base, top, offset, inode;
+      char permissions[5];
+      char device[6];
+      char name[PATH_MAX + 1];
+
+      // Parse fields from line
+      sscanf(line, "%lx-%lx %4s %lx %5s %ld %s", &base, &top, permissions, &offset, device, &inode, name);
+
+      // Filter by device id '00:00' so that we only get file system mapped files.
+      if (strcmp(device, "00:00") != 0) {
+
+        // Call callback with the fields of interest
+        if(callback(name, (address)base, (address)top, param)) {
+          // Oops abort, callback aborted
+          fclose(procmapsFile);
+          return 1;
+        }
+      }
+    }
+    fclose(procmapsFile);
+  }
+  return 0;
+}
+
 void os::print_os_info_brief(outputStream* st) {
   os::Linux::print_distro_info(st);
 
--- a/hotspot/src/os/posix/vm/os_posix.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/os/posix/vm/os_posix.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -215,6 +215,9 @@
   struct utsname name;
   uname(&name);
   st->print("%s ", name.sysname);
+#ifdef ASSERT
+  st->print("%s ", name.nodename);
+#endif
   st->print("%s ", name.release);
   st->print("%s ", name.version);
   st->print("%s", name.machine);
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -1722,41 +1722,54 @@
   return false;
 }
 
-// Prints the names and full paths of all opened dynamic libraries
-// for current process
-void os::print_dll_info(outputStream * st) {
+int os::get_loaded_modules_info(os::LoadedModulesCallbackFunc callback, void *param) {
   Dl_info dli;
-  void *handle;
+  // Sanity check?
+  if (dladdr(CAST_FROM_FN_PTR(void *, os::get_loaded_modules_info), &dli) == 0 ||
+      dli.dli_fname == NULL) {
+    return 1;
+  }
+
+  void * handle = dlopen(dli.dli_fname, RTLD_LAZY);
+  if (handle == NULL) {
+    return 1;
+  }
+
   Link_map *map;
-  Link_map *p;
-
-  st->print_cr("Dynamic libraries:"); st->flush();
-
-  if (dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli) == 0 ||
-      dli.dli_fname == NULL) {
-    st->print_cr("Error: Cannot print dynamic libraries.");
-    return;
-  }
-  handle = dlopen(dli.dli_fname, RTLD_LAZY);
-  if (handle == NULL) {
-    st->print_cr("Error: Cannot print dynamic libraries.");
-    return;
-  }
   dlinfo(handle, RTLD_DI_LINKMAP, &map);
   if (map == NULL) {
-    st->print_cr("Error: Cannot print dynamic libraries.");
-    return;
-  }
-
-  while (map->l_prev != NULL)
+    dlclose(handle);
+    return 1;
+  }
+
+  while (map->l_prev != NULL) {
     map = map->l_prev;
+  }
 
   while (map != NULL) {
-    st->print_cr(PTR_FORMAT " \t%s", map->l_addr, map->l_name);
+    // Iterate through all map entries and call callback with fields of interest
+    if(callback(map->l_name, (address)map->l_addr, (address)0, param)) {
+      dlclose(handle);
+      return 1;
+    }
     map = map->l_next;
   }
 
   dlclose(handle);
+  return 0;
+}
+
+int _print_dll_info_cb(const char * name, address base_address, address top_address, void * param) {
+  outputStream * out = (outputStream *) param;
+  out->print_cr(PTR_FORMAT " \t%s", base_address, name);
+  return 0;
+}
+
+void os::print_dll_info(outputStream * st) {
+  st->print_cr("Dynamic libraries:"); st->flush();
+  if (get_loaded_modules_info(_print_dll_info_cb, (void *)st)) {
+    st->print_cr("Error: Cannot print dynamic libraries.");
+  }
 }
 
   // Loads .dll/.so and
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -1301,120 +1301,6 @@
 }
 #endif
 
-
-// Enumerate all modules for a given process ID
-//
-// Notice that Windows 95/98/Me and Windows NT/2000/XP have
-// different API for doing this. We use PSAPI.DLL on NT based
-// Windows and ToolHelp on 95/98/Me.
-
-// Callback function that is called by enumerate_modules() on
-// every DLL module.
-// Input parameters:
-//    int       pid,
-//    char*     module_file_name,
-//    address   module_base_addr,
-//    unsigned  module_size,
-//    void*     param
-typedef int (*EnumModulesCallbackFunc)(int, char *, address, unsigned, void *);
-
-// enumerate_modules for Windows NT, using PSAPI
-static int _enumerate_modules_winnt( int pid, EnumModulesCallbackFunc func, void * param)
-{
-  HANDLE   hProcess;
-
-# define MAX_NUM_MODULES 128
-  HMODULE     modules[MAX_NUM_MODULES];
-  static char filename[MAX_PATH];
-  int         result = 0;
-
-  if (!os::PSApiDll::PSApiAvailable()) {
-    return 0;
-  }
-
-  hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
-                         FALSE, pid);
-  if (hProcess == NULL) return 0;
-
-  DWORD size_needed;
-  if (!os::PSApiDll::EnumProcessModules(hProcess, modules,
-                           sizeof(modules), &size_needed)) {
-      CloseHandle(hProcess);
-      return 0;
-  }
-
-  // number of modules that are currently loaded
-  int num_modules = size_needed / sizeof(HMODULE);
-
-  for (int i = 0; i < MIN2(num_modules, MAX_NUM_MODULES); i++) {
-    // Get Full pathname:
-    if (!os::PSApiDll::GetModuleFileNameEx(hProcess, modules[i],
-                             filename, sizeof(filename))) {
-        filename[0] = '\0';
-    }
-
-    MODULEINFO modinfo;
-    if (!os::PSApiDll::GetModuleInformation(hProcess, modules[i],
-                               &modinfo, sizeof(modinfo))) {
-        modinfo.lpBaseOfDll = NULL;
-        modinfo.SizeOfImage = 0;
-    }
-
-    // Invoke callback function
-    result = func(pid, filename, (address)modinfo.lpBaseOfDll,
-                  modinfo.SizeOfImage, param);
-    if (result) break;
-  }
-
-  CloseHandle(hProcess);
-  return result;
-}
-
-
-// enumerate_modules for Windows 95/98/ME, using TOOLHELP
-static int _enumerate_modules_windows( int pid, EnumModulesCallbackFunc func, void *param)
-{
-  HANDLE                hSnapShot;
-  static MODULEENTRY32  modentry;
-  int                   result = 0;
-
-  if (!os::Kernel32Dll::HelpToolsAvailable()) {
-    return 0;
-  }
-
-  // Get a handle to a Toolhelp snapshot of the system
-  hSnapShot = os::Kernel32Dll::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
-  if (hSnapShot == INVALID_HANDLE_VALUE) {
-      return FALSE;
-  }
-
-  // iterate through all modules
-  modentry.dwSize = sizeof(MODULEENTRY32);
-  bool not_done = os::Kernel32Dll::Module32First( hSnapShot, &modentry ) != 0;
-
-  while (not_done) {
-    // invoke the callback
-    result=func(pid, modentry.szExePath, (address)modentry.modBaseAddr,
-                modentry.modBaseSize, param);
-    if (result) break;
-
-    modentry.dwSize = sizeof(MODULEENTRY32);
-    not_done = os::Kernel32Dll::Module32Next( hSnapShot, &modentry ) != 0;
-  }
-
-  CloseHandle(hSnapShot);
-  return result;
-}
-
-int enumerate_modules( int pid, EnumModulesCallbackFunc func, void * param )
-{
-  // Get current process ID if caller doesn't provide it.
-  if (!pid) pid = os::current_process_id();
-
-  if (os::win32::is_nt()) return _enumerate_modules_winnt  (pid, func, param);
-  else                    return _enumerate_modules_windows(pid, func, param);
-}
-
 struct _modinfo {
    address addr;
    char*   full_path;   // point to a char buffer
@@ -1422,13 +1308,13 @@
    address base_addr;
 };
 
-static int _locate_module_by_addr(int pid, char * mod_fname, address base_addr,
-                                  unsigned size, void * param) {
+static int _locate_module_by_addr(const char * mod_fname, address base_addr,
+                                  address top_address, void * param) {
    struct _modinfo *pmod = (struct _modinfo *)param;
    if (!pmod) return -1;
 
-   if (base_addr     <= pmod->addr &&
-       base_addr+size > pmod->addr) {
+   if (base_addr   <= pmod->addr &&
+       top_address > pmod->addr) {
      // if a buffer is provided, copy path name to the buffer
      if (pmod->full_path) {
        jio_snprintf(pmod->full_path, pmod->buflen, "%s", mod_fname);
@@ -1453,8 +1339,7 @@
   mi.addr      = addr;
   mi.full_path = buf;
   mi.buflen    = buflen;
-  int pid = os::current_process_id();
-  if (enumerate_modules(pid, _locate_module_by_addr, (void *)&mi)) {
+  if (get_loaded_modules_info(_locate_module_by_addr, (void *)&mi)) {
     // buf already contains path name
     if (offset) *offset = addr - mi.base_addr;
     return true;
@@ -1479,14 +1364,14 @@
 }
 
 // save the start and end address of jvm.dll into param[0] and param[1]
-static int _locate_jvm_dll(int pid, char* mod_fname, address base_addr,
-                    unsigned size, void * param) {
+static int _locate_jvm_dll(const char* mod_fname, address base_addr,
+                    address top_address, void * param) {
    if (!param) return -1;
 
-   if (base_addr     <= (address)_locate_jvm_dll &&
-       base_addr+size > (address)_locate_jvm_dll) {
+   if (base_addr   <= (address)_locate_jvm_dll &&
+       top_address > (address)_locate_jvm_dll) {
          ((address*)param)[0] = base_addr;
-         ((address*)param)[1] = base_addr + size;
+         ((address*)param)[1] = top_address;
          return 1;
    }
    return 0;
@@ -1497,8 +1382,7 @@
 // check if addr is inside jvm.dll
 bool os::address_is_in_vm(address addr) {
   if (!vm_lib_location[0] || !vm_lib_location[1]) {
-    int pid = os::current_process_id();
-    if (!enumerate_modules(pid, _locate_jvm_dll, (void *)vm_lib_location)) {
+    if (!get_loaded_modules_info(_locate_jvm_dll, (void *)vm_lib_location)) {
       assert(false, "Can't find jvm module.");
       return false;
     }
@@ -1508,14 +1392,13 @@
 }
 
 // print module info; param is outputStream*
-static int _print_module(int pid, char* fname, address base,
-                         unsigned size, void* param) {
+static int _print_module(const char* fname, address base_address,
+                         address top_address, void* param) {
    if (!param) return -1;
 
    outputStream* st = (outputStream*)param;
 
-   address end_addr = base + size;
-   st->print(PTR_FORMAT " - " PTR_FORMAT " \t%s\n", base, end_addr, fname);
+   st->print(PTR_FORMAT " - " PTR_FORMAT " \t%s\n", base_address, top_address, fname);
    return 0;
 }
 
@@ -1644,11 +1527,60 @@
   return NULL;
 }
 
-
 void os::print_dll_info(outputStream *st) {
-   int pid = os::current_process_id();
    st->print_cr("Dynamic libraries:");
-   enumerate_modules(pid, _print_module, (void *)st);
+   get_loaded_modules_info(_print_module, (void *)st);
+}
+
+int os::get_loaded_modules_info(os::LoadedModulesCallbackFunc callback, void *param) {
+  HANDLE   hProcess;
+
+# define MAX_NUM_MODULES 128
+  HMODULE     modules[MAX_NUM_MODULES];
+  static char filename[MAX_PATH];
+  int         result = 0;
+
+  if (!os::PSApiDll::PSApiAvailable()) {
+    return 0;
+  }
+
+  int pid = os::current_process_id();
+  hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
+                         FALSE, pid);
+  if (hProcess == NULL) return 0;
+
+  DWORD size_needed;
+  if (!os::PSApiDll::EnumProcessModules(hProcess, modules,
+                           sizeof(modules), &size_needed)) {
+      CloseHandle(hProcess);
+      return 0;
+  }
+
+  // number of modules that are currently loaded
+  int num_modules = size_needed / sizeof(HMODULE);
+
+  for (int i = 0; i < MIN2(num_modules, MAX_NUM_MODULES); i++) {
+    // Get Full pathname:
+    if (!os::PSApiDll::GetModuleFileNameEx(hProcess, modules[i],
+                             filename, sizeof(filename))) {
+        filename[0] = '\0';
+    }
+
+    MODULEINFO modinfo;
+    if (!os::PSApiDll::GetModuleInformation(hProcess, modules[i],
+                               &modinfo, sizeof(modinfo))) {
+        modinfo.lpBaseOfDll = NULL;
+        modinfo.SizeOfImage = 0;
+    }
+
+    // Invoke callback function
+    result = callback(filename, (address)modinfo.lpBaseOfDll,
+                  (address)((u8)modinfo.lpBaseOfDll + (u8)modinfo.SizeOfImage), param);
+    if (result) break;
+  }
+
+  CloseHandle(hProcess);
+  return result;
 }
 
 void os::print_os_info_brief(outputStream* st) {
@@ -1656,8 +1588,17 @@
 }
 
 void os::print_os_info(outputStream* st) {
-  st->print("OS:");
-
+#ifdef ASSERT
+  char buffer[1024];
+  DWORD size = sizeof(buffer);
+  st->print(" HostName: ");
+  if (GetComputerNameEx(ComputerNameDnsHostname, buffer, &size)) {
+    st->print("%s", buffer);
+  } else {
+    st->print("N/A");
+  }
+#endif
+  st->print(" OS:");
   os::win32::print_windows_version(st);
 }
 
--- a/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -563,3 +563,8 @@
   assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment");
 }
 #endif
+
+int os::extra_bang_size_in_bytes() {
+  // PPC does not require the additional stack bang.
+  return 0;
+}
--- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -1030,3 +1030,8 @@
 void os::verify_stack_alignment() {
 }
 #endif
+
+int os::extra_bang_size_in_bytes() {
+  // JDK-8050147 requires the full cache line bang for x86.
+  return VM_Version::L1_line_size();
+}
--- a/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -465,3 +465,8 @@
 void os::verify_stack_alignment() {
 }
 #endif
+
+int os::extra_bang_size_in_bytes() {
+  // Zero does not require an additional stack bang.
+  return 0;
+}
--- a/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -612,3 +612,8 @@
   assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment");
 }
 #endif
+
+int os::extra_bang_size_in_bytes() {
+  // PPC does not require the additional stack bang.
+  return 0;
+}
--- a/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -752,3 +752,8 @@
 void os::verify_stack_alignment() {
 }
 #endif
+
+int os::extra_bang_size_in_bytes() {
+  // SPARC does not require the additional stack bang.
+  return 0;
+}
--- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -930,3 +930,8 @@
   // keep the page mapped so CS limit isn't reduced.
 #endif
 }
+
+int os::extra_bang_size_in_bytes() {
+  // JDK-8050147 requires the full cache line bang for x86.
+  return VM_Version::L1_line_size();
+}
--- a/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -495,3 +495,8 @@
 void os::verify_stack_alignment() {
 }
 #endif
+
+int os::extra_bang_size_in_bytes() {
+  // Zero does not require an additional stack banging.
+  return 0;
+}
--- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -774,3 +774,8 @@
 void os::verify_stack_alignment() {
 }
 #endif
+
+int os::extra_bang_size_in_bytes() {
+  // SPARC does not require an additional stack bang.
+  return 0;
+}
--- a/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -28,10 +28,140 @@
 #include "runtime/os.hpp"
 #include "vm_version_sparc.hpp"
 
-# include <sys/auxv.h>
-# include <sys/auxv_SPARC.h>
-# include <sys/systeminfo.h>
-# include <kstat.h>
+#include <sys/auxv.h>
+#include <sys/auxv_SPARC.h>
+#include <sys/systeminfo.h>
+#include <kstat.h>
+#include <picl.h>
+
+extern "C" static int PICL_get_l1_data_cache_line_size_helper(picl_nodehdl_t nodeh, void *result);
+extern "C" static int PICL_get_l2_cache_line_size_helper(picl_nodehdl_t nodeh, void *result);
+
+class PICL {
+  // Get a value of the integer property. The value in the tree can be either 32 or 64 bit
+  // depending on the platform. The result is converted to int.
+  static int get_int_property(picl_nodehdl_t nodeh, const char* name, int* result) {
+    picl_propinfo_t pinfo;
+    picl_prophdl_t proph;
+    if (picl_get_prop_by_name(nodeh, name, &proph) != PICL_SUCCESS ||
+        picl_get_propinfo(proph, &pinfo) != PICL_SUCCESS) {
+      return PICL_FAILURE;
+    }
+
+    if (pinfo.type != PICL_PTYPE_INT && pinfo.type != PICL_PTYPE_UNSIGNED_INT) {
+      assert(false, "Invalid property type");
+      return PICL_FAILURE;
+    }
+    if (pinfo.size == sizeof(int64_t)) {
+      int64_t val;
+      if (picl_get_propval(proph, &val, sizeof(int64_t)) != PICL_SUCCESS) {
+        return PICL_FAILURE;
+      }
+      *result = static_cast<int>(val);
+    } else if (pinfo.size == sizeof(int32_t)) {
+      int32_t val;
+      if (picl_get_propval(proph, &val, sizeof(int32_t)) != PICL_SUCCESS) {
+        return PICL_FAILURE;
+      }
+      *result = static_cast<int>(val);
+    } else {
+      assert(false, "Unexpected integer property size");
+      return PICL_FAILURE;
+    }
+    return PICL_SUCCESS;
+  }
+
+  // Visitor and a state machine that visits integer properties and verifies that the
+  // values are the same. Stores the unique value observed.
+  class UniqueValueVisitor {
+    enum {
+      INITIAL,        // Start state, no assignments happened
+      ASSIGNED,       // Assigned a value
+      INCONSISTENT    // Inconsistent value seen
+    } _state;
+    int _value;
+  public:
+    UniqueValueVisitor() : _state(INITIAL) { }
+    int value() {
+      assert(_state == ASSIGNED, "Precondition");
+      return _value;
+    }
+    void set_value(int value) {
+      assert(_state == INITIAL, "Precondition");
+      _value = value;
+      _state = ASSIGNED;
+    }
+    bool is_initial()       { return _state == INITIAL;      }
+    bool is_assigned()      { return _state == ASSIGNED;     }
+    bool is_inconsistent()  { return _state == INCONSISTENT; }
+    void set_inconsistent() { _state = INCONSISTENT;         }
+
+    static int visit(picl_nodehdl_t nodeh, const char* name, void *arg) {
+      UniqueValueVisitor *state = static_cast<UniqueValueVisitor*>(arg);
+      assert(!state->is_inconsistent(), "Precondition");
+      int curr;
+      if (PICL::get_int_property(nodeh, name, &curr) == PICL_SUCCESS) {
+        if (!state->is_assigned()) { // first iteration
+          state->set_value(curr);
+        } else if (curr != state->value()) { // following iterations
+          state->set_inconsistent();
+        }
+      }
+      if (state->is_inconsistent()) {
+        return PICL_WALK_TERMINATE;
+      }
+      return PICL_WALK_CONTINUE;
+    }
+  };
+
+  int _L1_data_cache_line_size;
+  int _L2_cache_line_size;
+public:
+  static int get_l1_data_cache_line_size(picl_nodehdl_t nodeh, void *state) {
+    return UniqueValueVisitor::visit(nodeh, "l1-dcache-line-size", state);
+  }
+  static int get_l2_cache_line_size(picl_nodehdl_t nodeh, void *state) {
+    return UniqueValueVisitor::visit(nodeh, "l2-cache-line-size", state);
+  }
+
+  PICL() : _L1_data_cache_line_size(0), _L2_cache_line_size(0) {
+    if (picl_initialize() == PICL_SUCCESS) {
+      picl_nodehdl_t rooth;
+      if (picl_get_root(&rooth) == PICL_SUCCESS) {
+        UniqueValueVisitor L1_state;
+        // Visit all "cpu" class instances
+        picl_walk_tree_by_class(rooth, "cpu", &L1_state, PICL_get_l1_data_cache_line_size_helper);
+        if (L1_state.is_initial()) { // Still initial, iteration found no values
+          // Try walk all "core" class instances, it might be a Fujitsu machine
+          picl_walk_tree_by_class(rooth, "core", &L1_state, PICL_get_l1_data_cache_line_size_helper);
+        }
+        if (L1_state.is_assigned()) { // Is there a value?
+          _L1_data_cache_line_size = L1_state.value();
+        }
+
+        UniqueValueVisitor L2_state;
+        picl_walk_tree_by_class(rooth, "cpu", &L2_state, PICL_get_l2_cache_line_size_helper);
+        if (L2_state.is_initial()) {
+          picl_walk_tree_by_class(rooth, "core", &L2_state, PICL_get_l2_cache_line_size_helper);
+        }
+        if (L2_state.is_assigned()) {
+          _L2_cache_line_size = L2_state.value();
+        }
+      }
+      picl_shutdown();
+    }
+  }
+
+  unsigned int L1_data_cache_line_size() const { return _L1_data_cache_line_size; }
+  unsigned int L2_cache_line_size() const      { return _L2_cache_line_size;      }
+};
+
+extern "C" static int PICL_get_l1_data_cache_line_size_helper(picl_nodehdl_t nodeh, void *result) {
+  return PICL::get_l1_data_cache_line_size(nodeh, result);
+}
+extern "C" static int PICL_get_l2_cache_line_size_helper(picl_nodehdl_t nodeh, void *result) {
+  return PICL::get_l2_cache_line_size(nodeh, result);
+}
 
 // We need to keep these here as long as we have to build on Solaris
 // versions before 10.
@@ -211,5 +341,10 @@
     kstat_close(kc);
   }
 
+  // Figure out cache line sizes using PICL
+  PICL picl;
+  _L1_data_cache_line_size = picl.L1_data_cache_line_size();
+  _L2_cache_line_size      = picl.L2_cache_line_size();
+
   return features;
 }
--- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -918,3 +918,8 @@
 #endif
 }
 #endif
+
+int os::extra_bang_size_in_bytes() {
+  // JDK-8050147 requires the full cache line bang for x86.
+  return VM_Version::L1_line_size();
+}
--- a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -639,3 +639,8 @@
 #endif
 }
 #endif
+
+int os::extra_bang_size_in_bytes() {
+  // JDK-8050147 requires the full cache line bang for x86.
+  return VM_Version::L1_line_size();
+}
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -170,7 +170,7 @@
 // removes the need to bang the stack in the deoptimization blob which
 // in turn simplifies stack overflow handling.
 int LIR_Assembler::bang_size_in_bytes() const {
-  return MAX2(initial_frame_size_in_bytes(), _compilation->interpreter_frame_size());
+  return MAX2(initial_frame_size_in_bytes() + os::extra_bang_size_in_bytes(), _compilation->interpreter_frame_size());
 }
 
 void LIR_Assembler::emit_exception_entries(ExceptionInfoList* info_list) {
--- a/hotspot/src/share/vm/ci/ciEnv.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/ci/ciEnv.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -926,7 +926,7 @@
 #ifdef ASSERT
     if (!counter_changed && !PrintCompilation) {
       // Print out the compile task that failed
-      _task->print_line();
+      _task->print_tty();
     }
 #endif
     assert(counter_changed, "failed dependencies, but counter didn't change");
--- a/hotspot/src/share/vm/classfile/classLoader.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -1528,7 +1528,7 @@
               if (TieredCompilation && TieredStopAtLevel >= CompLevel_full_optimization) {
                 // Clobber the first compile and force second tier compilation
                 nmethod* nm = m->code();
-                if (nm != NULL) {
+                if (nm != NULL && !m->is_method_handle_intrinsic()) {
                   // Throw out the code so that the code cache doesn't fill up
                   nm->make_not_entrant();
                   m->clear_code();
@@ -1547,7 +1547,7 @@
             }
 
             nmethod* nm = m->code();
-            if (nm != NULL) {
+            if (nm != NULL && !m->is_method_handle_intrinsic()) {
               // Throw out the code so that the code cache doesn't fill up
               nm->make_not_entrant();
               m->clear_code();
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -746,7 +746,7 @@
   // mark metadata seen on the stack and code cache so we can delete
   // unneeded entries.
   bool has_redefined_a_class = JvmtiExport::has_redefined_a_class();
-  MetadataOnStackMark md_on_stack;
+  MetadataOnStackMark md_on_stack(has_redefined_a_class);
   if (has_redefined_a_class) {
     // purge_previous_versions also cleans weak method links. Because
     // one method's MDO can reference another method from another
--- a/hotspot/src/share/vm/classfile/metadataOnStackMark.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/classfile/metadataOnStackMark.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,7 +41,7 @@
 // Walk metadata on the stack and mark it so that redefinition doesn't delete
 // it.  Class unloading also walks the previous versions and might try to
 // delete it, so this class is used by class unloading also.
-MetadataOnStackMark::MetadataOnStackMark() {
+MetadataOnStackMark::MetadataOnStackMark(bool has_redefined_a_class) {
   assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
   NOT_PRODUCT(_is_active = true;)
   if (_marked_objects == NULL) {
@@ -49,7 +49,7 @@
   }
 
   Threads::metadata_do(Metadata::mark_on_stack);
-  if (JvmtiExport::has_redefined_a_class()) {
+  if (has_redefined_a_class) {
     CodeCache::alive_nmethods_do(nmethod::mark_on_stack);
   }
   CompileBroker::mark_on_stack();
--- a/hotspot/src/share/vm/classfile/metadataOnStackMark.hpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/classfile/metadataOnStackMark.hpp	Wed Jul 05 20:01:50 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,7 @@
 class MetadataOnStackMark : public StackObj {
   NOT_PRODUCT(static bool _is_active;)
  public:
-  MetadataOnStackMark();
+  MetadataOnStackMark(bool has_redefined_a_class);
   ~MetadataOnStackMark();
   static void record(Metadata* m);
 };
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -52,6 +52,7 @@
 #include "oops/typeArrayKlass.hpp"
 #include "prims/jvmtiEnvBase.hpp"
 #include "prims/methodHandles.hpp"
+#include "runtime/arguments.hpp"
 #include "runtime/biasedLocking.hpp"
 #include "runtime/fieldType.hpp"
 #include "runtime/handles.inline.hpp"
@@ -2274,7 +2275,11 @@
     m = Method::make_method_handle_intrinsic(iid, signature, CHECK_(empty));
     CompileBroker::compile_method(m, InvocationEntryBci, CompLevel_highest_tier,
                                   methodHandle(), CompileThreshold, "MH", CHECK_(empty));
-
+    // Check if we need to have compiled code but we don't.
+    if (!Arguments::is_interpreter_only() && !m->has_compiled_code()) {
+      THROW_MSG_(vmSymbols::java_lang_VirtualMachineError(),
+                 "out of space in CodeCache for method handle intrinsic", empty);
+    }
     // Now grab the lock.  We might have to throw away the new method,
     // if a racing thread has managed to install one at the same time.
     {
@@ -2288,6 +2293,9 @@
   }
 
   assert(spe != NULL && spe->method() != NULL, "");
+  assert(Arguments::is_interpreter_only() || (spe->method()->has_compiled_code() &&
+         spe->method()->code()->entry_point() == spe->method()->from_compiled_entry()),
+         "MH intrinsic invariant");
   return spe->method();
 }
 
--- a/hotspot/src/share/vm/code/codeCache.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/code/codeCache.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -249,6 +249,7 @@
 #define FOR_ALL_BLOBS(var)       for (CodeBlob *var =       first() ; var != NULL; var =       next(var) )
 #define FOR_ALL_ALIVE_BLOBS(var) for (CodeBlob *var = alive(first()); var != NULL; var = alive(next(var)))
 #define FOR_ALL_ALIVE_NMETHODS(var) for (nmethod *var = alive_nmethod(first()); var != NULL; var = alive_nmethod(next(var)))
+#define FOR_ALL_NMETHODS(var) for (nmethod *var = first_nmethod(); var != NULL; var = next_nmethod(var))
 
 
 bool CodeCache::contains(void *p) {
@@ -687,7 +688,9 @@
 void CodeCache::mark_all_nmethods_for_deoptimization() {
   MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
   FOR_ALL_ALIVE_NMETHODS(nm) {
-    nm->mark_for_deoptimization();
+    if (!nm->method()->is_method_handle_intrinsic()) {
+      nm->mark_for_deoptimization();
+    }
   }
 }
 
@@ -967,6 +970,25 @@
   }
 }
 
+void CodeCache::print_codelist(outputStream* st) {
+  assert_locked_or_safepoint(CodeCache_lock);
+
+  FOR_ALL_NMETHODS(p) {
+    ResourceMark rm;
+    char *method_name = p->method()->name_and_sig_as_C_string();
+    st->print_cr("%d %d %s ["INTPTR_FORMAT", "INTPTR_FORMAT" - "INTPTR_FORMAT"]",
+                 p->compile_id(), p->comp_level(), method_name, (intptr_t)p->header_begin(),
+                 (intptr_t)p->code_begin(), (intptr_t)p->code_end());
+  }
+}
+
+void CodeCache::print_layout(outputStream* st) {
+  assert_locked_or_safepoint(CodeCache_lock);
+  ResourceMark rm;
+
+  print_summary(st, true);
+}
+
 void CodeCache::log_state(outputStream* st) {
   st->print(" total_blobs='" UINT32_FORMAT "' nmethods='" UINT32_FORMAT "'"
             " adapters='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'",
--- a/hotspot/src/share/vm/code/codeCache.hpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/code/codeCache.hpp	Wed Jul 05 20:01:50 2017 +0200
@@ -152,6 +152,10 @@
   static void print_summary(outputStream* st, bool detailed = true); // Prints a summary of the code cache usage
   static void log_state(outputStream* st);
 
+  // Dcmd (Diagnostic commands)
+  static void print_codelist(outputStream* st);
+  static void print_layout(outputStream* st);
+
   // The full limits of the codeCache
   static address  low_bound()                    { return (address) _heap->low_boundary(); }
   static address  high_bound()                   { return (address) _heap->high_boundary(); }
--- a/hotspot/src/share/vm/code/compiledIC.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/code/compiledIC.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -595,6 +595,7 @@
   } else {
     // Callee is interpreted code.  In any case entering the interpreter
     // puts a converter-frame on the stack to save arguments.
+    assert(!m->is_method_handle_intrinsic(), "Compiled code should never call interpreter MH intrinsics");
     info._to_interpreter = true;
     info._entry      = m()->get_c2i_entry();
   }
--- a/hotspot/src/share/vm/code/nmethod.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/code/nmethod.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -2062,7 +2062,7 @@
                "metadata must be found in exactly one place");
         if (r->metadata_is_immediate() && r->metadata_value() != NULL) {
           Metadata* md = r->metadata_value();
-          f(md);
+          if (md != _method) f(md);
         }
       } else if (iter.type() == relocInfo::virtual_call_type) {
         // Check compiledIC holders associated with this nmethod
--- a/hotspot/src/share/vm/code/nmethod.hpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/code/nmethod.hpp	Wed Jul 05 20:01:50 2017 +0200
@@ -448,7 +448,10 @@
   // alive.  It is used when an uncommon trap happens.  Returns true
   // if this thread changed the state of the nmethod or false if
   // another thread performed the transition.
-  bool  make_not_entrant() { return make_not_entrant_or_zombie(not_entrant); }
+  bool  make_not_entrant() {
+    assert(!method()->is_method_handle_intrinsic(), "Cannot make MH intrinsic not entrant");
+    return make_not_entrant_or_zombie(not_entrant);
+  }
   bool  make_zombie()      { return make_not_entrant_or_zombie(zombie); }
 
   // used by jvmti to track if the unload event has been reported
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -166,7 +166,7 @@
     StringLogMessage lm;
     stringStream sstr = lm.stream();
     // msg.time_stamp().update_to(tty->time_stamp().ticks());
-    task->print_compilation(&sstr, NULL, true);
+    task->print_compilation(&sstr, NULL, true, false);
     log(thread, "%s", (const char*)lm);
   }
 
@@ -328,7 +328,6 @@
   if (nm == NULL)  _code_handle = NULL;  // drop the handle also
 }
 
-
 void CompileTask::mark_on_stack() {
   // Mark these methods as something redefine classes cannot remove.
   _method->set_on_stack(true);
@@ -338,18 +337,6 @@
 }
 
 // ------------------------------------------------------------------
-// CompileTask::print
-void CompileTask::print() {
-  tty->print("<CompileTask compile_id=%d ", _compile_id);
-  tty->print("method=");
-  _method->print_name(tty);
-  tty->print_cr(" osr_bci=%d is_blocking=%s is_complete=%s is_success=%s>",
-             _osr_bci, bool_to_str(_is_blocking),
-             bool_to_str(_is_complete), bool_to_str(_is_success));
-}
-
-
-// ------------------------------------------------------------------
 // CompileTask::print_line_on_error
 //
 // This function is called by fatal error handler when the thread
@@ -367,19 +354,18 @@
 
 // ------------------------------------------------------------------
 // CompileTask::print_line
-void CompileTask::print_line() {
+void CompileTask::print_tty() {
   ttyLocker ttyl;  // keep the following output all in one block
   // print compiler name if requested
   if (CIPrintCompilerName) tty->print("%s:", CompileBroker::compiler_name(comp_level()));
-  print_compilation();
+    print_compilation(tty);
 }
 
-
 // ------------------------------------------------------------------
 // CompileTask::print_compilation_impl
 void CompileTask::print_compilation_impl(outputStream* st, Method* method, int compile_id, int comp_level,
                                          bool is_osr_method, int osr_bci, bool is_blocking,
-                                         const char* msg, bool short_form) {
+                                         const char* msg, bool short_form, bool cr) {
   if (!short_form) {
     st->print("%7d ", (int) st->time_stamp().milliseconds());  // print timestamp
   }
@@ -428,7 +414,7 @@
   if (msg != NULL) {
     st->print("   %s", msg);
   }
-  if (!short_form) {
+  if (cr) {
     st->cr();
   }
 }
@@ -494,9 +480,9 @@
 
 // ------------------------------------------------------------------
 // CompileTask::print_compilation
-void CompileTask::print_compilation(outputStream* st, const char* msg, bool short_form) {
+void CompileTask::print_compilation(outputStream* st, const char* msg, bool short_form, bool cr) {
   bool is_osr_method = osr_bci() != InvocationEntryBci;
-  print_compilation_impl(st, method(), compile_id(), comp_level(), is_osr_method, osr_bci(), is_blocking(), msg, short_form);
+  print_compilation_impl(st, method(), compile_id(), comp_level(), is_osr_method, osr_bci(), is_blocking(), msg, short_form, cr);
 }
 
 // ------------------------------------------------------------------
@@ -621,7 +607,9 @@
   // Mark the method as being in the compile queue.
   task->method()->set_queued_for_compilation();
 
-  NOT_PRODUCT(print();)
+  if (CIPrintCompileQueue) {
+    print_tty();
+  }
 
   if (LogCompilation && xtty != NULL) {
     task->log_task_queued();
@@ -786,24 +774,40 @@
   }
 }
 
-#ifndef PRODUCT
-/**
- * Print entire compilation queue.
- */
-void CompileQueue::print() {
-  if (CIPrintCompileQueue) {
-    ttyLocker ttyl;
-    tty->print_cr("Contents of %s", name());
-    tty->print_cr("----------------------");
-    CompileTask* task = _first;
+
+CompileQueue* CompileBroker::compile_queue(int comp_level) {
+  if (is_c2_compile(comp_level)) return _c2_compile_queue;
+  if (is_c1_compile(comp_level)) return _c1_compile_queue;
+  return NULL;
+}
+
+
+void CompileBroker::print_compile_queues(outputStream* st) {
+  _c1_compile_queue->print(st);
+  _c2_compile_queue->print(st);
+}
+
+
+void CompileQueue::print(outputStream* st) {
+  assert_locked_or_safepoint(lock());
+  st->print_cr("Contents of %s", name());
+  st->print_cr("----------------------------");
+  CompileTask* task = _first;
+  if (task == NULL) {
+    st->print_cr("Empty");;
+  } else {
     while (task != NULL) {
-      task->print_line();
+      task->print_compilation(st, NULL, true, true);
       task = task->next();
     }
-    tty->print_cr("----------------------");
   }
+  st->print_cr("----------------------------");
 }
-#endif // PRODUCT
+
+void CompileQueue::print_tty() {
+  ttyLocker ttyl;
+  print(tty);
+}
 
 CompilerCounters::CompilerCounters(const char* thread_name, int instance, TRAPS) {
 
@@ -1068,11 +1072,11 @@
 #endif // !ZERO && !SHARK
   // Initialize the compilation queue
   if (c2_compiler_count > 0) {
-    _c2_compile_queue  = new CompileQueue("C2 CompileQueue",  MethodCompileQueue_lock);
+    _c2_compile_queue  = new CompileQueue("C2 compile queue",  MethodCompileQueue_lock);
     _compilers[1]->set_num_compiler_threads(c2_compiler_count);
   }
   if (c1_compiler_count > 0) {
-    _c1_compile_queue  = new CompileQueue("C1 CompileQueue",  MethodCompileQueue_lock);
+    _c1_compile_queue  = new CompileQueue("C1 compile queue",  MethodCompileQueue_lock);
     _compilers[0]->set_num_compiler_threads(c1_compiler_count);
   }
 
@@ -1892,7 +1896,7 @@
 void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
   if (PrintCompilation) {
     ResourceMark rm;
-    task->print_line();
+    task->print_tty();
   }
   elapsedTimer time;
 
--- a/hotspot/src/share/vm/compiler/compileBroker.hpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/compiler/compileBroker.hpp	Wed Jul 05 20:01:50 2017 +0200
@@ -111,14 +111,14 @@
 private:
   static void  print_compilation_impl(outputStream* st, Method* method, int compile_id, int comp_level,
                                       bool is_osr_method = false, int osr_bci = -1, bool is_blocking = false,
-                                      const char* msg = NULL, bool short_form = false);
+                                      const char* msg = NULL, bool short_form = false, bool cr = true);
 
 public:
-  void         print_compilation(outputStream* st = tty, const char* msg = NULL, bool short_form = false);
-  static void  print_compilation(outputStream* st, const nmethod* nm, const char* msg = NULL, bool short_form = false) {
+  void         print_compilation(outputStream* st = tty, const char* msg = NULL, bool short_form = false, bool cr = true);
+  static void  print_compilation(outputStream* st, const nmethod* nm, const char* msg = NULL, bool short_form = false, bool cr = true) {
     print_compilation_impl(st, nm->method(), nm->compile_id(), nm->comp_level(),
                            nm->is_osr_method(), nm->is_osr_method() ? nm->osr_entry_bci() : -1, /*is_blocking*/ false,
-                           msg, short_form);
+                           msg, short_form, cr);
   }
 
   static void  print_inlining(outputStream* st, ciMethod* method, int inline_level, int bci, const char* msg = NULL);
@@ -131,8 +131,7 @@
 
   static void  print_inline_indent(int inline_level, outputStream* st = tty);
 
-  void         print();
-  void         print_line();
+  void         print_tty();
   void         print_line_on_error(outputStream* st, char* buf, int buflen);
 
   void         log_task(xmlStream* log);
@@ -234,7 +233,8 @@
   // Redefine Classes support
   void mark_on_stack();
   void free_all();
-  NOT_PRODUCT (void print();)
+  void print_tty();
+  void print(outputStream* st = tty);
 
   ~CompileQueue() {
     assert (is_empty(), " Compile Queue must be empty");
@@ -341,7 +341,7 @@
   static void init_compiler_threads(int c1_compiler_count, int c2_compiler_count);
   static bool compilation_is_complete  (methodHandle method, int osr_bci, int comp_level);
   static bool compilation_is_prohibited(methodHandle method, int osr_bci, int comp_level);
-  static bool is_compile_blocking      ();
+  static bool is_compile_blocking();
   static void preload_classes          (methodHandle method, TRAPS);
 
   static CompileTask* create_compile_task(CompileQueue* queue,
@@ -369,11 +369,8 @@
                                   int hot_count,
                                   const char* comment,
                                   Thread* thread);
-  static CompileQueue* compile_queue(int comp_level) {
-    if (is_c2_compile(comp_level)) return _c2_compile_queue;
-    if (is_c1_compile(comp_level)) return _c1_compile_queue;
-    return NULL;
-  }
+
+  static CompileQueue* compile_queue(int comp_level);
   static bool init_compiler_runtime();
   static void shutdown_compiler_runtime(AbstractCompiler* comp, CompilerThread* thread);
 
@@ -390,6 +387,7 @@
   }
 
   static bool compilation_is_in_queue(methodHandle method);
+  static void print_compile_queues(outputStream* st);
   static int queue_size(int comp_level) {
     CompileQueue *q = compile_queue(comp_level);
     return q != NULL ? q->size() : 0;
--- a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -369,33 +369,45 @@
 #endif
 }
 
-bool
-G1BlockOffsetArray::verify_for_object(HeapWord* obj_start,
-                                      size_t word_size) const {
-  size_t first_card = _array->index_for(obj_start);
-  size_t last_card = _array->index_for(obj_start + word_size - 1);
-  if (!_array->is_card_boundary(obj_start)) {
-    // If the object is not on a card boundary the BOT entry of the
-    // first card should point to another object so we should not
-    // check that one.
-    first_card += 1;
-  }
-  for (size_t card = first_card; card <= last_card; card += 1) {
-    HeapWord* card_addr = _array->address_for_index(card);
-    HeapWord* block_start = block_start_const(card_addr);
-    if (block_start != obj_start) {
-      gclog_or_tty->print_cr("block start: "PTR_FORMAT" is incorrect - "
-                             "card index: "SIZE_FORMAT" "
-                             "card addr: "PTR_FORMAT" BOT entry: %u "
-                             "obj: "PTR_FORMAT" word size: "SIZE_FORMAT" "
-                             "cards: ["SIZE_FORMAT","SIZE_FORMAT"]",
-                             p2i(block_start), card, p2i(card_addr),
-                             _array->offset_array(card),
-                             p2i(obj_start), word_size, first_card, last_card);
-      return false;
+void G1BlockOffsetArray::verify() const {
+  assert(gsp()->bottom() < gsp()->top(), "Only non-empty regions should be verified.");
+  size_t start_card = _array->index_for(gsp()->bottom());
+  size_t end_card = _array->index_for(gsp()->top() - 1);
+
+  for (size_t current_card = start_card; current_card < end_card; current_card++) {
+    u_char entry = _array->offset_array(current_card);
+    if (entry < N_words) {
+      // The entry should point to an object before the current card. Verify that
+      // it is possible to walk from that object in to the current card by just
+      // iterating over the objects following it.
+      HeapWord* card_address = _array->address_for_index(current_card);
+      HeapWord* obj_end = card_address - entry;
+      while (obj_end < card_address) {
+        HeapWord* obj = obj_end;
+        size_t obj_size = block_size(obj);
+        obj_end = obj + obj_size;
+        guarantee(obj_end > obj && obj_end <= gsp()->top(),
+            err_msg("Invalid object end. obj: " PTR_FORMAT " obj_size: " SIZE_FORMAT " obj_end: " PTR_FORMAT " top: " PTR_FORMAT,
+                p2i(obj), obj_size, p2i(obj_end), p2i(gsp()->top())));
+      }
+    } else {
+      // Because we refine the BOT based on which cards are dirty there is not much we can verify here.
+      // We need to make sure that we are going backwards and that we don't pass the start of the
+      // corresponding heap region. But that is about all we can verify.
+      size_t backskip = BlockOffsetArray::entry_to_cards_back(entry);
+      guarantee(backskip >= 1, "Must be going back at least one card.");
+
+      size_t max_backskip = current_card - start_card;
+      guarantee(backskip <= max_backskip,
+          err_msg("Going backwards beyond the start_card. start_card: " SIZE_FORMAT " current_card: " SIZE_FORMAT " backskip: " SIZE_FORMAT,
+              start_card, current_card, backskip));
+
+      HeapWord* backskip_address = _array->address_for_index(current_card - backskip);
+      guarantee(backskip_address >= gsp()->bottom(),
+          err_msg("Going backwards beyond bottom of the region: bottom: " PTR_FORMAT ", backskip_address: " PTR_FORMAT,
+              p2i(gsp()->bottom()), p2i(backskip_address)));
     }
   }
-  return true;
 }
 
 #ifndef PRODUCT
--- a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp	Wed Jul 05 20:01:50 2017 +0200
@@ -304,13 +304,9 @@
   virtual HeapWord* block_start_unsafe(const void* addr);
   virtual HeapWord* block_start_unsafe_const(const void* addr) const;
 
-  // Used by region verification. Checks that the contents of the
-  // BOT reflect that there's a single object that spans the address
-  // range [obj_start, obj_start + word_size); returns true if this is
-  // the case, returns false if it's not.
-  bool verify_for_object(HeapWord* obj_start, size_t word_size) const;
+  void check_all_cards(size_t left_card, size_t right_card) const;
 
-  void check_all_cards(size_t left_card, size_t right_card) const;
+  void verify() const;
 
   virtual void print_on(outputStream* out) PRODUCT_RETURN;
 };
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CodeCacheRemSet.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -48,6 +48,7 @@
     return hash ^ (hash >> 7); // code heap blocks are 128byte aligned
   }
 
+  void remove_entry(Entry* e, Entry* previous);
   Entry* new_entry(nmethod* nm);
 
  public:
@@ -67,7 +68,7 @@
   void nmethods_do(CodeBlobClosure* blk);
 
   template<typename CB>
-  void remove_if(CB& should_remove);
+  int remove_if(CB& should_remove);
 
   static void purge_list_append(CodeRootSetTable* tbl);
   static void purge();
@@ -91,6 +92,18 @@
   return entry;
 }
 
+void CodeRootSetTable::remove_entry(Entry* e, Entry* previous) {
+  int index = hash_to_index(e->hash());
+  assert((e == bucket(index)) == (previous == NULL), "if e is the first entry then previous should be null");
+
+  if (previous == NULL) {
+    set_entry(index, e->next());
+  } else {
+    previous->set_next(e->next());
+  }
+  free_entry(e);
+}
+
 CodeRootSetTable::~CodeRootSetTable() {
   for (int index = 0; index < table_size(); ++index) {
     for (Entry* e = bucket(index); e != NULL; ) {
@@ -133,12 +146,7 @@
   Entry* previous = NULL;
   for (Entry* e = bucket(index); e != NULL; previous = e, e = e->next()) {
     if (e->literal() == nm) {
-      if (previous != NULL) {
-        previous->set_next(e->next());
-      } else {
-        set_entry(index, e->next());
-      }
-      free_entry(e);
+      remove_entry(e, previous);
       return true;
     }
   }
@@ -163,25 +171,23 @@
 }
 
 template<typename CB>
-void CodeRootSetTable::remove_if(CB& should_remove) {
+int CodeRootSetTable::remove_if(CB& should_remove) {
+  int num_removed = 0;
   for (int index = 0; index < table_size(); ++index) {
     Entry* previous = NULL;
     Entry* e = bucket(index);
     while (e != NULL) {
       Entry* next = e->next();
       if (should_remove(e->literal())) {
-        if (previous != NULL) {
-          previous->set_next(next);
-        } else {
-          set_entry(index, next);
-        }
-        free_entry(e);
+        remove_entry(e, previous);
+        ++num_removed;
       } else {
         previous = e;
       }
       e = next;
     }
   }
+  return num_removed;
 }
 
 G1CodeRootSet::~G1CodeRootSet() {
@@ -320,14 +326,19 @@
   bool operator() (nmethod* nm) {
     _detector._points_into = false;
     _blobs.do_code_blob(nm);
-    return _detector._points_into;
+    return !_detector._points_into;
   }
 };
 
 void G1CodeRootSet::clean(HeapRegion* owner) {
   CleanCallback should_clean(owner);
   if (_table != NULL) {
-    _table->remove_if(should_clean);
+    int removed = _table->remove_if(should_clean);
+    assert((size_t)removed <= _length, "impossible");
+    _length -= removed;
+  }
+  if (_length == 0) {
+    clear();
   }
 }
 
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -861,7 +861,6 @@
   HeapWord* prev_p = NULL;
   VerifyLiveClosure vl_cl(g1, vo);
   bool is_humongous = isHumongous();
-  bool do_bot_verify = !is_young();
   size_t object_num = 0;
   while (p < top()) {
     oop obj = oop(p);
@@ -878,15 +877,6 @@
        return;
     }
 
-    // If it returns false, verify_for_object() will output the
-    // appropriate message.
-    if (do_bot_verify &&
-        !g1->is_obj_dead(obj, this) &&
-        !_offsets.verify_for_object(p, obj_size)) {
-      *failures = true;
-      return;
-    }
-
     if (!g1->is_obj_dead_cond(obj, this, vo)) {
       if (obj->is_oop()) {
         Klass* klass = obj->klass();
@@ -924,6 +914,10 @@
     p += obj_size;
   }
 
+  if (!is_young() && !is_empty()) {
+    _offsets.verify();
+  }
+
   if (p != top()) {
     gclog_or_tty->print_cr("end of last object "PTR_FORMAT" "
                            "does not match top "PTR_FORMAT, p, top());
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -460,6 +460,8 @@
 oop InstanceKlass::init_lock() const {
   // return the init lock from the mirror
   oop lock = java_lang_Class::init_lock(java_mirror());
+  // Prevent reordering with any access of initialization state
+  OrderAccess::loadload();
   assert((oop)lock != NULL || !is_not_initialized(), // initialized or in_error state
          "only fully initialized state can have a null lock");
   return lock;
@@ -2437,16 +2439,6 @@
     assert(breakpoints() == 0x0, "should have cleared breakpoints");
   }
 
-  // deallocate information about previous versions
-  if (_previous_versions != NULL) {
-    for (int i = _previous_versions->length() - 1; i >= 0; i--) {
-      PreviousVersionNode * pv_node = _previous_versions->at(i);
-      delete pv_node;
-    }
-    delete _previous_versions;
-    _previous_versions = NULL;
-  }
-
   // deallocate the cached class file
   if (_cached_class_file != NULL) {
     os::free(_cached_class_file, mtClass);
@@ -3020,16 +3012,17 @@
   st->print(BULLET"field type annotations:  "); fields_type_annotations()->print_value_on(st); st->cr();
   {
     bool have_pv = false;
-    PreviousVersionWalker pvw(Thread::current(), (InstanceKlass*)this);
-    for (PreviousVersionNode * pv_node = pvw.next_previous_version();
-         pv_node != NULL; pv_node = pvw.next_previous_version()) {
+    // previous versions are linked together through the InstanceKlass
+    for (InstanceKlass* pv_node = _previous_versions;
+         pv_node != NULL;
+         pv_node = pv_node->previous_versions()) {
       if (!have_pv)
         st->print(BULLET"previous version:  ");
       have_pv = true;
-      pv_node->prev_constant_pool()->print_value_on(st);
+      pv_node->constants()->print_value_on(st);
     }
     if (have_pv) st->cr();
-  } // pvw is cleaned up
+  }
 
   if (generic_signature() != NULL) {
     st->print(BULLET"generic signature: ");
@@ -3443,92 +3436,92 @@
 // RedefineClasses() support for previous versions:
 
 // Purge previous versions
-static void purge_previous_versions_internal(InstanceKlass* ik, int emcp_method_count) {
+void InstanceKlass::purge_previous_versions(InstanceKlass* ik) {
   if (ik->previous_versions() != NULL) {
     // This klass has previous versions so see what we can cleanup
     // while it is safe to do so.
 
     int deleted_count = 0;    // leave debugging breadcrumbs
     int live_count = 0;
-    ClassLoaderData* loader_data = ik->class_loader_data() == NULL ?
-                       ClassLoaderData::the_null_class_loader_data() :
-                       ik->class_loader_data();
+    ClassLoaderData* loader_data = ik->class_loader_data();
+    assert(loader_data != NULL, "should never be null");
 
     // RC_TRACE macro has an embedded ResourceMark
-    RC_TRACE(0x00000200, ("purge: %s: previous version length=%d",
-      ik->external_name(), ik->previous_versions()->length()));
-
-    for (int i = ik->previous_versions()->length() - 1; i >= 0; i--) {
-      // check the previous versions array
-      PreviousVersionNode * pv_node = ik->previous_versions()->at(i);
-      ConstantPool* cp_ref = pv_node->prev_constant_pool();
-      assert(cp_ref != NULL, "cp ref was unexpectedly cleared");
-
-      ConstantPool* pvcp = cp_ref;
+    RC_TRACE(0x00000200, ("purge: %s: previous versions", ik->external_name()));
+
+    // previous versions are linked together through the InstanceKlass
+    InstanceKlass* pv_node = ik->previous_versions();
+    InstanceKlass* last = ik;
+    int version = 0;
+
+    // check the previous versions list
+    for (; pv_node != NULL; ) {
+
+      ConstantPool* pvcp = pv_node->constants();
+      assert(pvcp != NULL, "cp ref was unexpectedly cleared");
+
       if (!pvcp->on_stack()) {
         // If the constant pool isn't on stack, none of the methods
-        // are executing.  Delete all the methods, the constant pool and
-        // and this previous version node.
-        GrowableArray<Method*>* method_refs = pv_node->prev_EMCP_methods();
-        if (method_refs != NULL) {
-          for (int j = method_refs->length() - 1; j >= 0; j--) {
-            Method* method = method_refs->at(j);
-            assert(method != NULL, "method ref was unexpectedly cleared");
-            method_refs->remove_at(j);
-            // method will be freed with associated class.
-          }
-        }
-        // Remove the constant pool
-        delete pv_node;
-        // Since we are traversing the array backwards, we don't have to
-        // do anything special with the index.
-        ik->previous_versions()->remove_at(i);
+        // are executing.  Unlink this previous_version.
+        // The previous version InstanceKlass is on the ClassLoaderData deallocate list
+        // so will be deallocated during the next phase of class unloading.
+        pv_node = pv_node->previous_versions();
+        last->link_previous_versions(pv_node);
         deleted_count++;
+        version++;
         continue;
       } else {
-        RC_TRACE(0x00000200, ("purge: previous version @%d is alive", i));
+        RC_TRACE(0x00000200, ("purge: previous version " INTPTR_FORMAT " is alive",
+                              pv_node));
         assert(pvcp->pool_holder() != NULL, "Constant pool with no holder");
         guarantee (!loader_data->is_unloading(), "unloaded classes can't be on the stack");
         live_count++;
       }
 
-      // At least one method is live in this previous version, clean out
-      // the others or mark them as obsolete.
-      GrowableArray<Method*>* method_refs = pv_node->prev_EMCP_methods();
+      // At least one method is live in this previous version so clean its MethodData.
+      // Reset dead EMCP methods not to get breakpoints.
+      // All methods are deallocated when all of the methods for this class are no
+      // longer running.
+      Array<Method*>* method_refs = pv_node->methods();
       if (method_refs != NULL) {
         RC_TRACE(0x00000200, ("purge: previous methods length=%d",
           method_refs->length()));
-        for (int j = method_refs->length() - 1; j >= 0; j--) {
+        for (int j = 0; j < method_refs->length(); j++) {
           Method* method = method_refs->at(j);
-          assert(method != NULL, "method ref was unexpectedly cleared");
-
-          // Remove the emcp method if it's not executing
-          // If it's been made obsolete by a redefinition of a non-emcp
-          // method, mark it as obsolete but leave it to clean up later.
+
           if (!method->on_stack()) {
-            method_refs->remove_at(j);
-          } else if (emcp_method_count == 0) {
-            method->set_is_obsolete();
+            // no breakpoints for non-running methods
+            if (method->is_running_emcp()) {
+              method->set_running_emcp(false);
+            }
           } else {
+            assert (method->is_obsolete() || method->is_running_emcp(),
+                    "emcp method cannot run after emcp bit is cleared");
             // RC_TRACE macro has an embedded ResourceMark
             RC_TRACE(0x00000200,
               ("purge: %s(%s): prev method @%d in version @%d is alive",
               method->name()->as_C_string(),
-              method->signature()->as_C_string(), j, i));
+              method->signature()->as_C_string(), j, version));
             if (method->method_data() != NULL) {
-              // Clean out any weak method links
+              // Clean out any weak method links for running methods
+              // (also should include not EMCP methods)
               method->method_data()->clean_weak_method_links();
             }
           }
         }
       }
+      // next previous version
+      last = pv_node;
+      pv_node = pv_node->previous_versions();
+      version++;
     }
-    assert(ik->previous_versions()->length() == live_count, "sanity check");
     RC_TRACE(0x00000200,
       ("purge: previous version stats: live=%d, deleted=%d", live_count,
       deleted_count));
   }
 
+  // Clean MethodData of this class's methods so they don't refer to
+  // old methods that are no longer running.
   Array<Method*>* methods = ik->methods();
   int num_methods = methods->length();
   for (int index2 = 0; index2 < num_methods; ++index2) {
@@ -3538,122 +3531,30 @@
   }
 }
 
-// External interface for use during class unloading.
-void InstanceKlass::purge_previous_versions(InstanceKlass* ik) {
-  // Call with >0 emcp methods since they are not currently being redefined.
-  purge_previous_versions_internal(ik, 1);
-}
-
-
-// Potentially add an information node that contains pointers to the
-// interesting parts of the previous version of the_class.
-// This is also where we clean out any unused references.
-// Note that while we delete nodes from the _previous_versions
-// array, we never delete the array itself until the klass is
-// unloaded. The has_been_redefined() query depends on that fact.
-//
-void InstanceKlass::add_previous_version(instanceKlassHandle ikh,
-       BitMap* emcp_methods, int emcp_method_count) {
-  assert(Thread::current()->is_VM_thread(),
-         "only VMThread can add previous versions");
-
-  if (_previous_versions == NULL) {
-    // This is the first previous version so make some space.
-    // Start with 2 elements under the assumption that the class
-    // won't be redefined much.
-    _previous_versions =  new (ResourceObj::C_HEAP, mtClass)
-                            GrowableArray<PreviousVersionNode *>(2, true);
-  }
-
-  ConstantPool* cp_ref = ikh->constants();
-
-  // RC_TRACE macro has an embedded ResourceMark
-  RC_TRACE(0x00000400, ("adding previous version ref for %s @%d, EMCP_cnt=%d "
-                        "on_stack=%d",
-    ikh->external_name(), _previous_versions->length(), emcp_method_count,
-    cp_ref->on_stack()));
-
-  // If the constant pool for this previous version of the class
-  // is not marked as being on the stack, then none of the methods
-  // in this previous version of the class are on the stack so
-  // we don't need to create a new PreviousVersionNode. However,
-  // we still need to examine older previous versions below.
-  Array<Method*>* old_methods = ikh->methods();
-
-  if (cp_ref->on_stack()) {
-    PreviousVersionNode * pv_node = NULL;
-    if (emcp_method_count == 0) {
-      // non-shared ConstantPool gets a reference
-      pv_node = new PreviousVersionNode(cp_ref, NULL);
-      RC_TRACE(0x00000400,
-          ("add: all methods are obsolete; flushing any EMCP refs"));
-    } else {
-      int local_count = 0;
-      GrowableArray<Method*>* method_refs = new (ResourceObj::C_HEAP, mtClass)
-          GrowableArray<Method*>(emcp_method_count, true);
-      for (int i = 0; i < old_methods->length(); i++) {
-        if (emcp_methods->at(i)) {
-            // this old method is EMCP. Save it only if it's on the stack
-            Method* old_method = old_methods->at(i);
-            if (old_method->on_stack()) {
-              method_refs->append(old_method);
-            }
-          if (++local_count >= emcp_method_count) {
-            // no more EMCP methods so bail out now
-            break;
-          }
-        }
-      }
-      // non-shared ConstantPool gets a reference
-      pv_node = new PreviousVersionNode(cp_ref, method_refs);
-    }
-    // append new previous version.
-    _previous_versions->append(pv_node);
-  }
-
-  // Since the caller is the VMThread and we are at a safepoint, this
-  // is a good time to clear out unused references.
-
-  RC_TRACE(0x00000400, ("add: previous version length=%d",
-    _previous_versions->length()));
-
-  // Purge previous versions not executing on the stack
-  purge_previous_versions_internal(this, emcp_method_count);
-
+void InstanceKlass::mark_newly_obsolete_methods(Array<Method*>* old_methods,
+                                                int emcp_method_count) {
   int obsolete_method_count = old_methods->length() - emcp_method_count;
 
   if (emcp_method_count != 0 && obsolete_method_count != 0 &&
-      _previous_versions->length() > 0) {
+      _previous_versions != NULL) {
     // We have a mix of obsolete and EMCP methods so we have to
     // clear out any matching EMCP method entries the hard way.
     int local_count = 0;
     for (int i = 0; i < old_methods->length(); i++) {
-      if (!emcp_methods->at(i)) {
+      Method* old_method = old_methods->at(i);
+      if (old_method->is_obsolete()) {
         // only obsolete methods are interesting
-        Method* old_method = old_methods->at(i);
         Symbol* m_name = old_method->name();
         Symbol* m_signature = old_method->signature();
 
-        // we might not have added the last entry
-        for (int j = _previous_versions->length() - 1; j >= 0; j--) {
-          // check the previous versions array for non executing obsolete methods
-          PreviousVersionNode * pv_node = _previous_versions->at(j);
-
-          GrowableArray<Method*>* method_refs = pv_node->prev_EMCP_methods();
-          if (method_refs == NULL) {
-            // We have run into a PreviousVersion generation where
-            // all methods were made obsolete during that generation's
-            // RedefineClasses() operation. At the time of that
-            // operation, all EMCP methods were flushed so we don't
-            // have to go back any further.
-            //
-            // A NULL method_refs is different than an empty method_refs.
-            // We cannot infer any optimizations about older generations
-            // from an empty method_refs for the current generation.
-            break;
-          }
-
-          for (int k = method_refs->length() - 1; k >= 0; k--) {
+        // previous versions are linked together through the InstanceKlass
+        int j = 0;
+        for (InstanceKlass* prev_version = _previous_versions;
+             prev_version != NULL;
+             prev_version = prev_version->previous_versions(), j++) {
+
+          Array<Method*>* method_refs = prev_version->methods();
+          for (int k = 0; k < method_refs->length(); k++) {
             Method* method = method_refs->at(k);
 
             if (!method->is_obsolete() &&
@@ -3661,14 +3562,11 @@
                 method->signature() == m_signature) {
               // The current RedefineClasses() call has made all EMCP
               // versions of this method obsolete so mark it as obsolete
-              // and remove the reference.
               RC_TRACE(0x00000400,
                 ("add: %s(%s): flush obsolete method @%d in version @%d",
                 m_name->as_C_string(), m_signature->as_C_string(), k, j));
 
               method->set_is_obsolete();
-              // Leave obsolete methods on the previous version list to
-              // clean up later.
               break;
             }
           }
@@ -3676,9 +3574,9 @@
           // The previous loop may not find a matching EMCP method, but
           // that doesn't mean that we can optimize and not go any
           // further back in the PreviousVersion generations. The EMCP
-          // method for this generation could have already been deleted,
+          // method for this generation could have already been made obsolete,
           // but there still may be an older EMCP method that has not
-          // been deleted.
+          // been made obsolete.
         }
 
         if (++local_count >= obsolete_method_count) {
@@ -3688,15 +3586,69 @@
       }
     }
   }
+}
+
+// Save the scratch_class as the previous version if any of the methods are running.
+// The previous_versions are used to set breakpoints in EMCP methods and they are
+// also used to clean MethodData links to redefined methods that are no longer running.
+void InstanceKlass::add_previous_version(instanceKlassHandle scratch_class,
+                                         int emcp_method_count) {
+  assert(Thread::current()->is_VM_thread(),
+         "only VMThread can add previous versions");
+
+  // RC_TRACE macro has an embedded ResourceMark
+  RC_TRACE(0x00000400, ("adding previous version ref for %s, EMCP_cnt=%d",
+    scratch_class->external_name(), emcp_method_count));
+
+  // Clean out old previous versions
+  purge_previous_versions(this);
+
+  // Mark newly obsolete methods in remaining previous versions.  An EMCP method from
+  // a previous redefinition may be made obsolete by this redefinition.
+  Array<Method*>* old_methods = scratch_class->methods();
+  mark_newly_obsolete_methods(old_methods, emcp_method_count);
+
+  // If the constant pool for this previous version of the class
+  // is not marked as being on the stack, then none of the methods
+  // in this previous version of the class are on the stack so
+  // we don't need to add this as a previous version.
+  ConstantPool* cp_ref = scratch_class->constants();
+  if (!cp_ref->on_stack()) {
+    RC_TRACE(0x00000400, ("add: scratch class not added; no methods are running"));
+    return;
+  }
+
+  if (emcp_method_count != 0) {
+    // At least one method is still running, check for EMCP methods
+    for (int i = 0; i < old_methods->length(); i++) {
+      Method* old_method = old_methods->at(i);
+      if (!old_method->is_obsolete() && old_method->on_stack()) {
+        // if EMCP method (not obsolete) is on the stack, mark as EMCP so that
+        // we can add breakpoints for it.
+
+        // We set the method->on_stack bit during safepoints for class redefinition and
+        // class unloading and use this bit to set the is_running_emcp bit.
+        // After the safepoint, the on_stack bit is cleared and the running emcp
+        // method may exit.   If so, we would set a breakpoint in a method that
+        // is never reached, but this won't be noticeable to the programmer.
+        old_method->set_running_emcp(true);
+        RC_TRACE(0x00000400, ("add: EMCP method %s is on_stack " INTPTR_FORMAT,
+                              old_method->name_and_sig_as_C_string(), old_method));
+      } else if (!old_method->is_obsolete()) {
+        RC_TRACE(0x00000400, ("add: EMCP method %s is NOT on_stack " INTPTR_FORMAT,
+                              old_method->name_and_sig_as_C_string(), old_method));
+      }
+    }
+  }
+
+  // Add previous version if any methods are still running.
+  RC_TRACE(0x00000400, ("add: scratch class added; one of its methods is on_stack"));
+  assert(scratch_class->previous_versions() == NULL, "shouldn't have a previous version");
+  scratch_class->link_previous_versions(previous_versions());
+  link_previous_versions(scratch_class());
 } // end add_previous_version()
 
 
-// Determine if InstanceKlass has a previous version.
-bool InstanceKlass::has_previous_version() const {
-  return (_previous_versions != NULL && _previous_versions->length() > 0);
-} // end has_previous_version()
-
-
 Method* InstanceKlass::method_with_idnum(int idnum) {
   Method* m = NULL;
   if (idnum < methods()->length()) {
@@ -3722,61 +3674,3 @@
 unsigned char * InstanceKlass::get_cached_class_file_bytes() {
   return VM_RedefineClasses::get_cached_class_file_bytes(_cached_class_file);
 }
-
-
-// Construct a PreviousVersionNode entry for the array hung off
-// the InstanceKlass.
-PreviousVersionNode::PreviousVersionNode(ConstantPool* prev_constant_pool,
-  GrowableArray<Method*>* prev_EMCP_methods) {
-
-  _prev_constant_pool = prev_constant_pool;
-  _prev_EMCP_methods = prev_EMCP_methods;
-}
-
-
-// Destroy a PreviousVersionNode
-PreviousVersionNode::~PreviousVersionNode() {
-  if (_prev_constant_pool != NULL) {
-    _prev_constant_pool = NULL;
-  }
-
-  if (_prev_EMCP_methods != NULL) {
-    delete _prev_EMCP_methods;
-  }
-}
-
-// Construct a helper for walking the previous versions array
-PreviousVersionWalker::PreviousVersionWalker(Thread* thread, InstanceKlass *ik) {
-  _thread = thread;
-  _previous_versions = ik->previous_versions();
-  _current_index = 0;
-  _current_p = NULL;
-  _current_constant_pool_handle = constantPoolHandle(thread, ik->constants());
-}
-
-
-// Return the interesting information for the next previous version
-// of the klass. Returns NULL if there are no more previous versions.
-PreviousVersionNode* PreviousVersionWalker::next_previous_version() {
-  if (_previous_versions == NULL) {
-    // no previous versions so nothing to return
-    return NULL;
-  }
-
-  _current_p = NULL;  // reset to NULL
-  _current_constant_pool_handle = NULL;
-
-  int length = _previous_versions->length();
-
-  while (_current_index < length) {
-    PreviousVersionNode * pv_node = _previous_versions->at(_current_index++);
-
-    // Save a handle to the constant pool for this previous version,
-    // which keeps all the methods from being deallocated.
-    _current_constant_pool_handle = constantPoolHandle(_thread, pv_node->prev_constant_pool());
-    _current_p = pv_node;
-    return pv_node;
-  }
-
-  return NULL;
-} // end next_previous_version()
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp	Wed Jul 05 20:01:50 2017 +0200
@@ -59,7 +59,6 @@
 class fieldDescriptor;
 class DepChange;
 class nmethodBucket;
-class PreviousVersionNode;
 class JvmtiCachedClassFieldMap;
 class MemberNameTable;
 
@@ -205,7 +204,8 @@
     _misc_should_verify_class  = 1 << 2, // allow caching of preverification
     _misc_is_anonymous         = 1 << 3, // has embedded _host_klass field
     _misc_is_contended         = 1 << 4, // marked with contended annotation
-    _misc_has_default_methods  = 1 << 5  // class/superclass/implemented interfaces has default methods
+    _misc_has_default_methods  = 1 << 5, // class/superclass/implemented interfaces has default methods
+    _misc_has_been_redefined   = 1 << 6  // class has been redefined
   };
   u2              _misc_flags;
   u2              _minor_version;        // minor version number of class file
@@ -220,9 +220,8 @@
   nmethodBucket*  _dependencies;         // list of dependent nmethods
   nmethod*        _osr_nmethods_head;    // Head of list of on-stack replacement nmethods for this class
   BreakpointInfo* _breakpoints;          // bpt lists, managed by Method*
-  // Array of interesting part(s) of the previous version(s) of this
-  // InstanceKlass. See PreviousVersionWalker below.
-  GrowableArray<PreviousVersionNode *>* _previous_versions;
+  // Linked instanceKlasses of previous versions
+  InstanceKlass* _previous_versions;
   // JVMTI fields can be moved to their own structure - see 6315920
   // JVMTI: cached class file, before retransformable agent modified it in CFLH
   JvmtiCachedClassFileData* _cached_class_file;
@@ -608,19 +607,20 @@
   }
 
   // RedefineClasses() support for previous versions:
-  void add_previous_version(instanceKlassHandle ikh, BitMap *emcp_methods,
-         int emcp_method_count);
-  // If the _previous_versions array is non-NULL, then this klass
-  // has been redefined at least once even if we aren't currently
-  // tracking a previous version.
-  bool has_been_redefined() const { return _previous_versions != NULL; }
-  bool has_previous_version() const;
+  void add_previous_version(instanceKlassHandle ikh, int emcp_method_count);
+
+  InstanceKlass* previous_versions() const { return _previous_versions; }
+
+  bool has_been_redefined() const {
+    return (_misc_flags & _misc_has_been_redefined) != 0;
+  }
+  void set_has_been_redefined() {
+    _misc_flags |= _misc_has_been_redefined;
+  }
+
   void init_previous_versions() {
     _previous_versions = NULL;
   }
-  GrowableArray<PreviousVersionNode *>* previous_versions() const {
-    return _previous_versions;
-  }
 
   static void purge_previous_versions(InstanceKlass* ik);
 
@@ -1042,6 +1042,10 @@
 
   // Free CHeap allocated fields.
   void release_C_heap_structures();
+
+  // RedefineClasses support
+  void link_previous_versions(InstanceKlass* pv) { _previous_versions = pv; }
+  void mark_newly_obsolete_methods(Array<Method*>* old_methods, int emcp_method_count);
 public:
   // CDS support - remove and restore oops from metadata. Oops are not shared.
   virtual void remove_unshareable_info();
@@ -1141,62 +1145,6 @@
 };
 
 
-// If breakpoints are more numerous than just JVMTI breakpoints,
-// consider compressing this data structure.
-// It is currently a simple linked list defined in method.hpp.
-
-class BreakpointInfo;
-
-
-// A collection point for interesting information about the previous
-// version(s) of an InstanceKlass.  A GrowableArray of PreviousVersionNodes
-// is attached to the InstanceKlass as needed. See PreviousVersionWalker below.
-class PreviousVersionNode : public CHeapObj<mtClass> {
- private:
-  ConstantPool*    _prev_constant_pool;
-
-  // If the previous version of the InstanceKlass doesn't have any
-  // EMCP methods, then _prev_EMCP_methods will be NULL. If all the
-  // EMCP methods have been collected, then _prev_EMCP_methods can
-  // have a length of zero.
-  GrowableArray<Method*>* _prev_EMCP_methods;
-
-public:
-  PreviousVersionNode(ConstantPool* prev_constant_pool,
-                      GrowableArray<Method*>* prev_EMCP_methods);
-  ~PreviousVersionNode();
-  ConstantPool* prev_constant_pool() const {
-    return _prev_constant_pool;
-  }
-  GrowableArray<Method*>* prev_EMCP_methods() const {
-    return _prev_EMCP_methods;
-  }
-};
-
-
-// Helper object for walking previous versions.
-class PreviousVersionWalker : public StackObj {
- private:
-  Thread*                               _thread;
-  GrowableArray<PreviousVersionNode *>* _previous_versions;
-  int                                   _current_index;
-
-  // A pointer to the current node object so we can handle the deletes.
-  PreviousVersionNode*                  _current_p;
-
-  // The constant pool handle keeps all the methods in this class from being
-  // deallocated from the metaspace during class unloading.
-  constantPoolHandle                    _current_constant_pool_handle;
-
- public:
-  PreviousVersionWalker(Thread* thread, InstanceKlass *ik);
-
-  // Return the interesting information for the next previous version
-  // of the klass. Returns NULL if there are no more previous versions.
-  PreviousVersionNode* next_previous_version();
-};
-
-
 //
 // nmethodBucket is used to record dependent nmethods for
 // deoptimization.  nmethod dependencies are actually <klass, method>
--- a/hotspot/src/share/vm/oops/method.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/oops/method.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -1635,34 +1635,34 @@
 }
 
 int Method::highest_comp_level() const {
-  const MethodData* mdo = method_data();
-  if (mdo != NULL) {
-    return mdo->highest_comp_level();
+  const MethodCounters* mcs = method_counters();
+  if (mcs != NULL) {
+    return mcs->highest_comp_level();
   } else {
     return CompLevel_none;
   }
 }
 
 int Method::highest_osr_comp_level() const {
-  const MethodData* mdo = method_data();
-  if (mdo != NULL) {
-    return mdo->highest_osr_comp_level();
+  const MethodCounters* mcs = method_counters();
+  if (mcs != NULL) {
+    return mcs->highest_osr_comp_level();
   } else {
     return CompLevel_none;
   }
 }
 
 void Method::set_highest_comp_level(int level) {
-  MethodData* mdo = method_data();
-  if (mdo != NULL) {
-    mdo->set_highest_comp_level(level);
+  MethodCounters* mcs = method_counters();
+  if (mcs != NULL) {
+    mcs->set_highest_comp_level(level);
   }
 }
 
 void Method::set_highest_osr_comp_level(int level) {
-  MethodData* mdo = method_data();
-  if (mdo != NULL) {
-    mdo->set_highest_osr_comp_level(level);
+  MethodCounters* mcs = method_counters();
+  if (mcs != NULL) {
+    mcs->set_highest_osr_comp_level(level);
   }
 }
 
--- a/hotspot/src/share/vm/oops/method.hpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/oops/method.hpp	Wed Jul 05 20:01:50 2017 +0200
@@ -80,7 +80,8 @@
     _caller_sensitive = 1 << 1,
     _force_inline     = 1 << 2,
     _dont_inline      = 1 << 3,
-    _hidden           = 1 << 4
+    _hidden           = 1 << 4,
+    _running_emcp     = 1 << 5
   };
   u1 _flags;
 
@@ -688,6 +689,21 @@
   void set_is_obsolete()                            { _access_flags.set_is_obsolete(); }
   bool is_deleted() const                           { return access_flags().is_deleted(); }
   void set_is_deleted()                             { _access_flags.set_is_deleted(); }
+
+  bool is_running_emcp() const {
+    // EMCP methods are old but not obsolete or deleted. Equivalent
+    // Modulo Constant Pool means the method is equivalent except
+    // the constant pool and instructions that access the constant
+    // pool might be different.
+    // If a breakpoint is set in a redefined method, its EMCP methods that are
+    // still running must have a breakpoint also.
+    return (_flags & _running_emcp) != 0;
+  }
+
+  void set_running_emcp(bool x) {
+    _flags = x ? (_flags | _running_emcp) : (_flags & ~_running_emcp);
+  }
+
   bool on_stack() const                             { return access_flags().on_stack(); }
   void set_on_stack(const bool value);
 
--- a/hotspot/src/share/vm/oops/methodCounters.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/oops/methodCounters.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -35,4 +35,40 @@
   set_interpreter_throwout_count(0);
   set_interpreter_invocation_count(0);
   set_nmethod_age(INT_MAX);
+#ifdef TIERED
+  set_prev_time(0);
+  set_rate(0);
+  set_highest_comp_level(0);
+  set_highest_osr_comp_level(0);
+#endif
 }
+
+
+int MethodCounters::highest_comp_level() const {
+#ifdef TIERED
+  return _highest_comp_level;
+#else
+  return CompLevel_none;
+#endif
+}
+
+void MethodCounters::set_highest_comp_level(int level) {
+#ifdef TIERED
+  _highest_comp_level = level;
+#endif
+}
+
+int MethodCounters::highest_osr_comp_level() const {
+#ifdef TIERED
+  return _highest_osr_comp_level;
+#else
+  return CompLevel_none;
+#endif
+}
+
+void MethodCounters::set_highest_osr_comp_level(int level) {
+#ifdef TIERED
+  _highest_osr_comp_level = level;
+#endif
+}
+
--- a/hotspot/src/share/vm/oops/methodCounters.hpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/oops/methodCounters.hpp	Wed Jul 05 20:01:50 2017 +0200
@@ -49,6 +49,8 @@
 #ifdef TIERED
   float             _rate;                        // Events (invocation and backedge counter increments) per millisecond
   jlong             _prev_time;                   // Previous time the rate was acquired
+  u1                _highest_comp_level;          // Highest compile level this method has ever seen.
+  u1                _highest_osr_comp_level;      // Same for OSR level
 #endif
 
   MethodCounters() : _interpreter_invocation_count(0),
@@ -57,7 +59,9 @@
                      _nmethod_age(INT_MAX)
 #ifdef TIERED
                    , _rate(0),
-                     _prev_time(0)
+                     _prev_time(0),
+                     _highest_comp_level(0),
+                     _highest_osr_comp_level(0)
 #endif
   {
     invocation_counter()->init();
@@ -114,6 +118,11 @@
   void set_rate(float rate)                      { _rate = rate; }
 #endif
 
+  int highest_comp_level() const;
+  void set_highest_comp_level(int level);
+  int highest_osr_comp_level() const;
+  void set_highest_osr_comp_level(int level);
+
   // invocation counter
   InvocationCounter* invocation_counter() { return &_invocation_counter; }
   InvocationCounter* backedge_counter()   { return &_backedge_counter; }
--- a/hotspot/src/share/vm/oops/methodData.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/oops/methodData.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -1134,8 +1134,6 @@
   _tenure_traps = 0;
   _num_loops = 0;
   _num_blocks = 0;
-  _highest_comp_level = 0;
-  _highest_osr_comp_level = 0;
   _would_profile = true;
 
 #if INCLUDE_RTM_OPT
--- a/hotspot/src/share/vm/oops/methodData.hpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/oops/methodData.hpp	Wed Jul 05 20:01:50 2017 +0200
@@ -2095,10 +2095,6 @@
   // time with C1. It is used to determine if method is trivial.
   short             _num_loops;
   short             _num_blocks;
-  // Highest compile level this method has ever seen.
-  u1                _highest_comp_level;
-  // Same for OSR level
-  u1                _highest_osr_comp_level;
   // Does this method contain anything worth profiling?
   bool              _would_profile;
 
@@ -2277,11 +2273,6 @@
   void set_would_profile(bool p)              { _would_profile = p;    }
   bool would_profile() const                  { return _would_profile; }
 
-  int highest_comp_level() const              { return _highest_comp_level;      }
-  void set_highest_comp_level(int level)      { _highest_comp_level = level;     }
-  int highest_osr_comp_level() const          { return _highest_osr_comp_level;  }
-  void set_highest_osr_comp_level(int level)  { _highest_osr_comp_level = level; }
-
   int num_loops() const                       { return _num_loops;  }
   void set_num_loops(int n)                   { _num_loops = n;     }
   int num_blocks() const                      { return _num_blocks; }
--- a/hotspot/src/share/vm/opto/compile.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/opto/compile.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -430,7 +430,7 @@
 // removes the need to bang the stack in the deoptimization blob which
 // in turn simplifies stack overflow handling.
 int Compile::bang_size_in_bytes() const {
-  return MAX2(_interpreter_frame_size, frame_size_in_bytes());
+  return MAX2(frame_size_in_bytes() + os::extra_bang_size_in_bytes(), _interpreter_frame_size);
 }
 
 // ============================================================================
--- a/hotspot/src/share/vm/opto/library_call.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/opto/library_call.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -4968,7 +4968,8 @@
 
     // Allocate the result array
     Node* zlen = _gvn.transform(new AddINode(xlen, ylen));
-    Node* klass_node = makecon(TypeKlassPtr::make(ciTypeArrayKlass::make(T_INT)));
+    ciKlass* klass = ciTypeArrayKlass::make(T_INT);
+    Node* klass_node = makecon(TypeKlassPtr::make(klass));
 
     IdealKit ideal(this);
 
@@ -5002,7 +5003,8 @@
 
      sync_kit(ideal);
      z = __ value(z_alloc);
-     _gvn.set_type(z, TypeAryPtr::INTS);
+     // Can't use TypeAryPtr::INTS which uses Bottom offset.
+     _gvn.set_type(z, TypeOopPtr::make_from_klass(klass));
      // Final sync IdealKit and GraphKit.
      final_sync(ideal);
 #undef __
--- a/hotspot/src/share/vm/prims/jvmtiImpl.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/prims/jvmtiImpl.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -282,39 +282,22 @@
 void JvmtiBreakpoint::each_method_version_do(method_action meth_act) {
   ((Method*)_method->*meth_act)(_bci);
 
-  // add/remove breakpoint to/from versions of the method that
-  // are EMCP. Directly or transitively obsolete methods are
-  // not saved in the PreviousVersionNodes.
+  // add/remove breakpoint to/from versions of the method that are EMCP.
   Thread *thread = Thread::current();
   instanceKlassHandle ikh = instanceKlassHandle(thread, _method->method_holder());
   Symbol* m_name = _method->name();
   Symbol* m_signature = _method->signature();
 
   // search previous versions if they exist
-  PreviousVersionWalker pvw(thread, (InstanceKlass *)ikh());
-  for (PreviousVersionNode * pv_node = pvw.next_previous_version();
-       pv_node != NULL; pv_node = pvw.next_previous_version()) {
-    GrowableArray<Method*>* methods = pv_node->prev_EMCP_methods();
-
-    if (methods == NULL) {
-      // We have run into a PreviousVersion generation where
-      // all methods were made obsolete during that generation's
-      // RedefineClasses() operation. At the time of that
-      // operation, all EMCP methods were flushed so we don't
-      // have to go back any further.
-      //
-      // A NULL methods array is different than an empty methods
-      // array. We cannot infer any optimizations about older
-      // generations from an empty methods array for the current
-      // generation.
-      break;
-    }
+  for (InstanceKlass* pv_node = ikh->previous_versions();
+       pv_node != NULL;
+       pv_node = pv_node->previous_versions()) {
+    Array<Method*>* methods = pv_node->methods();
 
     for (int i = methods->length() - 1; i >= 0; i--) {
       Method* method = methods->at(i);
-      // obsolete methods that are running are not deleted from
-      // previous version array, but they are skipped here.
-      if (!method->is_obsolete() &&
+      // Only set breakpoints in running EMCP methods.
+      if (method->is_running_emcp() &&
           method->name() == m_name &&
           method->signature() == m_signature) {
         RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)",
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -135,7 +135,7 @@
 
   // Mark methods seen on stack and everywhere else so old methods are not
   // cleaned up if they're on the stack.
-  MetadataOnStackMark md_on_stack;
+  MetadataOnStackMark md_on_stack(true);
   HandleMark hm(thread);   // make sure any handles created are deleted
                            // before the stack walk again.
 
@@ -2826,11 +2826,10 @@
     }
 
     // the previous versions' constant pool caches may need adjustment
-    PreviousVersionWalker pvw(_thread, ik);
-    for (PreviousVersionNode * pv_node = pvw.next_previous_version();
-         pv_node != NULL; pv_node = pvw.next_previous_version()) {
-      other_cp = pv_node->prev_constant_pool();
-      cp_cache = other_cp->cache();
+    for (InstanceKlass* pv_node = ik->previous_versions();
+         pv_node != NULL;
+         pv_node = pv_node->previous_versions()) {
+      cp_cache = pv_node->constants()->cache();
       if (cp_cache != NULL) {
         cp_cache->adjust_method_entries(_matching_old_methods,
                                         _matching_new_methods,
@@ -2855,9 +2854,8 @@
   }
 }
 
-void VM_RedefineClasses::check_methods_and_mark_as_obsolete(
-       BitMap *emcp_methods, int * emcp_method_count_p) {
-  *emcp_method_count_p = 0;
+int VM_RedefineClasses::check_methods_and_mark_as_obsolete() {
+  int emcp_method_count = 0;
   int obsolete_count = 0;
   int old_index = 0;
   for (int j = 0; j < _matching_methods_length; ++j, ++old_index) {
@@ -2931,9 +2929,9 @@
       // that we get from effectively overwriting the old methods
       // when the new methods are attached to the_class.
 
-      // track which methods are EMCP for add_previous_version() call
-      emcp_methods->set_bit(old_index);
-      (*emcp_method_count_p)++;
+      // Count number of methods that are EMCP.  The method will be marked
+      // old but not obsolete if it is EMCP.
+      emcp_method_count++;
 
       // An EMCP method is _not_ obsolete. An obsolete method has a
       // different jmethodID than the current method. An EMCP method
@@ -2982,10 +2980,11 @@
                           old_method->name()->as_C_string(),
                           old_method->signature()->as_C_string()));
   }
-  assert((*emcp_method_count_p + obsolete_count) == _old_methods->length(),
+  assert((emcp_method_count + obsolete_count) == _old_methods->length(),
     "sanity check");
-  RC_TRACE(0x00000100, ("EMCP_cnt=%d, obsolete_cnt=%d", *emcp_method_count_p,
+  RC_TRACE(0x00000100, ("EMCP_cnt=%d, obsolete_cnt=%d", emcp_method_count,
     obsolete_count));
+  return emcp_method_count;
 }
 
 // This internal class transfers the native function registration from old methods
@@ -3379,11 +3378,8 @@
   old_constants->set_pool_holder(scratch_class());
 #endif
 
-  // track which methods are EMCP for add_previous_version() call below
-  BitMap emcp_methods(_old_methods->length());
-  int emcp_method_count = 0;
-  emcp_methods.clear();  // clears 0..(length() - 1)
-  check_methods_and_mark_as_obsolete(&emcp_methods, &emcp_method_count);
+  // track number of methods that are EMCP for add_previous_version() call below
+  int emcp_method_count = check_methods_and_mark_as_obsolete();
   transfer_old_native_function_registrations(the_class);
 
   // The class file bytes from before any retransformable agents mucked
@@ -3471,9 +3467,10 @@
     scratch_class->enclosing_method_method_index());
   scratch_class->set_enclosing_method_indices(old_class_idx, old_method_idx);
 
+  the_class->set_has_been_redefined();
+
   // keep track of previous versions of this class
-  the_class->add_previous_version(scratch_class, &emcp_methods,
-    emcp_method_count);
+  the_class->add_previous_version(scratch_class, emcp_method_count);
 
   RC_TIMER_STOP(_timer_rsc_phase1);
   RC_TIMER_START(_timer_rsc_phase2);
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp	Wed Jul 05 20:01:50 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -403,14 +403,9 @@
   // Change jmethodIDs to point to the new methods
   void update_jmethod_ids();
 
-  // In addition to marking methods as obsolete, this routine
-  // records which methods are EMCP (Equivalent Module Constant
-  // Pool) in the emcp_methods BitMap and returns the number of
-  // EMCP methods via emcp_method_count_p. This information is
-  // used when information about the previous version of the_class
-  // is squirreled away.
-  void check_methods_and_mark_as_obsolete(BitMap *emcp_methods,
-         int * emcp_method_count_p);
+  // In addition to marking methods as old and/or obsolete, this routine
+  // counts the number of methods that are EMCP (Equivalent Module Constant Pool).
+  int check_methods_and_mark_as_obsolete();
   void transfer_old_native_function_registrations(instanceKlassHandle the_class);
 
   // Install the redefinition of a class
--- a/hotspot/src/share/vm/runtime/arguments.hpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/runtime/arguments.hpp	Wed Jul 05 20:01:50 2017 +0200
@@ -590,7 +590,9 @@
   static void  fix_appclasspath();
 
   // Operation modi
-  static Mode mode()                        { return _mode; }
+  static Mode mode()                { return _mode; }
+  static bool is_interpreter_only() { return mode() == _int; }
+
 
   // Utility: copies src into buf, replacing "%%" with "%" and "%p" with pid.
   static bool copy_expand_pid(const char* src, size_t srclen, char* buf, size_t buflen);
--- a/hotspot/src/share/vm/runtime/globals.hpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Wed Jul 05 20:01:50 2017 +0200
@@ -2473,7 +2473,7 @@
   develop(bool, CIPrintCompilerName, false,                                 \
           "when CIPrint is active, print the name of the active compiler")  \
                                                                             \
-  develop(bool, CIPrintCompileQueue, false,                                 \
+  diagnostic(bool, CIPrintCompileQueue, false,                              \
           "display the contents of the compile queue whenever a "           \
           "compilation is enqueued")                                        \
                                                                             \
--- a/hotspot/src/share/vm/runtime/os.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/runtime/os.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -53,6 +53,7 @@
 #include "runtime/vm_version.hpp"
 #include "services/attachListener.hpp"
 #include "services/nmtCommon.hpp"
+#include "services/mallocTracker.hpp"
 #include "services/memTracker.hpp"
 #include "services/threadService.hpp"
 #include "utilities/defaultStream.hpp"
@@ -570,6 +571,17 @@
   NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1));
   NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size));
 
+#if INCLUDE_NMT
+  // NMT can not track malloc allocation size > MAX_MALLOC_SIZE, which is
+  // (1GB - 1) on 32-bit system. It is not an issue on 64-bit system, where
+  // MAX_MALLOC_SIZE = ((1 << 62) - 1).
+  // VM code does not have such large malloc allocation. However, it can come
+  // Unsafe call.
+  if (MemTracker::tracking_level() >= NMT_summary && size > MAX_MALLOC_SIZE) {
+    return NULL;
+  }
+#endif
+
 #ifdef ASSERT
   // checking for the WatcherThread and crash_protection first
   // since os::malloc can be called when the libjvm.{dll,so} is
@@ -640,6 +652,13 @@
 }
 
 void* os::realloc(void *memblock, size_t size, MEMFLAGS memflags, const NativeCallStack& stack) {
+#if INCLUDE_NMT
+  // See comments in os::malloc() above
+  if (MemTracker::tracking_level() >= NMT_summary && size > MAX_MALLOC_SIZE) {
+    return NULL;
+  }
+#endif
+
 #ifndef ASSERT
   NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1));
   NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size));
--- a/hotspot/src/share/vm/runtime/os.hpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/runtime/os.hpp	Wed Jul 05 20:01:50 2017 +0200
@@ -557,6 +557,16 @@
   // Unload library
   static void  dll_unload(void *lib);
 
+  // Callback for loaded module information
+  // Input parameters:
+  //    char*     module_file_name,
+  //    address   module_base_addr,
+  //    address   module_top_addr,
+  //    void*     param
+  typedef int (*LoadedModulesCallbackFunc)(const char *, address, address, void *);
+
+  static int get_loaded_modules_info(LoadedModulesCallbackFunc callback, void *param);
+
   // Return the handle of this process
   static void* get_default_process_handle();
 
@@ -761,6 +771,9 @@
   // Hook for os specific jvm options that we don't want to abort on seeing
   static bool obsolete_option(const JavaVMOption *option);
 
+  // Amount beyond the callee frame size that we bang the stack.
+  static int extra_bang_size_in_bytes();
+
   // Extensions
 #include "runtime/os_ext.hpp"
 
--- a/hotspot/src/share/vm/runtime/sweeper.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/runtime/sweeper.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -618,7 +618,7 @@
         if (mc == NULL) {
           // Sometimes we can get here without MethodCounters. For example if we run with -Xcomp.
           // Try to allocate them.
-          mc = Method::build_method_counters(nm->method(), Thread::current());
+          mc = nm->method()->get_method_counters(Thread::current());
         }
         if (mc != NULL) {
           // Snapshot the value as it's changed concurrently
--- a/hotspot/src/share/vm/runtime/vm_operations.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/runtime/vm_operations.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -470,3 +470,15 @@
     ShouldNotReachHere();
   }
 }
+
+void VM_PrintCompileQueue::doit() {
+  CompileBroker::print_compile_queues(_out);
+}
+
+void VM_PrintCodeList::doit() {
+  CodeCache::print_codelist(_out);
+}
+
+void VM_PrintCodeCache::doit() {
+  CodeCache::print_layout(_out);
+}
--- a/hotspot/src/share/vm/runtime/vm_operations.hpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/runtime/vm_operations.hpp	Wed Jul 05 20:01:50 2017 +0200
@@ -99,6 +99,9 @@
   template(RotateGCLog)                           \
   template(WhiteBoxOperation)                     \
   template(ClassLoaderStatsOperation)             \
+  template(PrintCompileQueue)                     \
+  template(PrintCodeList)                         \
+  template(PrintCodeCache)                        \
 
 class VM_Operation: public CHeapObj<mtInternal> {
  public:
@@ -413,4 +416,35 @@
   void doit() { gclog_or_tty->rotate_log(true, _out); }
 };
 
+class VM_PrintCompileQueue: public VM_Operation {
+ private:
+  outputStream* _out;
+
+ public:
+  VM_PrintCompileQueue(outputStream* st) : _out(st) {}
+  VMOp_Type type() const { return VMOp_PrintCompileQueue; }
+  void doit();
+};
+
+class VM_PrintCodeList: public VM_Operation {
+ private:
+  outputStream* _out;
+
+ public:
+  VM_PrintCodeList(outputStream* st) : _out(st) {}
+  VMOp_Type type() const { return VMOp_PrintCodeList; }
+  void doit();
+};
+
+class VM_PrintCodeCache: public VM_Operation {
+ private:
+  outputStream* _out;
+
+ public:
+  VM_PrintCodeCache(outputStream* st) : _out(st) {}
+  VMOp_Type type() const { return VMOp_PrintCodeCache; }
+  void doit();
+};
+
+
 #endif // SHARE_VM_RUNTIME_VM_OPERATIONS_HPP
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp	Wed Jul 05 20:01:50 2017 +0200
@@ -60,6 +60,9 @@
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RotateGCLogDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassLoaderStatsDCmd>(full_export, true, false));
+  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CompileQueueDCmd>(full_export, true, false));
+  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CodeListDCmd>(full_export, true, false));
+  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CodeCacheDCmd>(full_export, true, false));
 
   // Enhanced JMX Agent Support
   // These commands won't be exported via the DiagnosticCommandMBean until an
@@ -674,3 +677,18 @@
   }
 }
 
+void CompileQueueDCmd::execute(DCmdSource source, TRAPS) {
+  VM_PrintCompileQueue printCompileQueueOp(output());
+  VMThread::execute(&printCompileQueueOp);
+}
+
+void CodeListDCmd::execute(DCmdSource source, TRAPS) {
+  VM_PrintCodeList printCodeListOp(output());
+  VMThread::execute(&printCodeListOp);
+}
+
+void CodeCacheDCmd::execute(DCmdSource source, TRAPS) {
+  VM_PrintCodeCache printCodeCacheOp(output());
+  VMThread::execute(&printCodeCacheOp);
+}
+
--- a/hotspot/src/share/vm/services/diagnosticCommand.hpp	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/src/share/vm/services/diagnosticCommand.hpp	Wed Jul 05 20:01:50 2017 +0200
@@ -399,4 +399,68 @@
   }
 };
 
+class CompileQueueDCmd : public DCmd {
+public:
+  CompileQueueDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
+  static const char* name() {
+    return "Compiler.queue";
+  }
+  static const char* description() {
+    return "Print methods queued for compilation.";
+  }
+  static const char* impact() {
+    return "Low";
+  }
+  static const JavaPermission permission() {
+    JavaPermission p = {"java.lang.management.ManagementPermission",
+                        "monitor", NULL};
+    return p;
+  }
+  static int num_arguments() { return 0; }
+  virtual void execute(DCmdSource source, TRAPS);
+};
+
+class CodeListDCmd : public DCmd {
+public:
+  CodeListDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
+  static const char* name() {
+    return "Compiler.codelist";
+  }
+  static const char* description() {
+    return "Print all compiled methods in code cache.";
+  }
+  static const char* impact() {
+    return "Medium";
+  }
+  static const JavaPermission permission() {
+    JavaPermission p = {"java.lang.management.ManagementPermission",
+                        "monitor", NULL};
+    return p;
+  }
+  static int num_arguments() { return 0; }
+  virtual void execute(DCmdSource source, TRAPS);
+};
+
+
+class CodeCacheDCmd : public DCmd {
+public:
+  CodeCacheDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
+  static const char* name() {
+    return "Compiler.codecache";
+  }
+  static const char* description() {
+    return "Print code cache layout and bounds.";
+  }
+  static const char* impact() {
+    return "Low";
+  }
+  static const JavaPermission permission() {
+    JavaPermission p = {"java.lang.management.ManagementPermission",
+                        "monitor", NULL};
+    return p;
+  }
+  static int num_arguments() { return 0; }
+  virtual void execute(DCmdSource source, TRAPS);
+};
+
 #endif // SHARE_VM_SERVICES_DIAGNOSTICCOMMAND_HPP
--- a/hotspot/test/TEST.groups	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/test/TEST.groups	Wed Jul 05 20:01:50 2017 +0200
@@ -80,6 +80,7 @@
   runtime/NMT/MallocSiteHashOverflow.java \
   runtime/NMT/MallocStressTest.java \
   runtime/NMT/MallocTestType.java \
+  runtime/NMT/MallocTrackingVerify.java \
   runtime/NMT/ReleaseCommittedMemory.java \
   runtime/NMT/ReleaseNoCommit.java \
   runtime/NMT/ShutdownTwice.java \
@@ -87,6 +88,7 @@
   runtime/NMT/SummarySanityCheck.java \
   runtime/NMT/ThreadedMallocTestType.java \
   runtime/NMT/ThreadedVirtualAllocTestType.java \
+  runtime/NMT/UnsafeMallocLimit.java \
   runtime/NMT/VirtualAllocCommitUncommitRecommit.java \
   runtime/NMT/VirtualAllocTestType.java \
   runtime/RedefineObject/TestRedefineObject.java \
--- a/hotspot/test/gc/arguments/TestParallelHeapSizeFlags.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/test/gc/arguments/TestParallelHeapSizeFlags.java	Wed Jul 05 20:01:50 2017 +0200
@@ -22,7 +22,7 @@
 */
 
 /*
- * @ignore 8027915
+ * @ignore 8049864
  * @test TestParallelHeapSizeFlags
  * @key gc
  * @bug 8006088
--- a/hotspot/test/gc/arguments/TestUseCompressedOopsErgo.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/test/gc/arguments/TestUseCompressedOopsErgo.java	Wed Jul 05 20:01:50 2017 +0200
@@ -22,7 +22,6 @@
 */
 
 /*
- * @ignore 8025645
  * @test TestUseCompressedOopsErgo
  * @key gc
  * @bug 8010722
--- a/hotspot/test/gc/parallelScavenge/TestDynShrinkHeap.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/test/gc/parallelScavenge/TestDynShrinkHeap.java	Wed Jul 05 20:01:50 2017 +0200
@@ -22,7 +22,7 @@
  */
 
 /**
- * @ignore 8042051
+ * @ignore 8019361
  * @test TestDynShrinkHeap
  * @bug 8016479
  * @summary Verify that the heap shrinks after full GC according to the current values of the Min/MaxHeapFreeRatio flags
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/NMT/MallocTrackingVerify.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8054836
+ * @summary Test to verify correctness of malloc tracking
+ * @key nmt jcmd
+ * @library /testlibrary /testlibrary/whitebox
+ * @build MallocTrackingVerify
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail MallocTrackingVerify
+ *
+ */
+
+import java.util.ArrayList;
+import java.util.Random;
+
+import com.oracle.java.testlibrary.*;
+
+import sun.hotspot.WhiteBox;
+
+public class MallocTrackingVerify {
+    private static int MAX_ALLOC = 4 * 1024;
+
+    static ArrayList<MallocMemory> mallocd_memory = new ArrayList<MallocMemory>();
+    static long mallocd_total = 0;
+    public static WhiteBox wb = WhiteBox.getWhiteBox();
+
+    public static void main(String args[]) throws Exception {
+        OutputAnalyzer output;
+
+        // Grab my own PID
+        String pid = Integer.toString(ProcessTools.getProcessId());
+        ProcessBuilder pb = new ProcessBuilder();
+
+        Random random = new Random();
+        // Allocate small amounts of memory with random pseudo call stack
+        while (mallocd_total < MAX_ALLOC) {
+            int size = random.nextInt(31) + 1;
+            long addr = wb.NMTMallocWithPseudoStack(size, random.nextInt());
+            if (addr != 0) {
+                MallocMemory mem = new MallocMemory(addr, size);
+                mallocd_memory.add(mem);
+                mallocd_total += size;
+            } else {
+                System.out.println("Out of malloc memory");
+                break;
+            }
+        }
+
+        pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary" });
+        output = new OutputAnalyzer(pb.start());
+        output.shouldContain("Test (reserved=4KB, committed=4KB)");
+
+        // Free
+        for (MallocMemory mem : mallocd_memory) {
+            wb.NMTFree(mem.addr());
+        }
+
+        // Run 'jcmd <pid> VM.native_memory summary', check for expected output
+        pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid,
+                "VM.native_memory", "summary" });
+        output = new OutputAnalyzer(pb.start());
+        output.shouldNotContain("Test (reserved=");
+    }
+
+    static class MallocMemory {
+        private long addr;
+        private int size;
+
+        MallocMemory(long addr, int size) {
+            this.addr = addr;
+            this.size = size;
+        }
+
+        long addr() {
+            return this.addr;
+        }
+
+        int size() {
+            return this.size;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/NMT/UnsafeMallocLimit.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8055289
+ * @library /testlibrary
+ * @build UnsafeMallocLimit
+ * @run main/othervm -Xmx32m -XX:NativeMemoryTracking=summary UnsafeMallocLimit
+ */
+
+import com.oracle.java.testlibrary.*;
+import sun.misc.Unsafe;
+
+public class UnsafeMallocLimit {
+
+    public static void main(String args[]) throws Exception {
+        if (Platform.is32bit()) {
+            Unsafe unsafe = Utils.getUnsafe();
+            try {
+                unsafe.allocateMemory(1 << 30);
+                throw new RuntimeException("Did not get expected OOME");
+            } catch (OutOfMemoryError e) {
+                // Expected exception
+            }
+        } else {
+            System.out.println("Test only valid on 32-bit platforms");
+        }
+    }
+}
--- a/hotspot/test/runtime/RedefineFinalizer/RedefineFinalizer.java	Wed Jul 05 20:01:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 6904403
- * @summary Don't assert if we redefine finalize method
- * @library /testlibrary
- * @build RedefineClassHelper
- * @run main RedefineClassHelper
- * @run main/othervm -javaagent:redefineagent.jar RedefineFinalizer
- */
-
-/*
- * Regression test for hitting:
- *
- * assert(f == k->has_finalizer()) failed: inconsistent has_finalizer
- *
- * when redefining finalizer method
- */
-public class RedefineFinalizer {
-
-    public static String newB =
-                "class RedefineFinalizer$B {" +
-                "   protected void finalize() { " +
-                "       System.out.println(\"Finalizer called\");" +
-                "   }" +
-                "}";
-
-    public static void main(String[] args) throws Exception {
-        RedefineClassHelper.redefineClass(B.class, newB);
-
-        A a = new A();
-    }
-
-    static class A extends B {
-    }
-
-    static class B {
-        protected void finalize() {
-            // should be empty
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/RedefineTests/RedefineFinalizer.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6904403
+ * @summary Don't assert if we redefine finalize method
+ * @library /testlibrary
+ * @build RedefineClassHelper
+ * @run main RedefineClassHelper
+ * @run main/othervm -javaagent:redefineagent.jar RedefineFinalizer
+ */
+
+/*
+ * Regression test for hitting:
+ *
+ * assert(f == k->has_finalizer()) failed: inconsistent has_finalizer
+ *
+ * when redefining finalizer method
+ */
+public class RedefineFinalizer {
+
+    public static String newB =
+                "class RedefineFinalizer$B {" +
+                "   protected void finalize() { " +
+                "       System.out.println(\"Finalizer called\");" +
+                "   }" +
+                "}";
+
+    public static void main(String[] args) throws Exception {
+        RedefineClassHelper.redefineClass(B.class, newB);
+
+        A a = new A();
+    }
+
+    static class A extends B {
+    }
+
+    static class B {
+        protected void finalize() {
+            // should be empty
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/RedefineTests/RedefineRunningMethods.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8055008
+ * @summary Redefine EMCP and non-EMCP methods that are running in an infinite loop
+ * @library /testlibrary
+ * @build RedefineClassHelper
+ * @run main RedefineClassHelper
+ * @run main/othervm -javaagent:redefineagent.jar -XX:TraceRedefineClasses=0x600 RedefineRunningMethods
+ */
+public class RedefineRunningMethods {
+
+    public static String newB =
+                "class RedefineRunningMethods$B {" +
+                "   static int count1 = 0;" +
+                "   static int count2 = 0;" +
+                "   public static volatile boolean stop = false;" +
+                "  static void localSleep() { " +
+                "    try{ " +
+                "      Thread.currentThread().sleep(10);" +
+                "    } catch(InterruptedException ie) { " +
+                "    } " +
+                " } " +
+                "   public static void infinite() { " +
+                "       System.out.println(\"infinite called\");" +
+                "   }" +
+                "   public static void infinite_emcp() { " +
+                "       while (!stop) { count2++; localSleep(); }" +
+                "   }" +
+                "}";
+
+    public static String evenNewerB =
+                "class RedefineRunningMethods$B {" +
+                "   static int count1 = 0;" +
+                "   static int count2 = 0;" +
+                "   public static volatile boolean stop = false;" +
+                "  static void localSleep() { " +
+                "    try{ " +
+                "      Thread.currentThread().sleep(1);" +
+                "    } catch(InterruptedException ie) { " +
+                "    } " +
+                " } " +
+                "   public static void infinite() { }" +
+                "   public static void infinite_emcp() { " +
+                "       System.out.println(\"infinite_emcp now obsolete called\");" +
+                "   }" +
+                "}";
+
+    static class B {
+        static int count1 = 0;
+        static int count2 = 0;
+        public static volatile boolean stop = false;
+        static void localSleep() {
+          try{
+            Thread.currentThread().sleep(10);//sleep for 10 ms
+          } catch(InterruptedException ie) {
+          }
+        }
+
+        public static void infinite() {
+            while (!stop) { count1++; localSleep(); }
+        }
+        public static void infinite_emcp() {
+            while (!stop) { count2++; localSleep(); }
+        }
+    }
+
+
+    public static void main(String[] args) throws Exception {
+
+        new Thread() {
+            public void run() {
+                B.infinite();
+            }
+        }.start();
+
+        new Thread() {
+            public void run() {
+                B.infinite_emcp();
+            }
+        }.start();
+
+        RedefineClassHelper.redefineClass(B.class, newB);
+
+        System.gc();
+
+        B.infinite();
+
+        // Start a thread with the second version of infinite_emcp running
+        new Thread() {
+            public void run() {
+                B.infinite_emcp();
+            }
+        }.start();
+
+        for (int i = 0; i < 20 ; i++) {
+            String s = new String("some garbage");
+            System.gc();
+        }
+
+        RedefineClassHelper.redefineClass(B.class, evenNewerB);
+        System.gc();
+
+        for (int i = 0; i < 20 ; i++) {
+            B.infinite();
+            String s = new String("some garbage");
+            System.gc();
+        }
+
+        B.infinite_emcp();
+
+        // purge should clean everything up.
+        B.stop = true;
+
+        for (int i = 0; i < 20 ; i++) {
+            B.infinite();
+            String s = new String("some garbage");
+            System.gc();
+        }
+    }
+}
--- a/hotspot/test/runtime/SharedArchiveFile/ArchiveDoesNotExist.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/hotspot/test/runtime/SharedArchiveFile/ArchiveDoesNotExist.java	Wed Jul 05 20:01:50 2017 +0200
@@ -61,7 +61,7 @@
            "-version");
 
         output = new OutputAnalyzer(pb.start());
-        output.shouldContain("java version");
+        output.shouldMatch("(java|openjdk) version");
         output.shouldNotContain("sharing");
         output.shouldHaveExitValue(0);
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/CodeCacheTest.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test CodeCacheTest
+ * @bug 8054889
+ * @build DcmdUtil CodeCacheTest
+ * @run main CodeCacheTest
+ * @summary Test of diagnostic command Compiler.codecache
+ */
+
+import java.io.BufferedReader;
+import java.io.StringReader;
+import java.lang.reflect.Method;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class CodeCacheTest {
+
+    /**
+     * This test calls Jcmd (diagnostic command tool) Compiler.codecache and then parses the output,
+     * making sure that all number look ok
+     *
+     *
+     * Expected output:
+     *
+     * CodeCache: size=245760Kb used=4680Kb max_used=4680Kb free=241079Kb
+     * bounds [0x00007f5bd9000000, 0x00007f5bd94a0000, 0x00007f5be8000000]
+     * total_blobs=575 nmethods=69 adapters=423
+     * compilation: enabled
+     */
+
+    static Pattern line1 = Pattern.compile("CodeCache: size=(\\p{Digit}*)Kb used=(\\p{Digit}*)Kb max_used=(\\p{Digit}*)Kb free=(\\p{Digit}*)Kb");
+    static Pattern line2 = Pattern.compile(" bounds \\[0x(\\p{XDigit}*), 0x(\\p{XDigit}*), 0x(\\p{XDigit}*)\\]");
+    static Pattern line3 = Pattern.compile(" total_blobs=(\\p{Digit}*) nmethods=(\\p{Digit}*) adapters=(\\p{Digit}*)");
+    static Pattern line4 = Pattern.compile(" compilation: (\\w*)");
+
+    public static void main(String arg[]) throws Exception {
+
+        // Get output from dcmd (diagnostic command)
+        String result = DcmdUtil.executeDcmd("Compiler.codecache");
+        BufferedReader r = new BufferedReader(new StringReader(result));
+
+        // Validate first line
+        String line;
+        line = r.readLine();
+        Matcher m = line1.matcher(line);
+        if (m.matches()) {
+            for(int i = 1; i <= 4; i++) {
+                int val = Integer.parseInt(m.group(i));
+                if (val < 0) {
+                    throw new Exception("Failed parsing dcmd codecache output");
+                }
+            }
+        } else {
+            throw new Exception("Regexp 1 failed");
+        }
+
+        // Validate second line
+        line = r.readLine();
+        m = line2.matcher(line);
+        if (m.matches()) {
+            long start = Long.parseLong(m.group(1), 16);
+            if (start < 0) {
+                throw new Exception("Failed parsing dcmd codecache output");
+            }
+            long mark = Long.parseLong(m.group(2), 16);
+            if (mark < 0) {
+                throw new Exception("Failed parsing dcmd codecache output");
+            }
+            long top = Long.parseLong(m.group(3), 16);
+            if (top < 0) {
+                throw new Exception("Failed parsing dcmd codecache output");
+            }
+            if (start > mark) {
+                throw new Exception("Failed parsing dcmd codecache output");
+            }
+            if (mark > top) {
+                throw new Exception("Failed parsing dcmd codecache output");
+            }
+        } else {
+            throw new Exception("Regexp 2 failed line: " + line);
+        }
+
+        // Validate third line
+        line = r.readLine();
+        m = line3.matcher(line);
+        if (m.matches()) {
+            int blobs = Integer.parseInt(m.group(1));
+            if (blobs <= 0) {
+                throw new Exception("Failed parsing dcmd codecache output");
+            }
+            int nmethods = Integer.parseInt(m.group(2));
+            if (nmethods <= 0) {
+                throw new Exception("Failed parsing dcmd codecache output");
+            }
+            int adapters = Integer.parseInt(m.group(3));
+            if (adapters <= 0) {
+                throw new Exception("Failed parsing dcmd codecache output");
+            }
+            if (blobs < (nmethods + adapters)) {
+                throw new Exception("Failed parsing dcmd codecache output");
+            }
+        } else {
+            throw new Exception("Regexp 3 failed");
+        }
+
+        // Validate fourth line
+        line = r.readLine();
+        m = line4.matcher(line);
+        if (m.matches()) {
+            if (!m.group(1).equals("enabled")) {
+                throw new Exception("Invalid message: '" + m.group(1) + "'");
+            }
+        } else {
+            throw new Exception("Regexp 4 failed");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/CodelistTest.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test CodelistTest
+ * @bug 8054889
+ * @build DcmdUtil MethodIdentifierParser CodelistTest
+ * @run main CodelistTest
+ * @summary Test of diagnostic command Compiler.codelist
+ */
+
+import java.io.BufferedReader;
+import java.io.StringReader;
+import java.lang.reflect.Method;
+
+public class CodelistTest {
+
+    /**
+     * This test calls Jcmd (diagnostic command tool) Compiler.codelist and then parses the output,
+     * making sure that the first methods in the list is valid by reflection.
+     *
+     * Output example:
+     *
+     * 6 0 java.lang.System.arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V [0x00007f7b49200910, 0x00007f7b49200aa0 - 0x00007f7b49200d30]
+     * 2 3 java.lang.String.indexOf(II)I [0x00007f7b49200d90, 0x00007f7b49200f60 - 0x00007f7b49201490]
+     * 7 3 java.lang.Math.min(II)I [0x00007f7b4922f010, 0x00007f7b4922f180 - 0x00007f7b4922f338]
+     * 8 3 java.lang.String.equals(Ljava/lang/Object;)Z [0x00007f7b4922fb10, 0x00007f7b4922fd40 - 0x00007f7b49230698]
+     * 9 3 java.lang.AbstractStringBuilder.ensureCapacityInternal(I)V [0x00007f7b49232010, 0x00007f7b492321a0 - 0x00007f7b49232510]
+     * 10 1 java.lang.Object.<init>()V [0x00007f7b49233e90, 0x00007f7b49233fe0 - 0x00007f7b49234118]
+     *
+     */
+
+    public static void main(String arg[]) throws Exception {
+        int ok   = 0;
+        int fail = 0;
+
+        // Get output from dcmd (diagnostic command)
+        String result = DcmdUtil.executeDcmd("Compiler.codelist");
+        BufferedReader r = new BufferedReader(new StringReader(result));
+
+        // Grab a method name from the output
+        String line;
+        int count = 0;
+
+        while((line = r.readLine()) != null) {
+            count++;
+
+            String[] parts = line.split(" ");
+            // int compileID = Integer.parseInt(parts[0]);
+            // int compileLevel = Integer.parseInt(parts[1]);
+            String methodPrintedInLogFormat = parts[2];
+
+            // skip inits and clinits - they can not be reflected
+            if (methodPrintedInLogFormat.contains("<init>")) {
+                continue;
+            }
+            if (methodPrintedInLogFormat.contains("<clinit>")) {
+                continue;
+            }
+
+            MethodIdentifierParser mf = new MethodIdentifierParser(methodPrintedInLogFormat);
+            Method m;
+            try {
+                m = mf.getMethod();
+            } catch (NoSuchMethodException e) {
+                m = null;
+            }
+            if (m == null) {
+                throw new Exception("Test failed");
+            }
+            if (count > 10) {
+                // Testing 10 entries is enough. Lets not waste time.
+                break;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/CompilerQueueTest.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test CompilerQueueTest
+ * @bug 8054889
+ * @build DcmdUtil CompilerQueueTest
+ * @run main CompilerQueueTest
+ * @summary Test of diagnostic command Compiler.queue
+ */
+
+import java.io.BufferedReader;
+import java.io.StringReader;
+
+public class CompilerQueueTest {
+
+    /**
+     * This test calls Jcmd (diagnostic command tool) Compiler.queue and
+     * then parses the output, making sure that the output look ok.
+     *
+     *
+     * Output example:
+     *
+     * Contents of C1 compile queue
+     * ----------------------------
+     * 73       3       java.lang.AbstractStringBuilder::append (50 bytes)
+     * 74       1       java.util.TreeMap::size (5 bytes)
+     * 75       3       java.lang.StringBuilder::append (8 bytes)
+     * 83       3       java.util.TreeMap$ValueIterator::next (8 bytes)
+     * 84       1       javax.management.MBeanFeatureInfo::getName (5 bytes)
+     * ----------------------------
+     * Contents of C2 compile queue
+     * ----------------------------
+     * Empty
+     * ----------------------------
+     *
+     **/
+
+    public static void main(String arg[]) throws Exception {
+
+        // Get output from dcmd (diagnostic command)
+        String result = DcmdUtil.executeDcmd("Compiler.queue");
+        BufferedReader r = new BufferedReader(new StringReader(result));
+
+        String line;
+        match(r.readLine(), "Contents of C1 compile queue");
+        match(r.readLine(), "----------------------------");
+        String str = r.readLine();
+        if (!str.equals("Empty")) {
+            while (str.charAt(0) != '-') {
+                validateMethodLine(str);
+                str = r.readLine();
+            }
+        } else {
+            str = r.readLine();
+        }
+
+        match(str,          "----------------------------");
+        match(r.readLine(), "Contents of C2 compile queue");
+        match(r.readLine(), "----------------------------");
+        str = r.readLine();
+        if (!str.equals("Empty")) {
+            while (str.charAt(0) != '-') {
+                validateMethodLine(str);
+                str = r.readLine();
+            }
+        } else {
+            str = r.readLine();
+        }
+        match(str, "----------------------------");
+    }
+
+    private static void validateMethodLine(String str)  throws Exception {
+        String name = str.substring(19);
+        int sep = name.indexOf("::");
+        try {
+            Class.forName(name.substring(0, sep));
+        } catch (ClassNotFoundException e) {
+            throw new Exception("Failed parsing dcmd queue");
+        }
+    }
+
+    public static void match(String line, String str) throws Exception {
+        if (!line.equals(str)) {
+            throw new Exception("String equals: " + line + ", " + str);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/MethodIdentifierParser.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+
+public class MethodIdentifierParser {
+
+    private String logString;
+    private String className;
+    private String methodName;
+    private String methodDescriptor;
+
+    /**
+     * This is a utility class for parsing the log entries for a method. It supplies
+     * a few select methods for reflecting the class and method from that information.
+     *
+     * Example log entries:
+     * "java.util.TreeMap.successor(Ljava/util/TreeMap$Entry;)Ljava/util/TreeMap$Entry;"
+     */
+
+    public MethodIdentifierParser(String logString) {
+        this.logString = logString;
+
+        int i      = logString.lastIndexOf("."); // find start of method name
+        className  = logString.substring(0, i);  // classname is everything before
+        int i2     = logString.indexOf("(");     // Signature starts with an '('
+        methodName = logString.substring(i+1, i2);
+        methodDescriptor  = logString.substring(i2, logString.length());
+
+        // Add sanity check for extracted fields
+    }
+
+    public Method getMethod() throws NoSuchMethodException, SecurityException, ClassNotFoundException, Exception {
+        try {
+            return Class.forName(className).getDeclaredMethod(methodName, getParamenterDescriptorArray());
+        } catch (UnexpectedTokenException e) {
+            throw new Exception("Parse failed");
+        }
+    }
+
+    public Class<?>[] getParamenterDescriptorArray() throws ClassNotFoundException, UnexpectedTokenException {
+        ParameterDecriptorIterator s = new ParameterDecriptorIterator(methodDescriptor);
+        Class<?> paramType;
+        ArrayList<Class<?>> list = new ArrayList<Class<?>>();
+        while ((paramType = s.nextParamType()) != null) {
+            list.add(paramType);
+        }
+        if (list.size() > 0) {
+            return list.toArray(new Class<?>[list.size()]);
+        } else {
+            return null;
+        }
+    }
+
+    class ParameterDecriptorIterator {
+
+        // This class uses charAt() indexing for startMark and i
+        // That is when i points to the last char it can be retrieved with
+        // charAt(i). Including the last char for a subString requires
+        // substring(startMark, i+1);
+
+        private String methodDescriptor;
+        private int startMark;
+
+        public ParameterDecriptorIterator(String signature) {
+            this.methodDescriptor = signature;
+            this.startMark = 0;
+            if (signature.charAt(0) == '(') {
+                this.startMark = 1;
+            }
+        }
+
+        public Class<?> nextParamType() throws UnexpectedTokenException {
+            int i = startMark;
+            while (methodDescriptor.length() > i) {
+                switch (methodDescriptor.charAt(i)) {
+                case 'C':
+                case 'B':
+                case 'I':
+                case 'J':
+                case 'Z':
+                case 'F':
+                case 'D':
+                case 'S':
+                    // Primitive class case, but we may have gotten here with [ as first token
+                    break;
+                case 'L':
+                    // Internal class name suffixed by ';'
+                    while (methodDescriptor.charAt(i) != ';') {
+                        i++;
+                    }
+                    break;
+                case '[':
+                    i++;         // arrays -> do another pass
+                    continue;
+                case ')':
+                    return null; // end found
+                case 'V':
+                case ';':
+                default:
+                    throw new UnexpectedTokenException(methodDescriptor, i);
+                }
+                break;
+            }
+            if (i == startMark) {
+                // Single char -> primitive class case
+                startMark++; // Update for next iteration
+                switch (methodDescriptor.charAt(i)) {
+                case 'C':
+                    return char.class;
+                case 'B':
+                    return byte.class;
+                case 'I':
+                    return int.class;
+                case 'J':
+                    return long.class;
+                case 'F':
+                    return float.class;
+                case 'D':
+                    return double.class;
+                case 'S':
+                    return short.class;
+                case 'Z':
+                    return boolean.class;
+                default:
+                    throw new UnexpectedTokenException(methodDescriptor, i);
+                }
+            } else {
+                // Multi char case
+                String nextParam;
+                if (methodDescriptor.charAt(startMark) == 'L') {
+                    // When reflecting a class the leading 'L' and trailing';' must be removed.
+                    // (When reflecting an array of classes, they must remain...)
+                    nextParam = methodDescriptor.substring(startMark+1, i);
+                } else {
+                    // Any kind of array - simple case, use whole descriptor when reflecting.
+                    nextParam = methodDescriptor.substring(startMark, i+1);
+                }
+                startMark = ++i; // Update for next iteration
+                try {
+                    // The parameter descriptor uses JVM internal class identifier with '/' as
+                    // package separator, but Class.forName expects '.'.
+                    nextParam = nextParam.replace('/', '.');
+                    return Class.forName(nextParam);
+                } catch (ClassNotFoundException e) {
+                    System.out.println("Class not Found: " + nextParam);
+                    return null;
+                }
+            }
+        }
+    }
+
+    class UnexpectedTokenException extends Exception {
+        String descriptor;
+        int i;
+        public UnexpectedTokenException(String descriptor, int i) {
+            this.descriptor = descriptor;
+            this.i = i;
+        }
+
+        @Override
+        public String toString() {
+            return "Unexpected token at: " + i + " in signature: " + descriptor;
+        }
+
+        private static final long serialVersionUID = 1L;
+    }
+
+    public void debugPrint() {
+        System.out.println("mlf in:               " + logString);
+        System.out.println("mlf class:            " + className);
+        System.out.println("mlf method:           " + methodName);
+        System.out.println("mlf methodDescriptor: " + methodDescriptor);
+    }
+}
--- a/jaxp/.hgtags	Wed Jul 05 20:01:05 2017 +0200
+++ b/jaxp/.hgtags	Wed Jul 05 20:01:50 2017 +0200
@@ -273,3 +273,4 @@
 dc1e26434b3fd7e9b8eeab149103c1e30965f95c jdk9-b28
 30adcd13a313ea91e81164801a2f89282756d933 jdk9-b29
 d181d4002214e4914d5525bd5ee13369311c765c jdk9-b30
+292317ebc7dbaca6b3965f0bc7b38a2cee733b7a jdk9-b31
--- a/jaxws/.hgtags	Wed Jul 05 20:01:05 2017 +0200
+++ b/jaxws/.hgtags	Wed Jul 05 20:01:50 2017 +0200
@@ -276,3 +276,4 @@
 5282a14f131f897cc9575872c0fae72d47dc4e65 jdk9-b28
 3d1a4bfb6abbf5011ba6d8896301ee3b6ef3ba72 jdk9-b29
 e58d3ea638c3824f01547596b2a98aa5f77c4a5c jdk9-b30
+7af228ae847f3c02aaafb7b01cdbb3bdc2e89e77 jdk9-b31
--- a/jaxws/src/jdk.xml.bind/share/classes/com/sun/tools/internal/xjc/api/util/ApClassLoader.java	Wed Jul 05 20:01:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,152 +0,0 @@
-/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.tools.internal.xjc.api.util;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.File;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.net.MalformedURLException;
-
-import com.sun.istack.internal.Nullable;
-
-/**
- * {@link ClassLoader} that loads Annotation Processing and specified classes
- * both into the same classloader, so that they can reference each other.
- *
- * @author Bhakti Mehta
- * @since 2.0 beta
- */
-public final class ApClassLoader extends URLClassLoader {
-    /**
-     * List of package prefixes we want to mask the
-     * parent classLoader from loading
-     */
-    private final String[] packagePrefixes;
-
-    /**
-     *
-     * @param packagePrefixes
-     *      The package prefixes that are forced to resolve within this class loader.
-     * @param parent
-     *      The parent class loader to delegate to. Null to indicate bootstrap classloader.
-     */
-    public ApClassLoader(@Nullable ClassLoader parent, String[] packagePrefixes) throws ToolsJarNotFoundException {
-        super(getToolsJar(parent),parent);
-        if(getURLs().length==0)
-            // if tools.jar was found in our classloader, no need to create
-            // a parallel classes
-            this.packagePrefixes = new String[0];
-        else
-            this.packagePrefixes = packagePrefixes;
-    }
-
-    public Class loadClass(String className) throws ClassNotFoundException {
-        for( String prefix : packagePrefixes ) {
-            if (className.startsWith(prefix) ) {
-                // we need to load those classes in this class loader
-                // without delegation.
-                return findClass(className);
-            }
-        }
-
-        return super.loadClass(className);
-
-    }
-
-    protected Class findClass(String name) throws ClassNotFoundException {
-
-        StringBuilder sb = new StringBuilder(name.length() + 6);
-        sb.append(name.replace('.','/')).append(".class");
-
-        InputStream is = getResourceAsStream(sb.toString());
-        if (is==null)
-            throw new ClassNotFoundException("Class not found" + sb);
-
-        try {
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            byte[] buf = new byte[1024];
-            int len;
-            while((len=is.read(buf))>=0)
-                baos.write(buf,0,len);
-
-            buf = baos.toByteArray();
-
-            // define package if not defined yet
-            int i = name.lastIndexOf('.');
-            if (i != -1) {
-                String pkgname = name.substring(0, i);
-                Package pkg = getPackage(pkgname);
-                if(pkg==null)
-                    definePackage(pkgname, null, null, null, null, null, null, null);
-            }
-
-            return defineClass(name,buf,0,buf.length);
-        } catch (IOException e) {
-            throw new ClassNotFoundException(name,e);
-        } finally {
-            try {
-                is.close();
-            } catch (IOException ioe) {
-                //ignore
-            }
-        }
-    }
-
-    /**
-     * Returns a class loader that can load classes from JDK tools.jar.
-     * @param parent
-     */
-    private static URL[] getToolsJar(@Nullable ClassLoader parent) throws ToolsJarNotFoundException {
-
-        try {
-            Class.forName("com.sun.tools.javac.Main", false, parent);
-            return new URL[0];
-            // we can already load them in the parent class loader.
-            // so no need to look for tools.jar.
-            // this happens when we are run inside IDE/Ant, or
-            // in Mac OS.
-        } catch (ClassNotFoundException e) {
-            // otherwise try to find tools.jar
-        }
-
-        File jreHome = new File(System.getProperty("java.home"));
-        File toolsJar = new File( jreHome.getParent(), "lib/tools.jar" );
-
-        if (!toolsJar.exists()) {
-            throw new ToolsJarNotFoundException(toolsJar);
-        }
-
-        try {
-            return new URL[]{toolsJar.toURL()};
-        } catch (MalformedURLException e) {
-            // impossible
-            throw new AssertionError(e);
-        }
-    }
-}
--- a/jaxws/src/jdk.xml.bind/share/classes/com/sun/tools/internal/xjc/api/util/ToolsJarNotFoundException.java	Wed Jul 05 20:01:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.tools.internal.xjc.api.util;
-
-import java.io.File;
-
-/**
- * Signals an error when tools.jar was not found.
- *
- * Simply print out the message obtained by {@link #getMessage()}.
- *
- * @author Kohsuke Kawaguchi
- */
-public final class ToolsJarNotFoundException extends Exception {
-    /**
-     * Location where we expected to find tools.jar
-     */
-    public final File toolsJar;
-
-    public ToolsJarNotFoundException(File toolsJar) {
-        super(calcMessage(toolsJar));
-        this.toolsJar = toolsJar;
-    }
-
-    private static String calcMessage(File toolsJar) {
-        return Messages.TOOLS_JAR_NOT_FOUND.format(toolsJar.getPath());
-    }
-}
--- a/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/Invoker.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/Invoker.java	Wed Jul 05 20:01:50 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,19 +29,16 @@
 import com.sun.istack.internal.tools.ParallelWorldClassLoader;
 import com.sun.tools.internal.ws.resources.WscompileMessages;
 import com.sun.tools.internal.ws.wscompile.Options;
-import com.sun.tools.internal.xjc.api.util.ToolsJarNotFoundException;
 import com.sun.xml.internal.bind.util.Which;
 
 import javax.xml.ws.Service;
 import javax.xml.ws.WebServiceFeature;
 import javax.xml.namespace.QName;
-import java.io.File;
 import java.io.OutputStream;
 import java.io.IOException;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.util.ArrayList;
@@ -59,7 +56,7 @@
     /**
      * The list of package prefixes we want the
      * {@link MaskingClassLoader} to prevent the parent
-     * classLoader from loading
+     * class loader from loading
      */
     static final String[] maskedPackages = new String[]{
             "com.sun.istack.internal.tools.",
@@ -130,24 +127,6 @@
                     return -1;
                 }
 
-                //find and load tools.jar
-                List<URL> urls = new ArrayList<URL>();
-                findToolsJar(cl, urls);
-
-                if(urls.size() > 0){
-                    List<String> mask = new ArrayList<String>(Arrays.asList(maskedPackages));
-
-                    // first create a protected area so that we load JAXB/WS 2.1 API
-                    // and everything that depends on them inside
-                    cl = new MaskingClassLoader(cl,mask);
-
-                    // then this classloader loads the API and tools.jar
-                    cl = new URLClassLoader(urls.toArray(new URL[urls.size()]), cl);
-
-                    // finally load the rest of the RI. The actual class files are loaded from ancestors
-                    cl = new ParallelWorldClassLoader(cl,"");
-                        }
-
             }
 
             Thread.currentThread().setContextClassLoader(cl);
@@ -158,8 +137,6 @@
             Method runMethod = compileTool.getMethod("run",String[].class);
             boolean r = (Boolean)runMethod.invoke(tool,new Object[]{args});
             return r ? 0 : 1;
-        } catch (ToolsJarNotFoundException e) {
-            System.err.println(e.getMessage());
         } catch (InvocationTargetException e) {
             throw e.getCause();
         } catch(ClassNotFoundException e){
@@ -167,8 +144,6 @@
         }finally {
             Thread.currentThread().setContextClassLoader(oldcc);
         }
-
-        return -1;
     }
 
     /**
@@ -203,10 +178,10 @@
 
 
     /**
-     * Creates a classloader that can load JAXB/WS 2.2 API and tools.jar,
-     * and then return a classloader that can RI classes, which can see all those APIs and tools.jar.
+     * Creates a class loader that can load JAXB/WS 2.2 API,
+     * and then return a class loader that can RI classes, which can see all those APIs.
      */
-    public static ClassLoader createClassLoader(ClassLoader cl) throws ClassNotFoundException, IOException, ToolsJarNotFoundException {
+    public static ClassLoader createClassLoader(ClassLoader cl) throws ClassNotFoundException, IOException {
 
         URL[] urls = findIstack22APIs(cl);
         if(urls.length==0)
@@ -223,7 +198,7 @@
         // and everything that depends on them inside
         cl = new MaskingClassLoader(cl,mask);
 
-        // then this classloader loads the API and tools.jar
+        // then this class loader loads the API
         cl = new URLClassLoader(urls, cl);
 
         // finally load the rest of the RI. The actual class files are loaded from ancestors
@@ -233,13 +208,13 @@
     }
 
     /**
-     * Creates a classloader for loading JAXB/WS 2.2 jar and tools.jar
+     * Creates a class loader for loading JAXB/WS 2.2 jar
      */
-    private static URL[] findIstack22APIs(ClassLoader cl) throws ClassNotFoundException, IOException, ToolsJarNotFoundException {
+    private static URL[] findIstack22APIs(ClassLoader cl) throws ClassNotFoundException, IOException {
         List<URL> urls = new ArrayList<URL>();
 
         if(Service.class.getClassLoader()==null) {
-            // JAX-WS API is loaded from bootstrap classloader
+            // JAX-WS API is loaded from bootstrap class loader
             URL res = cl.getResource("javax/xml/ws/EndpointContext.class");
             if(res==null)
                 throw new ClassNotFoundException("There's no JAX-WS 2.2 API in the classpath");
@@ -250,28 +225,7 @@
             urls.add(ParallelWorldClassLoader.toJarUrl(res));
         }
 
-        findToolsJar(cl, urls);
-
         return urls.toArray(new URL[urls.size()]);
     }
 
-    private static void findToolsJar(ClassLoader cl, List<URL> urls) throws ToolsJarNotFoundException, MalformedURLException {
-        try {
-            Class.forName("com.sun.tools.javac.Main",false,cl);
-            // we can already load them in the parent class loader.
-            // so no need to look for tools.jar.
-            // this happens when we are run inside IDE/Ant, or
-            // in Mac OS.
-        } catch (ClassNotFoundException e) {
-            // otherwise try to find tools.jar
-            File jreHome = new File(System.getProperty("java.home"));
-            File toolsJar = new File( jreHome.getParent(), "lib/tools.jar" );
-
-            if (!toolsJar.exists()) {
-                throw new ToolsJarNotFoundException(toolsJar);
-            }
-            urls.add(toolsJar.toURL());
-        }
-    }
-
 }
--- a/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/WsGen.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/WsGen.java	Wed Jul 05 20:01:50 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,8 +35,7 @@
  */
 public class WsGen {
     /**
-     * CLI entry point. Use {@link Invoker} to
-     * load tools.jar
+     * CLI entry point. Use {@link Invoker} to load proper API version
      */
     public static void main(String[] args) throws Throwable {
         System.exit(Invoker.invoke("com.sun.tools.internal.ws.wscompile.WsgenTool", args));
@@ -50,7 +49,7 @@
      * it doesn't invoke {@link System#exit(int)}. This method
      * also doesn't play with classloaders. It's the caller's
      * responsibility to set up the classloader to load all jars
-     * needed to run the tool, including <tt>$JAVA_HOME/lib/tools.jar</tt>
+     * needed to run the tool.
      *
      * @return
      *      0 if the tool runs successfully.
--- a/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/WsImport.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/WsImport.java	Wed Jul 05 20:01:50 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,8 +35,7 @@
  */
 public class WsImport {
     /**
-     * CLI entry point. Use {@link Invoker} to
-     * load tools.jar
+     * CLI entry point. Use {@link Invoker} to load proper API version
      */
     public static void main(String[] args) throws Throwable {
         System.exit(Invoker.invoke("com.sun.tools.internal.ws.wscompile.WsimportTool", args));
@@ -50,7 +49,7 @@
      * it doesn't invoke {@link System#exit(int)}. This method
      * also doesn't play with classloaders. It's the caller's
      * responsibility to set up the classloader to load all jars
-     * needed to run the tool, including <tt>$JAVA_HOME/lib/tools.jar</tt>
+     * needed to run the tool.
      *
      * @return
      *      0 if the tool runs successfully.
--- a/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/resources/JavacompilerMessages.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/resources/JavacompilerMessages.java	Wed Jul 05 20:01:50 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,40 +39,16 @@
     private final static LocalizableMessageFactory messageFactory = new LocalizableMessageFactory("com.sun.tools.internal.ws.resources.javacompiler");
     private final static Localizer localizer = new Localizer();
 
-    public static Localizable localizableJAVACOMPILER_CLASSPATH_ERROR(Object arg0) {
-        return messageFactory.getMessage("javacompiler.classpath.error", arg0);
-    }
-
-    /**
-     * {0} is not available in the classpath, requires Sun's JDK version 5.0 or latter.
-     *
-     */
-    public static String JAVACOMPILER_CLASSPATH_ERROR(Object arg0) {
-        return localizer.localize(localizableJAVACOMPILER_CLASSPATH_ERROR(arg0));
-    }
-
-    public static Localizable localizableJAVACOMPILER_NOSUCHMETHOD_ERROR(Object arg0) {
-        return messageFactory.getMessage("javacompiler.nosuchmethod.error", arg0);
+    public static Localizable localizableNO_JAVACOMPILER_ERROR() {
+        return messageFactory.getMessage("no.javacompiler.error");
     }
 
     /**
-     * There is no such method {0} available, requires Sun's JDK version 5.0 or latter.
+     * No system compiler found, check your jdk.
      *
      */
-    public static String JAVACOMPILER_NOSUCHMETHOD_ERROR(Object arg0) {
-        return localizer.localize(localizableJAVACOMPILER_NOSUCHMETHOD_ERROR(arg0));
-    }
-
-    public static Localizable localizableJAVACOMPILER_ERROR(Object arg0) {
-        return messageFactory.getMessage("javacompiler.error", arg0);
-    }
-
-    /**
-     * error : {0}.
-     *
-     */
-    public static String JAVACOMPILER_ERROR(Object arg0) {
-        return localizer.localize(localizableJAVACOMPILER_ERROR(arg0));
+    public static String NO_JAVACOMPILER_ERROR() {
+        return localizer.localize(localizableNO_JAVACOMPILER_ERROR());
     }
 
 }
--- a/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/resources/javacompiler.properties	Wed Jul 05 20:01:05 2017 +0200
+++ b/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/resources/javacompiler.properties	Wed Jul 05 20:01:50 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,4 @@
 #
 # Generic Messages
 #
-javacompiler.classpath.error={0} is not available in the classpath, requires Sun's JDK version 5.0 or latter.
-javacompiler.nosuchmethod.error=There is no such method {0} available, requires Sun's JDK version 5.0 or latter.
-javacompiler.error=error : {0}.
+no.javacompiler.error=No system compiler found, check your jdk.
--- a/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/wscompile/JavaCompilerHelper.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/wscompile/JavaCompilerHelper.java	Wed Jul 05 20:01:50 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,14 +28,13 @@
 import com.sun.istack.internal.tools.ParallelWorldClassLoader;
 import com.sun.tools.internal.ws.resources.JavacompilerMessages;
 
+import javax.tools.JavaCompiler;
+import javax.tools.ToolProvider;
 import java.io.File;
 import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
 import java.net.MalformedURLException;
+import java.net.URISyntaxException;
 import java.net.URL;
-import java.net.URISyntaxException;
 
 /**
  * A helper class to invoke javac.
@@ -61,34 +60,17 @@
     }
 
     static boolean compile(String[] args, OutputStream out, ErrorReceiver receiver){
-        ClassLoader cl = Thread.currentThread().getContextClassLoader();
         try {
-            /* try to use the new compiler */
-            Class comSunToolsJavacMainClass =
-                    cl.loadClass("com.sun.tools.javac.Main");
-            try {
-                Method compileMethod =
-                        comSunToolsJavacMainClass.getMethod(
-                                "compile",
-                                compileMethodSignature);
-                    Object result =
-                            compileMethod.invoke(
-                                    null, args, new PrintWriter(out));
-                    return result instanceof Integer && (Integer) result == 0;
-            } catch (NoSuchMethodException e2) {
-                receiver.error(JavacompilerMessages.JAVACOMPILER_NOSUCHMETHOD_ERROR("getMethod(\"compile\", Class[])"), e2);
-            } catch (IllegalAccessException e) {
-                receiver.error(e);
-            } catch (InvocationTargetException e) {
-                receiver.error(e);
+            JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
+            if (comp == null) {
+                receiver.error(JavacompilerMessages.NO_JAVACOMPILER_ERROR(), null);
+                return false;
             }
-        } catch (ClassNotFoundException e) {
-            receiver.error(JavacompilerMessages.JAVACOMPILER_CLASSPATH_ERROR("com.sun.tools.javac.Main"), e);
+            return 0 == comp.run(null, out, out, args);
         } catch (SecurityException e) {
             receiver.error(e);
         }
         return false;
     }
 
-    private static final Class[] compileMethodSignature = {String[].class, PrintWriter.class};
 }
--- a/jdk/.hgtags	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/.hgtags	Wed Jul 05 20:01:50 2017 +0200
@@ -273,3 +273,4 @@
 1828f73b35cfe35e460e41fd6e087ab1f83e0621 jdk9-b28
 2da27e8e2c865e154f0c2eb9009f011a44649b11 jdk9-b29
 8d24fb4493f13d380a2adf62d444e1e5a4451f37 jdk9-b30
+71e99dae28f9791287b88d46e16a266b564f22be jdk9-b31
--- a/jdk/make/CreateJars.gmk	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/make/CreateJars.gmk	Wed Jul 05 20:01:50 2017 +0200
@@ -220,7 +220,6 @@
     sun/tools/serialver \
     sun/tools/tree \
     sun/tools/util \
-    sun/util/cldr/CLDRLocaleDataMetaInfo.class \
     sun/util/resources/provider/NonEnLocaleDataMetaInfo.class \
     META-INF/services/sun.util.locale.provider.LocaleDataMetaInfo \
     sun/util/resources/cldr \
@@ -452,11 +451,9 @@
 $(eval $(call SetupArchive,BUILD_CLDRDATA_JAR, \
     $(CLDR_METAINF_SERVICES), \
     SRCS := $(JDK_OUTPUTDIR)/modules/jdk.localedata \
-        $(JDK_OUTPUTDIR)/modules/java.base \
         $(CLDR_SERVICES_DIR), \
     SUFFIXES := .class, \
     INCLUDES := sun/text/resources/cldr \
-        sun/util/cldr/CLDRLocaleDataMetaInfo.class \
         sun/util/resources/cldr, \
     EXTRA_FILES := META-INF/services/sun.util.locale.provider.LocaleDataMetaInfo, \
     JAR := $(CLDRDATA_JAR_DST), \
--- a/jdk/make/gensrc/Gensrc-java.base.gmk	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/make/gensrc/Gensrc-java.base.gmk	Wed Jul 05 20:01:50 2017 +0200
@@ -29,14 +29,13 @@
 include GensrcProperties.gmk
 GENSRC_JAVA_BASE += $(GENSRC_PROPERTIES)
 
-include GensrcLocaleDataMetaInfo.gmk
+include GensrcLocaleData.gmk
 include GensrcCharacterData.gmk
 include GensrcMisc.gmk
 include GensrcCharsetMapping.gmk
 include GensrcCharsetCoder.gmk
 include GensrcBuffer.gmk
 include GensrcExceptions.gmk
-include GensrcCLDR.gmk
 
 java.base: $(GENSRC_JAVA_BASE)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/gensrc/Gensrc-jdk.localedata.gmk	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+include GensrcCommon.gmk
+
+# Hook to include the corresponding custom file, if present.
+$(eval $(call IncludeCustomExtension, jdk, gensrc/Gensrc-jdk.localedata.gmk))
+
+include GensrcLocaleData.gmk
+include GensrcCLDR.gmk
+
+jdk.localedata: $(GENSRC_JDK_LOCALEDATA)
+
+all: jdk.localedata
+
+.PHONY: all jdk.localedata
--- a/jdk/make/gensrc/GensrcCLDR.gmk	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/make/gensrc/GensrcCLDR.gmk	Wed Jul 05 20:01:50 2017 +0200
@@ -27,9 +27,8 @@
 CLDRSRCDIR := $(JDK_TOPDIR)/src/jdk.localedata/share/classes/sun/util/cldr/resources/$(subst .,_,$(CLDRVERSION))
 
 GENSRC_DIR := $(JDK_OUTPUTDIR)/gensrc/jdk.localedata
-BASE_GENSRC_DIR := $(JDK_OUTPUTDIR)/gensrc/java.base
 
-CLDR_METAINFO_FILE := $(BASE_GENSRC_DIR)/sun/util/cldr/CLDRLocaleDataMetaInfo.java
+CLDR_METAINFO_FILE := $(GENSRC_DIR)/sun/util/resources/cldr/provider/CLDRLocaleDataMetaInfo.java
 
 $(CLDR_METAINFO_FILE): $(wildcard $(CLDRSRCDIR)/common/dtd/*.dtd) \
     $(wildcard $(CLDRSRCDIR)/common/main/*.xml) \
@@ -37,16 +36,6 @@
     $(BUILD_TOOLS_JDK)
 	$(MKDIR) -p $(GENSRC_DIR)
 	$(TOOL_CLDRCONVERTER) -base $(CLDRSRCDIR) -o $(GENSRC_DIR)
-	$(MKDIR) -p $(BASE_GENSRC_DIR)/sun/text/resources/cldr
-	$(MKDIR) -p $(BASE_GENSRC_DIR)/sun/util/resources/cldr
-	$(RM) -r $(BASE_GENSRC_DIR)/sun/text/resources/cldr/en \
-	    $(BASE_GENSRC_DIR)/sun/util/resources/cldr/en
-	$(MV) $(GENSRC_DIR)/sun/text/resources/cldr/en $(BASE_GENSRC_DIR)/sun/text/resources/cldr/en
-	$(MV) $(GENSRC_DIR)/sun/util/resources/cldr/en $(BASE_GENSRC_DIR)/sun/util/resources/cldr/en
-	$(MV) $(GENSRC_DIR)/sun/text/resources/cldr/*.java $(BASE_GENSRC_DIR)/sun/text/resources/cldr
-	$(MV) $(GENSRC_DIR)/sun/util/resources/cldr/*.java $(BASE_GENSRC_DIR)/sun/util/resources/cldr
-	$(MKDIR) -p $(@D)
-	$(MV) $(GENSRC_DIR)/sun/util/cldr/CLDRLocaleDataMetaInfo.java $@
 
 GENSRC_CLDR := $(CLDR_METAINFO_FILE)
-GENSRC_JAVA_BASE += $(GENSRC_CLDR)
+GENSRC_JDK_LOCALEDATA += $(GENSRC_CLDR)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/gensrc/GensrcLocaleData.gmk	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,152 @@
+#
+# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# Scan for all locale resources and extract for which locales there exists
+# resources. Then put this meta information about existing (supported?) locales
+# into LocaleDataMetaInfo.java
+
+# First go look for all locale files
+LOCALE_FILES := $(shell $(FIND) $(JDK_TOPDIR)/src/java.base/share/classes \
+    $(JDK_TOPDIR)/src/jdk.localedata/share/classes \
+    -name "FormatData_*.java" -o -name "FormatData_*.properties" -o \
+    -name "CollationData_*.java" -o -name "CollationData_*.properties" -o \
+    -name "TimeZoneNames_*.java" -o -name "TimeZoneNames_*.properties" -o \
+    -name "LocaleNames_*.java" -o -name "LocaleNames_*.properties" -o \
+    -name "CurrencyNames_*.java" -o -name "CurrencyNames_*.properties" -o \
+    -name "CalendarData_*.java" -o -name "CalendarData_*.properties" -o \
+    -name "BreakIteratorInfo_*.java" -o -name "BreakIteratorRules_*.java")
+
+# Then translate the locale files into for example: FormatData_sv
+LOCALE_RESOURCES := $(sort $(subst .properties,,$(subst .java,,$(notdir $(LOCALE_FILES)))))
+
+# Include the list of resources found during the previous compile.
+-include $(JDK_OUTPUTDIR)/gensrc/_the.locale_resources
+
+MISSING_RESOURCES := $(filter-out $(LOCALE_RESOURCES), $(PREV_LOCALE_RESOURCES))
+NEW_RESOURCES := $(filter-out $(PREV_LOCALE_RESOURCES), $(LOCALE_RESOURCES))
+
+ifneq (, $(MISSING_RESOURCES)$(NEW_RESOURCES))
+  # There is a difference in the number of supported resources. Trigger a regeneration.
+  $(shell $(RM) $(JDK_OUTPUTDIR)/gensrc/sun/util/locale/provider/LocaleDataMetaInfo.java)
+endif
+
+# The EN locales
+EN_LOCALES := en%
+
+# Locales that don't have any resource files should be included here.
+ALL_NON_EN_LOCALES := ja-JP-JP nb-NO nn-NO th-TH-TH
+
+SED_ENARGS := -e 's|$(HASH)warn This file is preprocessed before being compiled|// -- This file was mechanically generated: Do not edit! -- //|g'
+SED_NONENARGS := $(SED_ENARGS)
+
+# Fill in the languages and package names
+SED_ENARGS += -e 's/$(HASH)Lang$(HASH)/En/' \
+    -e 's/$(HASH)Package$(HASH)/sun.util.locale.provider/'
+SED_NONENARGS += -e 's/$(HASH)Lang$(HASH)/NonEn/' \
+    -e 's/$(HASH)Package$(HASH)/sun.util.resources.provider/'
+
+# This macro creates a sed expression that substitues for example:
+# #FormatData_ENLocales# with: en% locales.
+define CaptureLocale
+  $1_LOCALES := $$(subst _,-,$$(filter-out $1, $$(subst $1_,,$$(filter $1_%, $(LOCALE_RESOURCES)))))
+  $1_EN_LOCALES := $$(filter $(EN_LOCALES), $$($1_LOCALES))
+  $1_NON_EN_LOCALES := $$(filter-out $(EN_LOCALES), $$($1_LOCALES))
+
+  # Special handling for Chinese locales to include implicit scripts
+  $1_NON_EN_LOCALES := $$(subst zh-CN,zh-CN$$(SPACE)zh-Hans-CN, $$($1_NON_EN_LOCALES))
+  $1_NON_EN_LOCALES := $$(subst zh-SG,zh-SG$$(SPACE)zh-Hans-SG, $$($1_NON_EN_LOCALES))
+  $1_NON_EN_LOCALES := $$(subst zh-HK,zh-HK$$(SPACE)zh-Hant-HK, $$($1_NON_EN_LOCALES))
+  $1_NON_EN_LOCALES := $$(subst zh-MO,zh-MO$$(SPACE)zh-Hant-MO, $$($1_NON_EN_LOCALES))
+  $1_NON_EN_LOCALES := $$(subst zh-TW,zh-TW$$(SPACE)zh-Hant-TW, $$($1_NON_EN_LOCALES))
+
+  ALL_EN_LOCALES += $$($1_EN_LOCALES)
+  ALL_NON_EN_LOCALES += $$($1_NON_EN_LOCALES)
+
+  # Don't sed in a space if there are no locales.
+  SED_ENARGS += -e 's/$$(HASH)$1_Locales$$(HASH)/$$(if $$($1_EN_LOCALES),$$(SPACE)$$($1_EN_LOCALES),)/g'
+  SED_NONENARGS += -e 's/$$(HASH)$1_Locales$$(HASH)/$$(if $$($1_NON_EN_LOCALES),$$(SPACE)$$($1_NON_EN_LOCALES),)/g'
+endef
+
+#sun.text.resources.FormatData
+$(eval $(call CaptureLocale,FormatData))
+
+#sun.text.resources.CollationData
+$(eval $(call CaptureLocale,CollationData))
+
+#sun.text.resources.BreakIteratorInfo
+$(eval $(call CaptureLocale,BreakIteratorInfo))
+
+#sun.text.resources.BreakIteratorRules
+$(eval $(call CaptureLocale,BreakIteratorRules))
+
+#sun.util.resources.TimeZoneNames
+$(eval $(call CaptureLocale,TimeZoneNames))
+
+#sun.util.resources.LocaleNames
+$(eval $(call CaptureLocale,LocaleNames))
+
+#sun.util.resources.CurrencyNames
+$(eval $(call CaptureLocale,CurrencyNames))
+
+#sun.util.resources.CalendarData
+$(eval $(call CaptureLocale,CalendarData))
+
+SED_ENARGS += -e 's/$(HASH)AvailableLocales_Locales$(HASH)/$(sort $(ALL_EN_LOCALES))/g'
+SED_NONENARGS += -e 's/$(HASH)AvailableLocales_Locales$(HASH)/$(sort $(ALL_NON_EN_LOCALES))/g'
+
+$(JDK_OUTPUTDIR)/gensrc/java.base/sun/util/locale/provider/EnLocaleDataMetaInfo.java: \
+    $(JDK_TOPDIR)/src/java.base/share/classes/sun/util/locale/provider/LocaleDataMetaInfo-XLocales.java.template
+	$(MKDIR) -p $(@D)
+	$(ECHO) Creating sun/util/locale/provider/EnLocaleDataMetaInfo.java from $(words $(LOCALE_RESOURCES)) found resources.
+	$(PRINTF) "PREV_LOCALE_RESOURCES:=$(LOCALE_RESOURCES)" > $(JDK_OUTPUTDIR)/gensrc/_the.locale_resources
+	$(SED) $(SED_ENARGS) $< > $@
+
+$(JDK_OUTPUTDIR)/gensrc/jdk.localedata/sun/util/resources/provider/NonEnLocaleDataMetaInfo.java: \
+    $(JDK_TOPDIR)/src/java.base/share/classes/sun/util/locale/provider/LocaleDataMetaInfo-XLocales.java.template
+	$(MKDIR) -p $(@D)
+	$(ECHO) Creating sun/util/resources/provider/NonEnLocaleDataMetaInfo.java from $(words $(LOCALE_RESOURCES)) found resources.
+	$(PRINTF) "PREV_LOCALE_RESOURCES:=$(LOCALE_RESOURCES)" > $(JDK_OUTPUTDIR)/gensrc/_the.locale_resources
+	$(SED) $(SED_NONENARGS) $< > $@
+
+GENSRC_BASELOCALEDATA := $(JDK_OUTPUTDIR)/gensrc/java.base/sun/util/locale/provider/EnLocaleDataMetaInfo.java
+GENSRC_LOCALEDATA := $(JDK_OUTPUTDIR)/gensrc/jdk.localedata/sun/util/resources/provider/NonEnLocaleDataMetaInfo.java
+
+################################################################################
+
+GENSRC_CRBC_DST := $(JDK_OUTPUTDIR)/gensrc/java.base/sun/util/CoreResourceBundleControl.java
+GENSRC_CRBC_CMD := $(JDK_TOPDIR)/make/scripts/localelist.sh
+
+JRE_NONEXIST_LOCALES := en en_US de_DE es_ES fr_FR it_IT ja_JP ko_KR sv_SE zh
+
+$(GENSRC_CRBC_DST): $(JDK_TOPDIR)/src/java.base/share/classes/sun/util/CoreResourceBundleControl-XLocales.java.template \
+    $(GENSRC_CRBC_CMD)
+	$(MKDIR) -p $(@D)
+	NAWK="$(NAWK)" SED="$(SED)" $(SH) $(GENSRC_CRBC_CMD) "$(JRE_NONEXIST_LOCALES)" $< $@
+
+GENSRC_BASELOCALEDATA += $(GENSRC_CRBC_DST)
+GENSRC_JAVA_BASE += $(GENSRC_BASELOCALEDATA)
+GENSRC_JDK_LOCALEDATA += $(GENSRC_LOCALEDATA)
+
+################################################################################
--- a/jdk/make/gensrc/GensrcLocaleDataMetaInfo.gmk	Wed Jul 05 20:01:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,151 +0,0 @@
-#
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.  Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-# Scan for all locale resources and extract for which locales there exists
-# resources. Then put this meta information about existing (supported?) locales
-# into LocaleDataMetaInfo.java
-
-# First go look for all locale files
-LOCALE_FILES := $(shell $(FIND) $(JDK_TOPDIR)/src/java.base/share/classes \
-    $(JDK_TOPDIR)/src/jdk.localedata/share/classes \
-    -name "FormatData_*.java" -o -name "FormatData_*.properties" -o \
-    -name "CollationData_*.java" -o -name "CollationData_*.properties" -o \
-    -name "TimeZoneNames_*.java" -o -name "TimeZoneNames_*.properties" -o \
-    -name "LocaleNames_*.java" -o -name "LocaleNames_*.properties" -o \
-    -name "CurrencyNames_*.java" -o -name "CurrencyNames_*.properties" -o \
-    -name "CalendarData_*.java" -o -name "CalendarData_*.properties" -o \
-    -name "BreakIteratorInfo_*.java" -o -name "BreakIteratorRules_*.java")
-
-# Then translate the locale files into for example: FormatData_sv
-LOCALE_RESOURCES := $(sort $(subst .properties,,$(subst .java,,$(notdir $(LOCALE_FILES)))))
-
-# Include the list of resources found during the previous compile.
--include $(JDK_OUTPUTDIR)/gensrc/_the.locale_resources
-
-MISSING_RESOURCES := $(filter-out $(LOCALE_RESOURCES), $(PREV_LOCALE_RESOURCES))
-NEW_RESOURCES := $(filter-out $(PREV_LOCALE_RESOURCES), $(LOCALE_RESOURCES))
-
-ifneq (, $(MISSING_RESOURCES)$(NEW_RESOURCES))
-  # There is a difference in the number of supported resources. Trigger a regeneration.
-  $(shell $(RM) $(JDK_OUTPUTDIR)/gensrc/sun/util/locale/provider/LocaleDataMetaInfo.java)
-endif
-
-# The EN locales
-EN_LOCALES := en%
-
-# Locales that don't have any resource files should be included here.
-ALL_NON_EN_LOCALES := ja-JP-JP nb-NO nn-NO th-TH-TH
-
-SED_ENARGS := -e 's|$(HASH)warn This file is preprocessed before being compiled|// -- This file was mechanically generated: Do not edit! -- //|g'
-SED_NONENARGS := $(SED_ENARGS)
-
-# Fill in the languages and package names
-SED_ENARGS += -e 's/$(HASH)Lang$(HASH)/En/' \
-    -e 's/$(HASH)Package$(HASH)/sun.util.locale.provider/'
-SED_NONENARGS += -e 's/$(HASH)Lang$(HASH)/NonEn/' \
-    -e 's/$(HASH)Package$(HASH)/sun.util.resources.provider/'
-
-# This macro creates a sed expression that substitues for example:
-# #FormatData_ENLocales# with: en% locales.
-define CaptureLocale
-  $1_LOCALES := $$(subst _,-,$$(filter-out $1, $$(subst $1_,,$$(filter $1_%, $(LOCALE_RESOURCES)))))
-  $1_EN_LOCALES := $$(filter $(EN_LOCALES), $$($1_LOCALES))
-  $1_NON_EN_LOCALES := $$(filter-out $(EN_LOCALES), $$($1_LOCALES))
-
-  # Special handling for Chinese locales to include implicit scripts
-  $1_NON_EN_LOCALES := $$(subst zh-CN,zh-CN$$(SPACE)zh-Hans-CN, $$($1_NON_EN_LOCALES))
-  $1_NON_EN_LOCALES := $$(subst zh-SG,zh-SG$$(SPACE)zh-Hans-SG, $$($1_NON_EN_LOCALES))
-  $1_NON_EN_LOCALES := $$(subst zh-HK,zh-HK$$(SPACE)zh-Hant-HK, $$($1_NON_EN_LOCALES))
-  $1_NON_EN_LOCALES := $$(subst zh-MO,zh-MO$$(SPACE)zh-Hant-MO, $$($1_NON_EN_LOCALES))
-  $1_NON_EN_LOCALES := $$(subst zh-TW,zh-TW$$(SPACE)zh-Hant-TW, $$($1_NON_EN_LOCALES))
-
-  ALL_EN_LOCALES += $$($1_EN_LOCALES)
-  ALL_NON_EN_LOCALES += $$($1_NON_EN_LOCALES)
-
-  # Don't sed in a space if there are no locales.
-  SED_ENARGS += -e 's/$$(HASH)$1_Locales$$(HASH)/$$(if $$($1_EN_LOCALES),$$(SPACE)$$($1_EN_LOCALES),)/g'
-  SED_NONENARGS += -e 's/$$(HASH)$1_Locales$$(HASH)/$$(if $$($1_NON_EN_LOCALES),$$(SPACE)$$($1_NON_EN_LOCALES),)/g'
-endef
-
-#sun.text.resources.FormatData
-$(eval $(call CaptureLocale,FormatData))
-
-#sun.text.resources.CollationData
-$(eval $(call CaptureLocale,CollationData))
-
-#sun.text.resources.BreakIteratorInfo
-$(eval $(call CaptureLocale,BreakIteratorInfo))
-
-#sun.text.resources.BreakIteratorRules
-$(eval $(call CaptureLocale,BreakIteratorRules))
-
-#sun.util.resources.TimeZoneNames
-$(eval $(call CaptureLocale,TimeZoneNames))
-
-#sun.util.resources.LocaleNames
-$(eval $(call CaptureLocale,LocaleNames))
-
-#sun.util.resources.CurrencyNames
-$(eval $(call CaptureLocale,CurrencyNames))
-
-#sun.util.resources.CalendarData
-$(eval $(call CaptureLocale,CalendarData))
-
-SED_ENARGS += -e 's/$(HASH)AvailableLocales_Locales$(HASH)/$(sort $(ALL_EN_LOCALES))/g'
-SED_NONENARGS += -e 's/$(HASH)AvailableLocales_Locales$(HASH)/$(sort $(ALL_NON_EN_LOCALES))/g'
-
-$(JDK_OUTPUTDIR)/gensrc/java.base/sun/util/locale/provider/EnLocaleDataMetaInfo.java: \
-    $(JDK_TOPDIR)/src/java.base/share/classes/sun/util/locale/provider/LocaleDataMetaInfo-XLocales.java.template
-	$(MKDIR) -p $(@D)
-	$(ECHO) Creating sun/util/locale/provider/EnLocaleDataMetaInfo.java from $(words $(LOCALE_RESOURCES)) found resources.
-	$(PRINTF) "PREV_LOCALE_RESOURCES:=$(LOCALE_RESOURCES)" > $(JDK_OUTPUTDIR)/gensrc/_the.locale_resources
-	$(SED) $(SED_ENARGS) $< > $@
-
-$(JDK_OUTPUTDIR)/gensrc/jdk.localedata/sun/util/resources/provider/NonEnLocaleDataMetaInfo.java: \
-    $(JDK_TOPDIR)/src/java.base/share/classes/sun/util/locale/provider/LocaleDataMetaInfo-XLocales.java.template
-	$(MKDIR) -p $(@D)
-	$(ECHO) Creating sun/util/resources/provider/NonEnLocaleDataMetaInfo.java from $(words $(LOCALE_RESOURCES)) found resources.
-	$(PRINTF) "PREV_LOCALE_RESOURCES:=$(LOCALE_RESOURCES)" > $(JDK_OUTPUTDIR)/gensrc/_the.locale_resources
-	$(SED) $(SED_NONENARGS) $< > $@
-
-GENSRC_LOCALEDATAMETAINFO := $(JDK_OUTPUTDIR)/gensrc/java.base/sun/util/locale/provider/EnLocaleDataMetaInfo.java \
-    $(JDK_OUTPUTDIR)/gensrc/jdk.localedata/sun/util/resources/provider/NonEnLocaleDataMetaInfo.java
-
-################################################################################
-
-GENSRC_CRBC_DST := $(JDK_OUTPUTDIR)/gensrc/java.base/sun/util/CoreResourceBundleControl.java
-GENSRC_CRBC_CMD := $(JDK_TOPDIR)/make/scripts/localelist.sh
-
-JRE_NONEXIST_LOCALES := en en_US de_DE es_ES fr_FR it_IT ja_JP ko_KR sv_SE zh
-
-$(GENSRC_CRBC_DST): $(JDK_TOPDIR)/src/java.base/share/classes/sun/util/CoreResourceBundleControl-XLocales.java.template \
-    $(GENSRC_CRBC_CMD)
-	$(MKDIR) -p $(@D)
-	NAWK="$(NAWK)" SED="$(SED)" $(SH) $(GENSRC_CRBC_CMD) "$(JRE_NONEXIST_LOCALES)" $< $@
-
-GENSRC_LOCALEDATAMETAINFO += $(GENSRC_CRBC_DST)
-GENSRC_JAVA_BASE += $(GENSRC_LOCALEDATAMETAINFO)
-
-################################################################################
--- a/jdk/make/lib/Awt2dLibraries.gmk	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/make/lib/Awt2dLibraries.gmk	Wed Jul 05 20:01:50 2017 +0200
@@ -217,10 +217,8 @@
       -I$(JDK_OUTPUTDIR)/gensrc_headers/java.base \
       #
   LIBAWT_EXFILES += \
-      sun/java2d/d3d/D3DPipeline.cpp \
       sun/java2d/d3d/D3DShaderGen.c \
       sun/awt/image/cvutils/img_colors.c \
-      sun/windows/WBufferStrategy.cpp \
       #
 
   LIBAWT_LANG := C++
--- a/jdk/make/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/make/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java	Wed Jul 05 20:01:50 2017 +0200
@@ -143,8 +143,9 @@
 
     @Override
     public void generateMetaInfo(Map<String, SortedSet<String>> metaInfo) throws IOException {
-        String dirName = CLDRConverter.DESTINATION_DIR + File.separator + "sun" + File.separator + "util" + File.separator
-                + "cldr" + File.separator;
+        String dirName = CLDRConverter.DESTINATION_DIR + File.separator + "sun" + File.separator + "util" +
+            File.separator + "resources" + File.separator + "cldr" + File.separator +
+            "provider" + File.separator ;
         File dir = new File(dirName);
         if (!dir.exists()) {
             dir.mkdirs();
@@ -158,7 +159,7 @@
         try (PrintWriter out = new PrintWriter(file, "us-ascii")) {
             out.println(CopyrightHeaders.getOpenJDKCopyright());
 
-            out.println("package sun.util.cldr;\n\n"
+            out.println("package sun.util.resources.cldr.provider;\n\n"
                       + "import java.util.ListResourceBundle;\n"
                       + "import sun.util.locale.provider.LocaleProviderAdapter;\n"
                       + "import sun.util.locale.provider.LocaleDataMetaInfo;\n");
--- a/jdk/make/src/classes/build/tools/module/GenJdepsModulesXml.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/make/src/classes/build/tools/module/GenJdepsModulesXml.java	Wed Jul 05 20:01:50 2017 +0200
@@ -25,29 +25,17 @@
 
 package build.tools.module;
 
-import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
+import java.io.UncheckedIOException;
 import java.nio.file.Files;
 import java.nio.file.NoSuchFileException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.attribute.BasicFileAttributes;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Map;
-import java.util.Objects;
 import java.util.Set;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-import javax.xml.namespace.QName;
-import javax.xml.stream.*;
-import javax.xml.stream.events.Attribute;
-import javax.xml.stream.events.XMLEvent;
+import java.util.stream.Collectors;
 
 /**
  * GenJdepsModulesXml augments the input modules.xml file(s)
@@ -97,14 +85,14 @@
         Set<Module> modules = new HashSet<>();
         for (; i < args.length; i++) {
             Path p = Paths.get(args[i]);
-            try (InputStream in = new BufferedInputStream(Files.newInputStream(p))) {
-                Set<Module> mods = gentool.load(in);
-                modules.addAll(mods);
-            }
+            modules.addAll(ModulesXmlReader.readModules(p)
+                    .stream()
+                    .map(gentool::buildIncludes)
+                    .collect(Collectors.toSet()));
         }
 
         Files.createDirectories(outfile.getParent());
-        gentool.writeXML(modules, outfile);
+        ModulesXmlWriter.writeModules(modules, outfile);
     }
 
     final Path modulepath;
@@ -112,228 +100,21 @@
         this.modulepath = modulepath;
     }
 
-    private static final String MODULES   = "modules";
-    private static final String MODULE    = "module";
-    private static final String NAME      = "name";
-    private static final String DEPEND    = "depend";
-    private static final String EXPORT    = "export";
-    private static final String TO        = "to";
-    private static final String INCLUDE   = "include";
-    private static final QName  REEXPORTS = new QName("re-exports");
-    private Set<Module> load(InputStream in) throws XMLStreamException, IOException {
-        Set<Module> modules = new HashSet<>();
-        XMLInputFactory factory = XMLInputFactory.newInstance();
-        XMLEventReader stream = factory.createXMLEventReader(in);
-        Module.Builder mb = null;
-        String modulename = null;
-        String pkg = null;
-        Set<String> permits = new HashSet<>();
-        while (stream.hasNext()) {
-            XMLEvent event = stream.nextEvent();
-            if (event.isStartElement()) {
-                String startTag = event.asStartElement().getName().getLocalPart();
-                switch (startTag) {
-                    case MODULES:
-                        break;
-                    case MODULE:
-                        if (mb != null) {
-                            throw new RuntimeException("end tag for module is missing");
-                        }
-                        modulename = getNextTag(stream, NAME);
-                        mb = new Module.Builder();
-                        mb.name(modulename);
-                        break;
-                    case NAME:
-                        throw new RuntimeException(event.toString());
-                    case DEPEND:
-                        boolean reexports = false;
-                        Attribute attr = event.asStartElement().getAttributeByName(REEXPORTS);
-                        if (attr != null) {
-                            String value = attr.getValue();
-                            if (value.equals("true") || value.equals("false")) {
-                                reexports = Boolean.parseBoolean(value);
-                            } else {
-                                throw new RuntimeException("unexpected attribute " + attr.toString());
-                            }
-                        }
-                        mb.require(getData(stream), reexports);
-                        break;
-                    case INCLUDE:
-                        throw new RuntimeException("unexpected " + event);
-                    case EXPORT:
-                        pkg = getNextTag(stream, NAME);
-                        break;
-                    case TO:
-                        permits.add(getData(stream));
-                        break;
-                    default:
-                }
-            } else if (event.isEndElement()) {
-                String endTag = event.asEndElement().getName().getLocalPart();
-                switch (endTag) {
-                    case MODULE:
-                        buildIncludes(mb, modulename);
-                        modules.add(mb.build());
-                        mb = null;
-                        break;
-                    case EXPORT:
-                        if (pkg == null) {
-                            throw new RuntimeException("export-to is malformed");
-                        }
-                        mb.exportTo(pkg, permits);
-                        pkg = null;
-                        permits.clear();
-                        break;
-                    default:
-                }
-            } else if (event.isCharacters()) {
-                String s = event.asCharacters().getData();
-                if (!s.trim().isEmpty()) {
-                    throw new RuntimeException("export-to is malformed");
-                }
-            }
-        }
-        return modules;
-    }
-
-    private String getData(XMLEventReader reader) throws XMLStreamException {
-        XMLEvent e = reader.nextEvent();
-        if (e.isCharacters()) {
-            return e.asCharacters().getData();
-        }
-        throw new RuntimeException(e.toString());
-    }
-
-    private String getNextTag(XMLEventReader reader, String tag) throws XMLStreamException {
-        XMLEvent e = reader.nextTag();
-        if (e.isStartElement()) {
-            String t = e.asStartElement().getName().getLocalPart();
-            if (!tag.equals(t)) {
-                throw new RuntimeException(e + " expected: " + tag);
-            }
-            return getData(reader);
-        }
-        throw new RuntimeException("export-to name is missing:" + e);
-    }
-    private void writeXML(Set<Module> modules, Path path)
-            throws IOException, XMLStreamException
-    {
-        XMLOutputFactory xof = XMLOutputFactory.newInstance();
-        try (OutputStream out = Files.newOutputStream(path)) {
-            int depth = 0;
-            XMLStreamWriter xtw = xof.createXMLStreamWriter(out, "UTF-8");
-            xtw.writeStartDocument("utf-8","1.0");
-            writeStartElement(xtw, MODULES, depth);
-            modules.stream()
-                   .sorted(Comparator.comparing(Module::name))
-                   .forEach(m -> writeModuleElement(xtw, m, depth+1));
-            writeEndElement(xtw, depth);
-            xtw.writeCharacters("\n");
-            xtw.writeEndDocument();
-            xtw.flush();
-            xtw.close();
-        }
-    }
-
-    private void writeElement(XMLStreamWriter xtw, String element, String value, int depth) {
-        try {
-            writeStartElement(xtw, element, depth);
-            xtw.writeCharacters(value);
-            xtw.writeEndElement();
-        } catch (XMLStreamException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    private void writeDependElement(XMLStreamWriter xtw, Module.Dependence d, int depth) {
-        try {
-            writeStartElement(xtw, DEPEND, depth);
-            if (d.reexport) {
-                xtw.writeAttribute("re-exports", "true");
-            }
-            xtw.writeCharacters(d.name);
-            xtw.writeEndElement();
-        } catch (XMLStreamException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    private void writeExportElement(XMLStreamWriter xtw, String pkg, int depth) {
-        writeExportElement(xtw, pkg, Collections.emptySet(), depth);
-    }
-
-    private void writeExportElement(XMLStreamWriter xtw, String pkg,
-                                    Set<String> permits, int depth) {
-        try {
-            writeStartElement(xtw, EXPORT, depth);
-            writeElement(xtw, NAME, pkg, depth+1);
-            if (!permits.isEmpty()) {
-                permits.stream().sorted()
-                       .forEach(m -> writeElement(xtw, TO, m, depth + 1));
-            }
-            writeEndElement(xtw, depth);
-        } catch (XMLStreamException e) {
-            throw new RuntimeException(e);
-        }
-    }
-    private void writeModuleElement(XMLStreamWriter xtw, Module m, int depth) {
-        try {
-            writeStartElement(xtw, MODULE, depth);
-            writeElement(xtw, NAME, m.name(), depth+1);
-            m.requires().stream().sorted(Comparator.comparing(d -> d.name))
-                        .forEach(d -> writeDependElement(xtw, d, depth+1));
-            m.exports().keySet().stream()
-                       .filter(pn -> m.exports().get(pn).isEmpty())
-                       .sorted()
-                       .forEach(pn -> writeExportElement(xtw, pn, depth+1));
-            m.exports().entrySet().stream()
-                       .filter(e -> !e.getValue().isEmpty())
-                       .sorted(Map.Entry.comparingByKey())
-                       .forEach(e -> writeExportElement(xtw, e.getKey(), e.getValue(), depth+1));
-            m.packages().stream().sorted()
-                        .forEach(p -> writeElement(xtw, INCLUDE, p, depth+1));
-            writeEndElement(xtw, depth);
-        } catch (XMLStreamException e) {
-            throw new RuntimeException(e);
-
-        }
-    }
-
-    /** Two spaces; the default indentation. */
-    public static final String DEFAULT_INDENT = "  ";
-
-    /** stack[depth] indicates what's been written into the current scope. */
-    private static String[] stack = new String[] { "\n",
-        "\n" + DEFAULT_INDENT,
-        "\n" + DEFAULT_INDENT + DEFAULT_INDENT,
-        "\n" + DEFAULT_INDENT + DEFAULT_INDENT + DEFAULT_INDENT};
-
-    private void writeStartElement(XMLStreamWriter xtw, String name, int depth)
-            throws XMLStreamException
-    {
-        xtw.writeCharacters(stack[depth]);
-        xtw.writeStartElement(name);
-    }
-
-    private void writeEndElement(XMLStreamWriter xtw, int depth) throws XMLStreamException {
-        xtw.writeCharacters(stack[depth]);
-        xtw.writeEndElement();
-    }
-
-    private String packageName(Path p) {
+    private static String packageName(Path p) {
         return packageName(p.toString().replace(File.separatorChar, '/'));
     }
-    private String packageName(String name) {
+    private static String packageName(String name) {
         int i = name.lastIndexOf('/');
         return (i > 0) ? name.substring(0, i).replace('/', '.') : "";
     }
 
-    private boolean includes(String name) {
-        return name.endsWith(".class") && !name.equals("module-info.class");
+    private static boolean includes(String name) {
+        return name.endsWith(".class");
     }
 
-    public void buildIncludes(Module.Builder mb, String modulename) throws IOException {
-        Path mclasses = modulepath.resolve(modulename);
+    public Module buildIncludes(Module module) {
+        Module.Builder mb = new Module.Builder(module);
+        Path mclasses = modulepath.resolve(module.name());
         try {
             Files.find(mclasses, Integer.MAX_VALUE, (Path p, BasicFileAttributes attr)
                          -> includes(p.getFileName().toString()))
@@ -341,145 +122,9 @@
                  .forEach(mb::include);
         } catch (NoSuchFileException e) {
             // aggregate module may not have class
-        }
-    }
-
-    static class Module {
-        static class Dependence {
-            final String name;
-            final boolean reexport;
-            Dependence(String name) {
-                this(name, false);
-            }
-            Dependence(String name, boolean reexport) {
-                this.name = name;
-                this.reexport = reexport;
-            }
-
-            @Override
-            public int hashCode() {
-                int hash = 5;
-                hash = 11 * hash + Objects.hashCode(this.name);
-                hash = 11 * hash + (this.reexport ? 1 : 0);
-                return hash;
-            }
-
-            public boolean equals(Object o) {
-                Dependence d = (Dependence)o;
-                return this.name.equals(d.name) && this.reexport == d.reexport;
-            }
-        }
-        private final String moduleName;
-        private final Set<Dependence> requires;
-        private final Map<String, Set<String>> exports;
-        private final Set<String> packages;
-
-        private Module(String name,
-                Set<Dependence> requires,
-                Map<String, Set<String>> exports,
-                Set<String> packages) {
-            this.moduleName = name;
-            this.requires = Collections.unmodifiableSet(requires);
-            this.exports = Collections.unmodifiableMap(exports);
-            this.packages = Collections.unmodifiableSet(packages);
-        }
-
-        public String name() {
-            return moduleName;
-        }
-
-        public Set<Dependence> requires() {
-            return requires;
-        }
-
-        public Map<String, Set<String>> exports() {
-            return exports;
-        }
-
-        public Set<String> packages() {
-            return packages;
-        }
-
-        @Override
-        public boolean equals(Object ob) {
-            if (!(ob instanceof Module)) {
-                return false;
-            }
-            Module that = (Module) ob;
-            return (moduleName.equals(that.moduleName)
-                    && requires.equals(that.requires)
-                    && exports.equals(that.exports)
-                    && packages.equals(that.packages));
+        } catch (IOException ioe) {
+            throw new UncheckedIOException(ioe);
         }
-
-        @Override
-        public int hashCode() {
-            int hc = moduleName.hashCode();
-            hc = hc * 43 + requires.hashCode();
-            hc = hc * 43 + exports.hashCode();
-            hc = hc * 43 + packages.hashCode();
-            return hc;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder sb = new StringBuilder();
-            sb.append("module ").append(moduleName).append(" {").append("\n");
-            requires.stream().sorted().forEach(d ->
-                    sb.append(String.format("   requires %s%s%n", d.reexport ? "public " : "", d.name)));
-            exports.entrySet().stream().filter(e -> e.getValue().isEmpty())
-                    .sorted(Map.Entry.comparingByKey())
-                    .forEach(e -> sb.append(String.format("   exports %s%n", e.getKey())));
-            exports.entrySet().stream().filter(e -> !e.getValue().isEmpty())
-                    .sorted(Map.Entry.comparingByKey())
-                    .forEach(e -> sb.append(String.format("   exports %s to %s%n", e.getKey(), e.getValue())));
-            packages.stream().sorted().forEach(pn -> sb.append(String.format("   includes %s%n", pn)));
-            sb.append("}");
-            return sb.toString();
-        }
-
-        static class Builder {
-            private String name;
-            private final Set<Dependence> requires = new HashSet<>();
-            private final Map<String, Set<String>> exports = new HashMap<>();
-            private final Set<String> packages = new HashSet<>();
-
-            public Builder() {
-            }
-
-            public Builder name(String n) {
-                name = n;
-                return this;
-            }
-
-            public Builder require(String d, boolean reexport) {
-                requires.add(new Dependence(d, reexport));
-                return this;
-            }
-
-            public Builder include(String p) {
-                packages.add(p);
-                return this;
-            }
-
-            public Builder export(String p) {
-                return exportTo(p, Collections.emptySet());
-            }
-
-            public Builder exportTo(String p, Set<String> ms) {
-                Objects.requireNonNull(p);
-                Objects.requireNonNull(ms);
-                if (exports.containsKey(p)) {
-                    throw new RuntimeException(name + " already exports " + p);
-                }
-                exports.put(p, new HashSet<>(ms));
-                return this;
-            }
-
-            public Module build() {
-                Module m = new Module(name, requires, exports, packages);
-                return m;
-            }
-        }
+        return mb.build();
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/src/classes/build/tools/module/GenModulesList.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package build.tools.module;
+
+import java.io.PrintWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * $ java build.tools.module.GenModulesList \
+ *        -o modules.list \
+ *        top/modules.xml ...
+ */
+public final class GenModulesList {
+    private final static String USAGE =
+        "Usage: GenModulesList -o <output file> path-to-modules-xml";
+
+    private Set<Module> modules = new HashSet<>();
+    private HashMap<String,Module> nameToModule = new HashMap<>();
+
+    public static void main(String[] args) throws Exception {
+        GenModulesList gen = new GenModulesList();
+        gen.run(args);
+    }
+
+    void run(String[] args) throws Exception {
+        Path outfile = null;
+        int i = 0;
+        while (i < args.length) {
+            String arg = args[i];
+            if (arg.equals("-o")) {
+                outfile = Paths.get(args[i+1]);
+                i = i+2;
+            } else {
+                break;
+            }
+        }
+        if (outfile == null || i >= args.length) {
+            System.err.println(USAGE);
+            System.exit(-1);
+        }
+
+        for (; i < args.length; i++) {
+            Path p = Paths.get(args[i]);
+            modules.addAll(ModulesXmlReader.readModules(p));
+        }
+
+        modules.stream()
+               .forEach(m -> nameToModule.put(m.name(), m));
+
+        Path parent = outfile.getParent();
+        if (parent != null)
+            Files.createDirectories(parent);
+
+        Iterable<Module> sortedModules = (new TopoSorter(modules)).result();
+        try (PrintWriter writer = new PrintWriter(outfile.toFile())) {
+            for (Module m : sortedModules) {
+                if (isNotAggregator(m)) {
+                    String deps = getModuleDependences(m).stream()
+                            .filter(GenModulesList::isNotAggregator)
+                            .map(Module::name)
+                            .collect(Collectors.joining(" "));
+                    writer.format("%s: %s%n", m.name(), deps);
+                }
+            }
+        }
+    }
+
+    private Module nameToModule(String name) {
+        return nameToModule.get(name);
+    }
+
+    private Set<Module> getModuleDependences(Module m) {
+        return m.requires().stream()
+                .map(d -> d.name())
+                .map(this::nameToModule)
+                .collect(Collectors.toSet());
+    }
+
+    static boolean isNotAggregator(Module m) {
+        return isNotAggregator(m.name());
+    }
+
+    static boolean isNotAggregator(String name) {
+        return AGGREGATORS.contains(name) ? false : true;
+    }
+
+    static final List<String> AGGREGATORS = Arrays.asList(new String[] {
+            "java.se", "java.compact1", "java.compact2",
+            "java.compact3", "jdk.compact3"});
+
+    class TopoSorter {
+        final Deque<Module> result = new LinkedList<>();
+        final Deque<Module> nodes = new LinkedList<>();
+
+        TopoSorter(Collection<Module> nodes) {
+            nodes.stream()
+                 .forEach(m -> this.nodes.add(m));
+
+            sort();
+        }
+
+        public Iterable<Module> result() {
+            return result;
+        }
+
+        private void sort() {
+            Deque<Module> visited = new LinkedList<>();
+            Deque<Module> done = new LinkedList<>();
+            Module node;
+            while ((node = nodes.poll()) != null) {
+                if (!visited.contains(node)) {
+                    visit(node, visited, done);
+                }
+            }
+        }
+
+        private void visit(Module m, Deque<Module> visited, Deque<Module> done) {
+            if (visited.contains(m)) {
+                if (!done.contains(m)) {
+                    throw new IllegalArgumentException("Cyclic detected: " +
+                            m + " " + getModuleDependences(m));
+                }
+                return;
+            }
+            visited.add(m);
+            getModuleDependences(m).stream()
+                                   .forEach(x -> visit(x, visited, done));
+            done.add(m);
+            result.addLast(m);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/src/classes/build/tools/module/Module.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package build.tools.module;
+
+import java.util.*;
+
+public class Module {
+    static class Dependence {
+        final String name;
+        final boolean reexport;
+        Dependence(String name) {
+            this(name, false);
+        }
+        Dependence(String name, boolean reexport) {
+            this.name = name;
+            this.reexport = reexport;
+        }
+
+        public String name() {
+            return name;
+        }
+
+        @Override
+        public int hashCode() {
+            int hash = 5;
+            hash = 11 * hash + Objects.hashCode(this.name);
+            hash = 11 * hash + (this.reexport ? 1 : 0);
+            return hash;
+        }
+
+        public boolean equals(Object o) {
+            Dependence d = (Dependence)o;
+            return this.name.equals(d.name) && this.reexport == d.reexport;
+        }
+    }
+    private final String moduleName;
+    private final Set<Dependence> requires;
+    private final Map<String, Set<String>> exports;
+    private final Set<String> packages;
+
+    private Module(String name,
+            Set<Dependence> requires,
+            Map<String, Set<String>> exports,
+            Set<String> packages) {
+        this.moduleName = name;
+        this.requires = Collections.unmodifiableSet(requires);
+        this.exports = Collections.unmodifiableMap(exports);
+        this.packages = Collections.unmodifiableSet(packages);
+    }
+
+    public String name() {
+        return moduleName;
+    }
+
+    public Set<Dependence> requires() {
+        return requires;
+    }
+
+    public Map<String, Set<String>> exports() {
+        return exports;
+    }
+
+    public Set<String> packages() {
+        return packages;
+    }
+
+    @Override
+    public boolean equals(Object ob) {
+        if (!(ob instanceof Module)) {
+            return false;
+        }
+        Module that = (Module) ob;
+        return (moduleName.equals(that.moduleName)
+                && requires.equals(that.requires)
+                && exports.equals(that.exports)
+                && packages.equals(that.packages));
+    }
+
+    @Override
+    public int hashCode() {
+        int hc = moduleName.hashCode();
+        hc = hc * 43 + requires.hashCode();
+        hc = hc * 43 + exports.hashCode();
+        hc = hc * 43 + packages.hashCode();
+        return hc;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("module ").append(moduleName).append(" {").append("\n");
+        requires.stream().sorted().forEach(d ->
+                sb.append(String.format("   requires %s%s%n", d.reexport ? "public " : "", d.name)));
+        exports.entrySet().stream().filter(e -> e.getValue().isEmpty())
+                .sorted(Map.Entry.comparingByKey())
+                .forEach(e -> sb.append(String.format("   exports %s%n", e.getKey())));
+        exports.entrySet().stream().filter(e -> !e.getValue().isEmpty())
+                .sorted(Map.Entry.comparingByKey())
+                .forEach(e -> sb.append(String.format("   exports %s to %s%n", e.getKey(), e.getValue())));
+        packages.stream().sorted().forEach(pn -> sb.append(String.format("   includes %s%n", pn)));
+        sb.append("}");
+        return sb.toString();
+    }
+
+    static class Builder {
+        private String name;
+        private final Set<Dependence> requires = new HashSet<>();
+        private final Map<String, Set<String>> exports = new HashMap<>();
+        private final Set<String> packages = new HashSet<>();
+
+        public Builder() {
+        }
+
+        public Builder(Module module) {
+            name = module.name();
+            requires.addAll(module.requires());
+            exports.putAll(module.exports());
+            packages.addAll(module.packages());
+        }
+
+        public Builder name(String n) {
+            name = n;
+            return this;
+        }
+
+        public Builder require(String d, boolean reexport) {
+            requires.add(new Dependence(d, reexport));
+            return this;
+        }
+
+        public Builder include(String p) {
+            packages.add(p);
+            return this;
+        }
+
+        public Builder export(String p) {
+            return exportTo(p, Collections.emptySet());
+        }
+
+        public Builder exportTo(String p, Set<String> ms) {
+            Objects.requireNonNull(p);
+            Objects.requireNonNull(ms);
+            if (exports.containsKey(p)) {
+                throw new RuntimeException(name + " already exports " + p);
+            }
+            exports.put(p, new HashSet<>(ms));
+            return this;
+        }
+
+        public Module build() {
+            Module m = new Module(name, requires, exports, packages);
+            return m;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/src/classes/build/tools/module/ModulesXmlReader.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package build.tools.module;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.XMLEvent;
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.HashSet;
+import java.util.Set;
+
+public class ModulesXmlReader {
+
+    private ModulesXmlReader() {}
+
+    public static Set<Module> readModules(Path modulesXml)
+        throws XMLStreamException, IOException
+    {
+        Set<Module> modules = new HashSet<>();
+        try (InputStream in = new BufferedInputStream(Files.newInputStream(modulesXml))) {
+            Set<Module> mods = ModulesXmlReader.load(in);
+            modules.addAll(mods);
+        }
+        return modules;
+    }
+
+    private static final String MODULES   = "modules";
+    private static final String MODULE    = "module";
+    private static final String NAME      = "name";
+    private static final String DEPEND    = "depend";
+    private static final String EXPORT    = "export";
+    private static final String TO        = "to";
+    private static final String INCLUDE   = "include";
+    private static final QName  REEXPORTS = new QName("re-exports");
+    private static Set<Module> load(InputStream in)
+        throws XMLStreamException, IOException
+    {
+        Set<Module> modules = new HashSet<>();
+        XMLInputFactory factory = XMLInputFactory.newInstance();
+        XMLEventReader stream = factory.createXMLEventReader(in);
+        Module.Builder mb = null;
+        String modulename = null;
+        String pkg = null;
+        Set<String> permits = new HashSet<>();
+        while (stream.hasNext()) {
+            XMLEvent event = stream.nextEvent();
+            if (event.isStartElement()) {
+                String startTag = event.asStartElement().getName().getLocalPart();
+                switch (startTag) {
+                    case MODULES:
+                        break;
+                    case MODULE:
+                        if (mb != null) {
+                            throw new RuntimeException("end tag for module is missing");
+                        }
+                        modulename = getNextTag(stream, NAME);
+                        mb = new Module.Builder();
+                        mb.name(modulename);
+                        break;
+                    case NAME:
+                        throw new RuntimeException(event.toString());
+                    case DEPEND:
+                        boolean reexports = false;
+                        Attribute attr = event.asStartElement().getAttributeByName(REEXPORTS);
+                        if (attr != null) {
+                            String value = attr.getValue();
+                            if (value.equals("true") || value.equals("false")) {
+                                reexports = Boolean.parseBoolean(value);
+                            } else {
+                                throw new RuntimeException("unexpected attribute " + attr.toString());
+                            }
+                        }
+                        mb.require(getData(stream), reexports);
+                        break;
+                    case INCLUDE:
+                        throw new RuntimeException("unexpected " + event);
+                    case EXPORT:
+                        pkg = getNextTag(stream, NAME);
+                        break;
+                    case TO:
+                        permits.add(getData(stream));
+                        break;
+                    default:
+                }
+            } else if (event.isEndElement()) {
+                String endTag = event.asEndElement().getName().getLocalPart();
+                switch (endTag) {
+                    case MODULE:
+                        modules.add(mb.build());
+                        mb = null;
+                        break;
+                    case EXPORT:
+                        if (pkg == null) {
+                            throw new RuntimeException("export-to is malformed");
+                        }
+                        mb.exportTo(pkg, permits);
+                        pkg = null;
+                        permits.clear();
+                        break;
+                    default:
+                }
+            } else if (event.isCharacters()) {
+                String s = event.asCharacters().getData();
+                if (!s.trim().isEmpty()) {
+                    throw new RuntimeException("export-to is malformed");
+                }
+            }
+        }
+        return modules;
+    }
+
+    private static String getData(XMLEventReader reader)
+        throws XMLStreamException
+    {
+        XMLEvent e = reader.nextEvent();
+        if (e.isCharacters())
+            return e.asCharacters().getData();
+
+        throw new RuntimeException(e.toString());
+    }
+
+    private static String getNextTag(XMLEventReader reader, String tag)
+        throws XMLStreamException
+    {
+        XMLEvent e = reader.nextTag();
+        if (e.isStartElement()) {
+            String t = e.asStartElement().getName().getLocalPart();
+            if (!tag.equals(t)) {
+                throw new RuntimeException(e + " expected: " + tag);
+            }
+            return getData(reader);
+        }
+        throw new RuntimeException("export-to name is missing:" + e);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/src/classes/build/tools/module/ModulesXmlWriter.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package build.tools.module;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Map;
+import java.util.Set;
+
+public final class ModulesXmlWriter {
+
+    private ModulesXmlWriter() {}
+
+    public static void writeModules(Set<Module> modules, Path path)
+        throws IOException, XMLStreamException
+    {
+        writeXML(modules, path);
+    }
+
+    private static final String MODULES   = "modules";
+    private static final String MODULE    = "module";
+    private static final String NAME      = "name";
+    private static final String DEPEND    = "depend";
+    private static final String EXPORT    = "export";
+    private static final String TO        = "to";
+    private static final String INCLUDE   = "include";
+    private static final QName  REEXPORTS = new QName("re-exports");
+
+    private static void writeXML(Set<Module> modules, Path path)
+        throws IOException, XMLStreamException
+    {
+        XMLOutputFactory xof = XMLOutputFactory.newInstance();
+        try (OutputStream out = Files.newOutputStream(path)) {
+            int depth = 0;
+            XMLStreamWriter xtw = xof.createXMLStreamWriter(out, "UTF-8");
+            xtw.writeStartDocument("utf-8","1.0");
+            writeStartElement(xtw, MODULES, depth);
+            modules.stream()
+                   .sorted(Comparator.comparing(Module::name))
+                   .forEach(m -> writeModuleElement(xtw, m, depth+1));
+            writeEndElement(xtw, depth);
+            xtw.writeCharacters("\n");
+            xtw.writeEndDocument();
+            xtw.flush();
+            xtw.close();
+        }
+    }
+
+    private static void writeElement(XMLStreamWriter xtw,
+                                     String element,
+                                     String value,
+                                     int depth) {
+        try {
+            writeStartElement(xtw, element, depth);
+            xtw.writeCharacters(value);
+            xtw.writeEndElement();
+        } catch (XMLStreamException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static void writeDependElement(XMLStreamWriter xtw,
+                                           Module.Dependence d,
+                                           int depth) {
+        try {
+            writeStartElement(xtw, DEPEND, depth);
+            if (d.reexport) {
+                xtw.writeAttribute("re-exports", "true");
+            }
+            xtw.writeCharacters(d.name);
+            xtw.writeEndElement();
+        } catch (XMLStreamException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static void writeExportElement(XMLStreamWriter xtw,
+                                           String pkg,
+                                           int depth) {
+        writeExportElement(xtw, pkg, Collections.emptySet(), depth);
+    }
+
+    private static void writeExportElement(XMLStreamWriter xtw,
+                                           String pkg,
+                                           Set<String> permits,
+                                           int depth) {
+        try {
+            writeStartElement(xtw, EXPORT, depth);
+            writeElement(xtw, NAME, pkg, depth+1);
+            if (!permits.isEmpty()) {
+                permits.stream().sorted()
+                       .forEach(m -> writeElement(xtw, TO, m, depth + 1));
+            }
+            writeEndElement(xtw, depth);
+        } catch (XMLStreamException e) {
+            throw new RuntimeException(e);
+        }
+    }
+    private static void writeModuleElement(XMLStreamWriter xtw,
+                                           Module m,
+                                           int depth) {
+        try {
+            writeStartElement(xtw, MODULE, depth);
+            writeElement(xtw, NAME, m.name(), depth+1);
+            m.requires().stream().sorted(Comparator.comparing(d -> d.name))
+                        .forEach(d -> writeDependElement(xtw, d, depth+1));
+            m.exports().keySet().stream()
+                       .filter(pn -> m.exports().get(pn).isEmpty())
+                       .sorted()
+                       .forEach(pn -> writeExportElement(xtw, pn, depth+1));
+            m.exports().entrySet().stream()
+                       .filter(e -> !e.getValue().isEmpty())
+                       .sorted(Map.Entry.comparingByKey())
+                       .forEach(e -> writeExportElement(xtw, e.getKey(), e.getValue(), depth+1));
+            m.packages().stream().sorted()
+                        .forEach(p -> writeElement(xtw, INCLUDE, p, depth+1));
+            writeEndElement(xtw, depth);
+        } catch (XMLStreamException e) {
+            throw new RuntimeException(e);
+
+        }
+    }
+
+    /** Two spaces; the default indentation. */
+    public static final String DEFAULT_INDENT = "  ";
+
+    /** stack[depth] indicates what's been written into the current scope. */
+    private static String[] stack = new String[] { "\n",
+        "\n" + DEFAULT_INDENT,
+        "\n" + DEFAULT_INDENT + DEFAULT_INDENT,
+        "\n" + DEFAULT_INDENT + DEFAULT_INDENT + DEFAULT_INDENT};
+
+    private static void writeStartElement(XMLStreamWriter xtw,
+                                          String name,
+                                          int depth)
+        throws XMLStreamException
+    {
+        xtw.writeCharacters(stack[depth]);
+        xtw.writeStartElement(name);
+    }
+
+    private static void writeEndElement(XMLStreamWriter xtw, int depth)
+        throws XMLStreamException
+    {
+        xtw.writeCharacters(stack[depth]);
+        xtw.writeEndElement();
+    }
+}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Wed Jul 05 20:01:50 2017 +0200
@@ -62,7 +62,7 @@
     private static final String CLL_SIG = "(L" + CLS + ";L" + OBJ + ";)L" + OBJ + ";";
 
     /** Name of its super class*/
-    private static final String superName = LF;
+    private static final String superName = OBJ;
 
     /** Name of new class */
     private final String className;
@@ -97,7 +97,7 @@
         if (DUMP_CLASS_FILES) {
             className = makeDumpableClassName(className);
         }
-        this.className  = superName + "$" + className;
+        this.className  = LF + "$" + className;
         this.sourceFile = "LambdaForm$" + className;
         this.lambdaForm = lambdaForm;
         this.invokerName = invokerName;
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Wed Jul 05 20:01:50 2017 +0200
@@ -188,7 +188,6 @@
     static MethodHandle makePairwiseConvert(MethodHandle target, MethodType srcType,
                                             boolean strict, boolean monobox) {
         MethodType dstType = target.type();
-        assert(dstType.parameterCount() == target.type().parameterCount());
         if (srcType == dstType)
             return target;
         if (USE_LAMBDA_FORM_EDITOR) {
@@ -265,6 +264,7 @@
 
     static MethodHandle makePairwiseConvertIndirect(MethodHandle target, MethodType srcType,
                                                     boolean strict, boolean monobox) {
+        assert(target.type().parameterCount() == srcType.parameterCount());
         // Calculate extra arguments (temporaries) required in the names array.
         Object[] convSpecs = computeValueConversions(srcType, target.type(), strict, monobox);
         final int INARG_COUNT = srcType.parameterCount();
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Wed Jul 05 20:01:50 2017 +0200
@@ -2023,8 +2023,9 @@
      */
     public static
     MethodHandle explicitCastArguments(MethodHandle target, MethodType newType) {
+        explicitCastArgumentsChecks(target, newType);
+        // use the asTypeCache when possible:
         MethodType oldType = target.type();
-        // use the asTypeCache when possible:
         if (oldType == newType)  return target;
         if (oldType.explicitCastEquivalentToAsType(newType)) {
             return target.asType(newType);
@@ -2032,6 +2033,12 @@
         return MethodHandleImpl.makePairwiseConvert(target, newType, false);
     }
 
+    private static void explicitCastArgumentsChecks(MethodHandle target, MethodType newType) {
+        if (target.type().parameterCount() != newType.parameterCount()) {
+            throw new WrongMethodTypeException("cannot explicitly cast " + target + " to " + newType);
+        }
+    }
+
     /**
      * Produces a method handle which adapts the calling sequence of the
      * given method handle to a new type, by reordering the arguments.
@@ -2164,7 +2171,7 @@
                 // dropIdx is missing from reorder; add it in at the end
                 int oldArity = reorder.length;
                 target = dropArguments(target, oldArity, newType.parameterType(dropIdx));
-                reorder = Arrays.copyOf(reorder, oldArity+1);
+                reorder = Arrays.copyOf(reorder, oldArity + 1);
                 reorder[oldArity] = dropIdx;
             }
             assert(target == originalTarget || permuteArgumentChecks(reorder, newType, target.type()));
@@ -2182,9 +2189,9 @@
             long mask = 0;
             for (int arg : reorder) {
                 assert(arg < newArity);
-                mask |= (1 << arg);
+                mask |= (1L << arg);
             }
-            if (mask == (1 << newArity) - 1) {
+            if (mask == (1L << newArity) - 1) {
                 assert(Long.numberOfTrailingZeros(Long.lowestOneBit(~mask)) == newArity);
                 return -1;
             }
@@ -2193,16 +2200,18 @@
             int zeroPos = Long.numberOfTrailingZeros(zeroBit);
             assert(zeroPos < newArity);
             return zeroPos;
+        } else {
+            BitSet mask = new BitSet(newArity);
+            for (int arg : reorder) {
+                assert (arg < newArity);
+                mask.set(arg);
+            }
+            int zeroPos = mask.nextClearBit(0);
+            assert(zeroPos <= newArity);
+            if (zeroPos == newArity)
+                return -1;
+            return zeroPos;
         }
-        BitSet mask = new BitSet(newArity);
-        for (int arg : reorder) {
-            assert(arg < newArity);
-            mask.set(arg);
-        }
-        int zeroPos = mask.nextClearBit(0);
-        if (zeroPos == newArity)
-            return -1;
-        return zeroPos;
     }
 
     /**
@@ -2218,32 +2227,42 @@
             long mask = 0;
             for (int i = 0; i < reorder.length; i++) {
                 int arg = reorder[i];
-                if (arg >= newArity)  return reorder.length;
-                int bit = 1 << arg;
-                if ((mask & bit) != 0)
+                if (arg >= newArity) {
+                    return reorder.length;
+                }
+                long bit = 1L << arg;
+                if ((mask & bit) != 0) {
                     return i;  // >0 indicates a dup
+                }
                 mask |= bit;
             }
-            if (mask == (1 << newArity) - 1) {
+            if (mask == (1L << newArity) - 1) {
                 assert(Long.numberOfTrailingZeros(Long.lowestOneBit(~mask)) == newArity);
                 return 0;
             }
             // find first zero
             long zeroBit = Long.lowestOneBit(~mask);
             int zeroPos = Long.numberOfTrailingZeros(zeroBit);
-            assert(zeroPos < newArity);
+            assert(zeroPos <= newArity);
+            if (zeroPos == newArity) {
+                return 0;
+            }
             return ~zeroPos;
         } else {
             // same algorithm, different bit set
             BitSet mask = new BitSet(newArity);
             for (int i = 0; i < reorder.length; i++) {
                 int arg = reorder[i];
-                if (arg >= newArity)  return reorder.length;
-                if (mask.get(arg))
+                if (arg >= newArity) {
+                    return reorder.length;
+                }
+                if (mask.get(arg)) {
                     return i;  // >0 indicates a dup
+                }
                 mask.set(arg);
             }
             int zeroPos = mask.nextClearBit(0);
+            assert(zeroPos <= newArity);
             if (zeroPos == newArity) {
                 return 0;
             }
@@ -2479,6 +2498,7 @@
     MethodHandle dropArguments(MethodHandle target, int pos, List<Class<?>> valueTypes) {
         MethodType oldType = target.type();  // get NPE
         int dropped = dropArgumentChecks(oldType, pos, valueTypes);
+        MethodType newType = oldType.insertParameterTypes(pos, valueTypes);
         if (dropped == 0)  return target;
         BoundMethodHandle result = target.rebind();
         LambdaForm lform = result.form;
@@ -2490,7 +2510,6 @@
         } else {
             lform = lform.addArguments(pos, valueTypes);
         }
-        MethodType newType = oldType.insertParameterTypes(pos, valueTypes);
         result = result.copyWith(newType, lform);
         return result;
     }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java	Wed Jul 05 20:01:50 2017 +0200
@@ -869,9 +869,7 @@
         if (dstTypes == srcTypes) {
             return true;
         }
-        if (dstTypes.length != srcTypes.length) {
-            return false;
-        }
+        assert(dstTypes.length == srcTypes.length);
         for (int i = 0; i < dstTypes.length; i++) {
             if (!explicitCastEquivalentToAsType(srcTypes[i], dstTypes[i])) {
                 return false;
--- a/jdk/src/java.base/share/classes/java/math/MutableBigInteger.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/math/MutableBigInteger.java	Wed Jul 05 20:01:50 2017 +0200
@@ -1261,19 +1261,20 @@
             int sigma = (int) Math.max(0, n32 - b.bitLength());   // step 3: sigma = max{T | (2^T)*B < beta^n}
             MutableBigInteger bShifted = new MutableBigInteger(b);
             bShifted.safeLeftShift(sigma);   // step 4a: shift b so its length is a multiple of n
-            safeLeftShift(sigma);     // step 4b: shift this by the same amount
+            MutableBigInteger aShifted = new MutableBigInteger (this);
+            aShifted.safeLeftShift(sigma);     // step 4b: shift a by the same amount
 
-            // step 5: t is the number of blocks needed to accommodate this plus one additional bit
-            int t = (int) ((bitLength()+n32) / n32);
+            // step 5: t is the number of blocks needed to accommodate a plus one additional bit
+            int t = (int) ((aShifted.bitLength()+n32) / n32);
             if (t < 2) {
                 t = 2;
             }
 
-            // step 6: conceptually split this into blocks a[t-1], ..., a[0]
-            MutableBigInteger a1 = getBlock(t-1, t, n);   // the most significant block of this
+            // step 6: conceptually split a into blocks a[t-1], ..., a[0]
+            MutableBigInteger a1 = aShifted.getBlock(t-1, t, n);   // the most significant block of a
 
             // step 7: z[t-2] = [a[t-1], a[t-2]]
-            MutableBigInteger z = getBlock(t-2, t, n);    // the second to most significant block
+            MutableBigInteger z = aShifted.getBlock(t-2, t, n);    // the second to most significant block
             z.addDisjoint(a1, n);   // z[t-2]
 
             // do schoolbook division on blocks, dividing 2-block numbers by 1-block numbers
@@ -1284,7 +1285,7 @@
                 ri = z.divide2n1n(bShifted, qi);
 
                 // step 8b: z = [ri, a[i-1]]
-                z = getBlock(i-1, t, n);   // a[i-1]
+                z = aShifted.getBlock(i-1, t, n);   // a[i-1]
                 z.addDisjoint(ri, n);
                 quotient.addShifted(qi, i*n);   // update q (part of step 9)
             }
@@ -1292,7 +1293,7 @@
             ri = z.divide2n1n(bShifted, qi);
             quotient.add(qi);
 
-            ri.rightShift(sigma);   // step 9: this and b were shifted, so shift back
+            ri.rightShift(sigma);   // step 9: a and b were shifted, so shift back
             return ri;
         }
     }
--- a/jdk/src/java.base/share/classes/java/util/zip/ZipInputStream.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/util/zip/ZipInputStream.java	Wed Jul 05 20:01:50 2017 +0200
@@ -336,8 +336,21 @@
         return new ZipEntry(name);
     }
 
-    /*
+    /**
      * Reads end of deflated entry as well as EXT descriptor if present.
+     *
+     * Local headers for DEFLATED entries may optionally be followed by a
+     * data descriptor, and that data descriptor may optionally contain a
+     * leading signature (EXTSIG).
+     *
+     * From the zip spec http://www.pkware.com/documents/casestudies/APPNOTE.TXT
+     *
+     * """Although not originally assigned a signature, the value 0x08074b50
+     * has commonly been adopted as a signature value for the data descriptor
+     * record.  Implementers should be aware that ZIP files may be
+     * encountered with or without this signature marking data descriptors
+     * and should account for either case when reading ZIP files to ensure
+     * compatibility."""
      */
     private void readEnd(ZipEntry e) throws IOException {
         int n = inf.getRemaining();
@@ -356,7 +369,7 @@
                     e.csize = get64(tmpbuf, ZIP64_EXTSIZ - ZIP64_EXTCRC);
                     e.size = get64(tmpbuf, ZIP64_EXTLEN - ZIP64_EXTCRC);
                     ((PushbackInputStream)in).unread(
-                        tmpbuf, ZIP64_EXTHDR - ZIP64_EXTCRC - 1, ZIP64_EXTCRC);
+                        tmpbuf, ZIP64_EXTHDR - ZIP64_EXTCRC, ZIP64_EXTCRC);
                 } else {
                     e.crc = get32(tmpbuf, ZIP64_EXTCRC);
                     e.csize = get64(tmpbuf, ZIP64_EXTSIZ);
@@ -370,7 +383,7 @@
                     e.csize = get32(tmpbuf, EXTSIZ - EXTCRC);
                     e.size = get32(tmpbuf, EXTLEN - EXTCRC);
                     ((PushbackInputStream)in).unread(
-                                               tmpbuf, EXTHDR - EXTCRC - 1, EXTCRC);
+                                               tmpbuf, EXTHDR - EXTCRC, EXTCRC);
                 } else {
                     e.crc = get32(tmpbuf, EXTCRC);
                     e.csize = get32(tmpbuf, EXTSIZ);
--- a/jdk/src/java.base/unix/native/libnio/ch/FileDispatcherImpl.c	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.base/unix/native/libnio/ch/FileDispatcherImpl.c	Wed Jul 05 20:01:50 2017 +0200
@@ -34,6 +34,10 @@
 #include <fcntl.h>
 #include <sys/uio.h>
 #include <unistd.h>
+#if defined(__linux__)
+#include <linux/fs.h>
+#include <sys/ioctl.h>
+#endif
 #include "nio.h"
 #include "nio_util.h"
 
@@ -177,10 +181,21 @@
 JNIEXPORT jlong JNICALL
 Java_sun_nio_ch_FileDispatcherImpl_size0(JNIEnv *env, jobject this, jobject fdo)
 {
+    jint fd = fdval(env, fdo);
     struct stat64 fbuf;
 
-    if (fstat64(fdval(env, fdo), &fbuf) < 0)
+    if (fstat64(fd, &fbuf) < 0)
         return handle(env, -1, "Size failed");
+
+#ifdef BLKGETSIZE64
+    if (S_ISBLK(fbuf.st_mode)) {
+        uint64_t size;
+        if (ioctl(fd, BLKGETSIZE64, &size) < 0)
+            return handle(env, -1, "Size failed");
+        return (jlong)size;
+    }
+#endif
+
     return fbuf.st_size;
 }
 
--- a/jdk/src/java.base/windows/native/libnet/NetworkInterface.c	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.base/windows/native/libnet/NetworkInterface.c	Wed Jul 05 20:01:50 2017 +0200
@@ -990,9 +990,11 @@
       case MIB_IF_TYPE_FDDI:
       case IF_TYPE_IEEE80211:
         len = ifRowP->dwPhysAddrLen;
-        ret = (*env)->NewByteArray(env, len);
-        if (!IS_NULL(ret)) {
-          (*env)->SetByteArrayRegion(env, ret, 0, len, (jbyte *) ifRowP->bPhysAddr);
+        if (len > 0) {
+            ret = (*env)->NewByteArray(env, len);
+            if (!IS_NULL(ret)) {
+              (*env)->SetByteArrayRegion(env, ret, 0, len, (jbyte *) ifRowP->bPhysAddr);
+            }
         }
         break;
       }
--- a/jdk/src/java.desktop/macosx/classes/sun/awt/datatransfer/flavormap.properties	Wed Jul 05 20:01:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-#
-# This properties file is used to initialize the default
-# java.awt.datatransfer.SystemFlavorMap. It contains the Mac OS X platform-specific,
-# default mappings between common Mac OS X selection atoms and platform-independent
-# MIME type strings, which will be converted into 
-# java.awt.datatransfer.DataFlavors.
-#
-# The standard format is:
-#
-# <native>=<MIME type>,<MIME type>, ...
-#
-# <native> should be a string identifier that the native platform will
-# recognize as a valid data format. <MIME type> should specify both a MIME
-# primary type and a MIME subtype separated by a '/'. The MIME type may include
-# parameters, where each parameter is a key/value pair separated by '=', and
-# where each parameter to the MIME type is separated by a ';'.
-#
-# Because SystemFlavorMap implements FlavorTable, developers are free to
-# duplicate DataFlavor values and set multiple values for a single native by
-# separating them with ",". If a mapping contains a duplicate key or value,
-# earlier mappings which included this key or value will be preferred.
-#
-# Mappings whose values specify DataFlavors with primary MIME types of
-# "text", and which support the charset parameter, should specify the exact
-# format in which the native platform expects the data. The "charset"
-# parameter specifies the char to byte encoding, the "eoln" parameter
-# specifies the end-of-line marker, and the "terminators" parameter specifies
-# the number of terminating NUL bytes. Note that "eoln" and "terminators"
-# are not standardized MIME type parameters. They are specific to this file
-# format ONLY. They will not appear in any of the DataFlavors returned by the
-# SystemFlavorMap at the Java level.
-#
-# If the "charset" parameter is omitted, or has zero length, the platform
-# default encoding is assumed. If the "eoln" parameter is omitted, or has
-# zero length, "\n" is assumed. If the "terminators" parameter is omitted,
-# or has a value less than zero, zero is assumed.
-#
-# Upon initialization, the data transfer subsystem will record the specified
-# details of the native text format, but the default SystemFlavorMap will
-# present a large set of synthesized DataFlavors which map, in both
-# directions, to the native. After receiving data from the application in one
-# of the synthetic DataFlavors, the data transfer subsystem will transform
-# the data stream into the format specified in this file before passing the
-# transformed stream to the native system.
-#
-# Mappings whose values specify DataFlavors with primary MIME types of
-# "text", but which do not support the charset parameter, will be treated as
-# opaque, 8-bit data. They will not undergo any transformation process, and
-# any "charset", "eoln", or "terminators" parameters specified in this file
-# will be ignored.
-#
-# See java.awt.datatransfer.DataFlavor.selectBestTextFlavor for a list of
-# text flavors which support the charset parameter.
-
-UTF8_STRING=text/plain;charset=UTF-8;eoln="\n";terminators=0
-
-# The COMPOUND_TEXT support for inter-client text transfer is disabled by 
-# default. The reason is that many native applications prefer this format over 
-# other native text formats, but are unable to decode the textual data in this 
-# format properly. This results in java-to-native text transfer failures.
-# To enable the COMPOUND_TEXT support for this JRE installation uncomment 
-# the line below.
-
-# COMPOUND_TEXT=text/plain;charset=x-compound-text;eoln="\n";terminators=0
-
-TEXT=text/plain;eoln="\n";terminators=0
-STRING=text/plain;charset=UTF-8;eoln="\n";terminators=0
-FILE_NAME=application/x-java-file-list;class=java.util.List
-text/uri-list=application/x-java-file-list;class=java.util.List
-PNG=image/x-java-image;class=java.awt.Image
-JFIF=image/x-java-image;class=java.awt.Image
-TIFF=image/x-java-image;class=java.awt.Image
-RICH_TEXT=text/rtf
-HTML=text/html;charset=utf-8;eoln="\r\n";terminators=1
-URL=application/x-java-url;class=java.net.URL,\
-    text/uri-list;eoln="\r\n";terminators=1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/macosx/classes/sun/datatransfer/resources/flavormap.properties	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,76 @@
+#
+# This properties file is used to initialize the default
+# java.awt.datatransfer.SystemFlavorMap. It contains the Mac OS X platform-specific,
+# default mappings between common Mac OS X selection atoms and platform-independent
+# MIME type strings, which will be converted into 
+# java.awt.datatransfer.DataFlavors.
+#
+# The standard format is:
+#
+# <native>=<MIME type>,<MIME type>, ...
+#
+# <native> should be a string identifier that the native platform will
+# recognize as a valid data format. <MIME type> should specify both a MIME
+# primary type and a MIME subtype separated by a '/'. The MIME type may include
+# parameters, where each parameter is a key/value pair separated by '=', and
+# where each parameter to the MIME type is separated by a ';'.
+#
+# Because SystemFlavorMap implements FlavorTable, developers are free to
+# duplicate DataFlavor values and set multiple values for a single native by
+# separating them with ",". If a mapping contains a duplicate key or value,
+# earlier mappings which included this key or value will be preferred.
+#
+# Mappings whose values specify DataFlavors with primary MIME types of
+# "text", and which support the charset parameter, should specify the exact
+# format in which the native platform expects the data. The "charset"
+# parameter specifies the char to byte encoding, the "eoln" parameter
+# specifies the end-of-line marker, and the "terminators" parameter specifies
+# the number of terminating NUL bytes. Note that "eoln" and "terminators"
+# are not standardized MIME type parameters. They are specific to this file
+# format ONLY. They will not appear in any of the DataFlavors returned by the
+# SystemFlavorMap at the Java level.
+#
+# If the "charset" parameter is omitted, or has zero length, the platform
+# default encoding is assumed. If the "eoln" parameter is omitted, or has
+# zero length, "\n" is assumed. If the "terminators" parameter is omitted,
+# or has a value less than zero, zero is assumed.
+#
+# Upon initialization, the data transfer subsystem will record the specified
+# details of the native text format, but the default SystemFlavorMap will
+# present a large set of synthesized DataFlavors which map, in both
+# directions, to the native. After receiving data from the application in one
+# of the synthetic DataFlavors, the data transfer subsystem will transform
+# the data stream into the format specified in this file before passing the
+# transformed stream to the native system.
+#
+# Mappings whose values specify DataFlavors with primary MIME types of
+# "text", but which do not support the charset parameter, will be treated as
+# opaque, 8-bit data. They will not undergo any transformation process, and
+# any "charset", "eoln", or "terminators" parameters specified in this file
+# will be ignored.
+#
+# See java.awt.datatransfer.DataFlavor.selectBestTextFlavor for a list of
+# text flavors which support the charset parameter.
+
+UTF8_STRING=text/plain;charset=UTF-8;eoln="\n";terminators=0
+
+# The COMPOUND_TEXT support for inter-client text transfer is disabled by 
+# default. The reason is that many native applications prefer this format over 
+# other native text formats, but are unable to decode the textual data in this 
+# format properly. This results in java-to-native text transfer failures.
+# To enable the COMPOUND_TEXT support for this JRE installation uncomment 
+# the line below.
+
+# COMPOUND_TEXT=text/plain;charset=x-compound-text;eoln="\n";terminators=0
+
+TEXT=text/plain;eoln="\n";terminators=0
+STRING=text/plain;charset=UTF-8;eoln="\n";terminators=0
+FILE_NAME=application/x-java-file-list;class=java.util.List
+text/uri-list=application/x-java-file-list;class=java.util.List
+PNG=image/x-java-image;class=java.awt.Image
+JFIF=image/x-java-image;class=java.awt.Image
+TIFF=image/x-java-image;class=java.awt.Image
+RICH_TEXT=text/rtf
+HTML=text/html;charset=utf-8;eoln="\r\n";terminators=1
+URL=application/x-java-url;class=java.net.URL,\
+    text/uri-list;eoln="\r\n";terminators=1
--- a/jdk/src/java.desktop/share/classes/java/awt/event/InputMethodEvent.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.desktop/share/classes/java/awt/event/InputMethodEvent.java	Wed Jul 05 20:01:50 2017 +0200
@@ -418,7 +418,8 @@
     private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException {
         s.defaultReadObject();
         if (when == 0) {
-            when = getMostRecentEventTimeForSource(this.source);
+            // Can't use getMostRecentEventTimeForSource because source is always null during deserialization
+            when = EventQueue.getMostRecentEventTime();
         }
     }
 
--- a/jdk/src/java.desktop/share/classes/javax/swing/JDesktopPane.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JDesktopPane.java	Wed Jul 05 20:01:50 2017 +0200
@@ -43,6 +43,7 @@
 import java.beans.PropertyVetoException;
 import java.util.Set;
 import java.util.TreeSet;
+import java.util.LinkedHashSet;
 /**
  * A container used to create a multiple-document interface or a virtual desktop.
  * You create <code>JInternalFrame</code> objects and add them to the
@@ -271,7 +272,7 @@
 
     private static Collection<JInternalFrame> getAllFrames(Container parent) {
         int i, count;
-        Collection<JInternalFrame> results = new ArrayList<JInternalFrame>();
+        Collection<JInternalFrame> results = new LinkedHashSet<>();
         count = parent.getComponentCount();
         for (i = 0; i < count; i++) {
             Component next = parent.getComponent(i);
--- a/jdk/src/java.desktop/share/classes/sun/java2d/opengl/OGLSurfaceDataProxy.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/opengl/OGLSurfaceDataProxy.java	Wed Jul 05 20:01:50 2017 +0200
@@ -65,7 +65,11 @@
                                            int w, int h)
     {
         if (cachedData == null) {
-            cachedData = oglgc.createManagedSurface(w, h, transparency);
+            try {
+                cachedData = oglgc.createManagedSurface(w, h, transparency);
+            } catch (OutOfMemoryError er) {
+                return null;
+            }
         }
         return cachedData;
     }
--- a/jdk/src/java.desktop/share/native/libfontmanager/freetypeScaler.c	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.desktop/share/native/libfontmanager/freetypeScaler.c	Wed Jul 05 20:01:50 2017 +0200
@@ -1082,86 +1082,60 @@
         return 1;
 }
 
-static void addToGP(GPData* gpdata, FT_Outline*outline) {
-    jbyte current_type=SEG_UNKNOWN;
-    int i, j;
-    jfloat x, y;
+static void addSeg(GPData *gp, jbyte type) {
+    gp->pointTypes[gp->numTypes++] = type;
+}
+
+static void addCoords(GPData *gp, FT_Vector *p) {
+    gp->pointCoords[gp->numCoords++] =  F26Dot6ToFloat(p->x);
+    gp->pointCoords[gp->numCoords++] = -F26Dot6ToFloat(p->y);
+}
 
-    j = 0;
-    for(i=0; i<outline->n_points; i++) {
-        x =  F26Dot6ToFloat(outline->points[i].x);
-        y = -F26Dot6ToFloat(outline->points[i].y);
+static int moveTo(FT_Vector *to, GPData *gp) {
+    if (gp->numCoords)
+        addSeg(gp, SEG_CLOSE);
+    addCoords(gp, to);
+    addSeg(gp, SEG_MOVETO);
+    return FT_Err_Ok;
+}
+
+static int lineTo(FT_Vector *to, GPData *gp) {
+    addCoords(gp, to);
+    addSeg(gp, SEG_LINETO);
+    return FT_Err_Ok;
+}
 
-        if (FT_CURVE_TAG(outline->tags[i]) == FT_CURVE_TAG_ON) {
-            /* If bit 0 is unset, the point is "off" the curve,
-             i.e., a Bezier control point, while it is "on" when set. */
-            if (current_type == SEG_UNKNOWN) { /* special case:
-                                                  very first point */
-                /* add segment */
-                gpdata->pointTypes[gpdata->numTypes++] = SEG_MOVETO;
-                current_type = SEG_LINETO;
-            } else {
-                gpdata->pointTypes[gpdata->numTypes++] = current_type;
-                current_type = SEG_LINETO;
-            }
-        } else {
-            if (current_type == SEG_UNKNOWN) { /* special case:
-                                                   very first point */
-                if (FT_CURVE_TAG(outline->tags[i+1]) == FT_CURVE_TAG_ON) {
-                    /* just skip first point. Adhoc heuristic? */
-                    continue;
-                } else {
-                    x = (x + F26Dot6ToFloat(outline->points[i+1].x))/2;
-                    y = (y - F26Dot6ToFloat(outline->points[i+1].y))/2;
-                    gpdata->pointTypes[gpdata->numTypes++] = SEG_MOVETO;
-                    current_type = SEG_LINETO;
-                }
-            } else if (FT_CURVE_TAG(outline->tags[i]) == FT_CURVE_TAG_CUBIC) {
-                /* Bit 1 is meaningful for 'off' points only.
-                   If set, it indicates a third-order Bezier arc control
-                   point; and a second-order control point if unset.  */
-                current_type = SEG_CUBICTO;
-            } else {
-                /* two successive conic "off" points forces the rasterizer
-                   to create (during the scan-line conversion process
-                   exclusively) a virtual "on" point amidst them, at their
-                   exact middle. This greatly facilitates the definition of
-                   successive conic Bezier arcs.  Moreover, it is the way
-                   outlines are described in the TrueType specification. */
-                if (current_type == SEG_QUADTO) {
-                    gpdata->pointCoords[gpdata->numCoords++] =
-                        F26Dot6ToFloat(outline->points[i].x +
-                        outline->points[i-1].x)/2;
-                    gpdata->pointCoords[gpdata->numCoords++] =
-                        - F26Dot6ToFloat(outline->points[i].y +
-                        outline->points[i-1].y)/2;
-                    gpdata->pointTypes[gpdata->numTypes++] = SEG_QUADTO;
-                }
-                current_type = SEG_QUADTO;
-            }
-        }
-        gpdata->pointCoords[gpdata->numCoords++] = x;
-        gpdata->pointCoords[gpdata->numCoords++] = y;
-        if (outline->contours[j] == i) { //end of contour
-            int start = j > 0 ? outline->contours[j-1]+1 : 0;
-            gpdata->pointTypes[gpdata->numTypes++] = current_type;
-            if (current_type == SEG_QUADTO &&
-            FT_CURVE_TAG(outline->tags[start]) != FT_CURVE_TAG_ON) {
-                gpdata->pointCoords[gpdata->numCoords++] =
-                            (F26Dot6ToFloat(outline->points[start].x) + x)/2;
-                gpdata->pointCoords[gpdata->numCoords++] =
-                            (-F26Dot6ToFloat(outline->points[start].y) + y)/2;
-            } else {
-                gpdata->pointCoords[gpdata->numCoords++] =
-                            F26Dot6ToFloat(outline->points[start].x);
-                gpdata->pointCoords[gpdata->numCoords++] =
-                            -F26Dot6ToFloat(outline->points[start].y);
-            }
-            gpdata->pointTypes[gpdata->numTypes++] = SEG_CLOSE;
-            current_type = SEG_UNKNOWN;
-            j++;
-        }
-    }
+static int conicTo(FT_Vector *control, FT_Vector *to, GPData *gp) {
+    addCoords(gp, control);
+    addCoords(gp, to);
+    addSeg(gp, SEG_QUADTO);
+    return FT_Err_Ok;
+}
+
+static int cubicTo(FT_Vector *control1,
+                   FT_Vector *control2,
+                   FT_Vector *to,
+                   GPData    *gp) {
+    addCoords(gp, control1);
+    addCoords(gp, control2);
+    addCoords(gp, to);
+    addSeg(gp, SEG_CUBICTO);
+    return FT_Err_Ok;
+}
+
+static void addToGP(GPData* gpdata, FT_Outline*outline) {
+    static const FT_Outline_Funcs outline_funcs = {
+        (FT_Outline_MoveToFunc) moveTo,
+        (FT_Outline_LineToFunc) lineTo,
+        (FT_Outline_ConicToFunc) conicTo,
+        (FT_Outline_CubicToFunc) cubicTo,
+        0, /* shift */
+        0, /* delta */
+    };
+
+    FT_Outline_Decompose(outline, &outline_funcs, gpdata);
+    if (gpdata->numCoords)
+        addSeg(gpdata, SEG_CLOSE);
 
     /* If set to 1, the outline will be filled using the even-odd fill rule */
     if (outline->flags & FT_OUTLINE_EVEN_ODD_FILL) {
--- a/jdk/src/java.desktop/share/native/liblcms/cmscam02.c	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.desktop/share/native/liblcms/cmscam02.c	Wed Jul 05 20:01:50 2017 +0200
@@ -467,11 +467,12 @@
     CAM02COLOR clr;
     cmsCIECAM02* lpMod = (cmsCIECAM02*) hModel;
 
-    memset(&clr, 0, sizeof(clr));
     _cmsAssert(lpMod != NULL);
     _cmsAssert(pIn != NULL);
     _cmsAssert(pOut != NULL);
 
+    memset(&clr, 0, sizeof(clr));
+
     clr.XYZ[0] = pIn ->X;
     clr.XYZ[1] = pIn ->Y;
     clr.XYZ[2] = pIn ->Z;
@@ -492,11 +493,12 @@
     CAM02COLOR clr;
     cmsCIECAM02* lpMod = (cmsCIECAM02*) hModel;
 
-    memset(&clr, 0, sizeof(clr));
     _cmsAssert(lpMod != NULL);
     _cmsAssert(pIn != NULL);
     _cmsAssert(pOut != NULL);
 
+    memset(&clr, 0, sizeof(clr));
+
     clr.J = pIn -> J;
     clr.C = pIn -> C;
     clr.h = pIn -> h;
@@ -511,4 +513,3 @@
     pOut ->Y = clr.XYZ[1];
     pOut ->Z = clr.XYZ[2];
 }
-
--- a/jdk/src/java.desktop/share/native/liblcms/cmscgats.c	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.desktop/share/native/liblcms/cmscgats.c	Wed Jul 05 20:01:50 2017 +0200
@@ -2179,9 +2179,9 @@
 
         if (cmsstrcasecmp(Fld, "SAMPLE_ID") == 0) {
 
-                    t -> SampleID = idField;
-
-        for (i=0; i < t -> nPatches; i++) {
+            t -> SampleID = idField;
+
+            for (i=0; i < t -> nPatches; i++) {
 
                 char *Data = GetData(it8, i, idField);
                 if (Data) {
@@ -2196,7 +2196,7 @@
                         SetData(it8, i, idField, Buffer);
 
                 }
-                }
+            }
 
         }
 
--- a/jdk/src/java.desktop/share/native/liblcms/cmscnvrt.c	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.desktop/share/native/liblcms/cmscnvrt.c	Wed Jul 05 20:01:50 2017 +0200
@@ -137,15 +137,68 @@
 
 
 // A pointer to the begining of the list
-static cmsIntentsList *Intents = DefaultIntents;
+_cmsIntentsPluginChunkType _cmsIntentsPluginChunk = { NULL };
+
+// Duplicates the zone of memory used by the plug-in in the new context
+static
+void DupPluginIntentsList(struct _cmsContext_struct* ctx,
+                                               const struct _cmsContext_struct* src)
+{
+   _cmsIntentsPluginChunkType newHead = { NULL };
+   cmsIntentsList*  entry;
+   cmsIntentsList*  Anterior = NULL;
+   _cmsIntentsPluginChunkType* head = (_cmsIntentsPluginChunkType*) src->chunks[IntentPlugin];
+
+    // Walk the list copying all nodes
+   for (entry = head->Intents;
+        entry != NULL;
+        entry = entry ->Next) {
+
+            cmsIntentsList *newEntry = ( cmsIntentsList *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(cmsIntentsList));
+
+            if (newEntry == NULL)
+                return;
+
+            // We want to keep the linked list order, so this is a little bit tricky
+            newEntry -> Next = NULL;
+            if (Anterior)
+                Anterior -> Next = newEntry;
+
+            Anterior = newEntry;
+
+            if (newHead.Intents == NULL)
+                newHead.Intents = newEntry;
+    }
+
+  ctx ->chunks[IntentPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsIntentsPluginChunkType));
+}
+
+void  _cmsAllocIntentsPluginChunk(struct _cmsContext_struct* ctx,
+                                         const struct _cmsContext_struct* src)
+{
+    if (src != NULL) {
+
+        // Copy all linked list
+        DupPluginIntentsList(ctx, src);
+    }
+    else {
+        static _cmsIntentsPluginChunkType IntentsPluginChunkType = { NULL };
+        ctx ->chunks[IntentPlugin] = _cmsSubAllocDup(ctx ->MemPool, &IntentsPluginChunkType, sizeof(_cmsIntentsPluginChunkType));
+    }
+}
+
 
 // Search the list for a suitable intent. Returns NULL if not found
 static
-cmsIntentsList* SearchIntent(cmsUInt32Number Intent)
+cmsIntentsList* SearchIntent(cmsContext ContextID, cmsUInt32Number Intent)
 {
+    _cmsIntentsPluginChunkType* ctx = ( _cmsIntentsPluginChunkType*) _cmsContextGetClientChunk(ContextID, IntentPlugin);
     cmsIntentsList* pt;
 
-    for (pt = Intents; pt != NULL; pt = pt -> Next)
+    for (pt = ctx -> Intents; pt != NULL; pt = pt -> Next)
+        if (pt ->Intent == Intent) return pt;
+
+    for (pt = DefaultIntents; pt != NULL; pt = pt -> Next)
         if (pt ->Intent == Intent) return pt;
 
     return NULL;
@@ -1031,7 +1084,7 @@
     // this case would present some issues if the custom intent tries to do things like
     // preserve primaries. This solution is not perfect, but works well on most cases.
 
-    Intent = SearchIntent(TheIntents[0]);
+    Intent = SearchIntent(ContextID, TheIntents[0]);
     if (Intent == NULL) {
         cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported intent '%d'", TheIntents[0]);
         return NULL;
@@ -1046,12 +1099,14 @@
 // Get information about available intents. nMax is the maximum space for the supplied "Codes"
 // and "Descriptions" the function returns the total number of intents, which may be greater
 // than nMax, although the matrices are not populated beyond this level.
-cmsUInt32Number CMSEXPORT cmsGetSupportedIntents(cmsUInt32Number nMax, cmsUInt32Number* Codes, char** Descriptions)
+cmsUInt32Number CMSEXPORT cmsGetSupportedIntentsTHR(cmsContext ContextID, cmsUInt32Number nMax, cmsUInt32Number* Codes, char** Descriptions)
 {
+    _cmsIntentsPluginChunkType* ctx = ( _cmsIntentsPluginChunkType*) _cmsContextGetClientChunk(ContextID, IntentPlugin);
     cmsIntentsList* pt;
     cmsUInt32Number nIntents;
 
-    for (nIntents=0, pt = Intents; pt != NULL; pt = pt -> Next)
+
+    for (nIntents=0, pt = ctx->Intents; pt != NULL; pt = pt -> Next)
     {
         if (nIntents < nMax) {
             if (Codes != NULL)
@@ -1064,37 +1119,52 @@
         nIntents++;
     }
 
+    for (nIntents=0, pt = DefaultIntents; pt != NULL; pt = pt -> Next)
+    {
+        if (nIntents < nMax) {
+            if (Codes != NULL)
+                Codes[nIntents] = pt ->Intent;
+
+            if (Descriptions != NULL)
+                Descriptions[nIntents] = pt ->Description;
+        }
+
+        nIntents++;
+    }
     return nIntents;
 }
 
+cmsUInt32Number CMSEXPORT cmsGetSupportedIntents(cmsUInt32Number nMax, cmsUInt32Number* Codes, char** Descriptions)
+{
+    return cmsGetSupportedIntentsTHR(NULL, nMax, Codes, Descriptions);
+}
+
 // The plug-in registration. User can add new intents or override default routines
 cmsBool  _cmsRegisterRenderingIntentPlugin(cmsContext id, cmsPluginBase* Data)
 {
+    _cmsIntentsPluginChunkType* ctx = ( _cmsIntentsPluginChunkType*) _cmsContextGetClientChunk(id, IntentPlugin);
     cmsPluginRenderingIntent* Plugin = (cmsPluginRenderingIntent*) Data;
     cmsIntentsList* fl;
 
-    // Do we have to reset the intents?
+    // Do we have to reset the custom intents?
     if (Data == NULL) {
 
-       Intents = DefaultIntents;
-       return TRUE;
+        ctx->Intents = NULL;
+        return TRUE;
     }
 
-    fl = SearchIntent(Plugin ->Intent);
+    fl = (cmsIntentsList*) _cmsPluginMalloc(id, sizeof(cmsIntentsList));
+    if (fl == NULL) return FALSE;
 
-    if (fl == NULL) {
-        fl = (cmsIntentsList*) _cmsPluginMalloc(id, sizeof(cmsIntentsList));
-        if (fl == NULL) return FALSE;
-    }
 
     fl ->Intent  = Plugin ->Intent;
-    strncpy(fl ->Description, Plugin ->Description, 255);
-    fl ->Description[255] = 0;
+    strncpy(fl ->Description, Plugin ->Description, sizeof(fl ->Description)-1);
+    fl ->Description[sizeof(fl ->Description)-1] = 0;
 
     fl ->Link    = Plugin ->Link;
 
-    fl ->Next = Intents;
-    Intents = fl;
+    fl ->Next = ctx ->Intents;
+    ctx ->Intents = fl;
 
     return TRUE;
 }
--- a/jdk/src/java.desktop/share/native/liblcms/cmserr.c	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.desktop/share/native/liblcms/cmserr.c	Wed Jul 05 20:01:50 2017 +0200
@@ -60,13 +60,14 @@
 // compare two strings ignoring case
 int CMSEXPORT cmsstrcasecmp(const char* s1, const char* s2)
 {
-         register const unsigned char *us1 = (const unsigned char *)s1,
-                                      *us2 = (const unsigned char *)s2;
+    register const unsigned char *us1 = (const unsigned char *)s1,
+                                 *us2 = (const unsigned char *)s2;
 
-        while (toupper(*us1) == toupper(*us2++))
-                if (*us1++ == '\0')
-                        return (0);
-        return (toupper(*us1) - toupper(*--us2));
+    while (toupper(*us1) == toupper(*us2++))
+        if (*us1++ == '\0')
+            return 0;
+
+    return (toupper(*us1) - toupper(*--us2));
 }
 
 // long int because C99 specifies ftell in such way (7.19.9.2)
@@ -91,9 +92,8 @@
 //
 // This is the interface to low-level memory management routines. By default a simple
 // wrapping to malloc/free/realloc is provided, although there is a limit on the max
-// amount of memoy that can be reclaimed. This is mostly as a safety feature to
-// prevent bogus or malintentionated code to allocate huge blocks that otherwise lcms
-// would never need.
+// amount of memoy that can be reclaimed. This is mostly as a safety feature to prevent
+// bogus or evil code to allocate huge blocks that otherwise lcms would never need.
 
 #define MAX_MEMORY_FOR_ALLOC  ((cmsUInt32Number)(1024U*1024U*512U))
 
@@ -103,7 +103,7 @@
 // required to be implemented: malloc, realloc and free, although the user may want to
 // replace the optional mallocZero, calloc and dup as well.
 
-cmsBool   _cmsRegisterMemHandlerPlugin(cmsPluginBase* Plugin);
+cmsBool   _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 
 // *********************************************************************************
 
@@ -143,7 +143,7 @@
     cmsUNUSED_PARAMETER(ContextID);
 }
 
-// The default realloc function. Again it check for exploits. If Ptr is NULL,
+// The default realloc function. Again it checks for exploits. If Ptr is NULL,
 // realloc behaves the same way as malloc and allocates a new block of size bytes.
 static
 void* _cmsReallocDefaultFn(cmsContext ContextID, void* Ptr, cmsUInt32Number size)
@@ -196,28 +196,73 @@
     return mem;
 }
 
-// Pointers to malloc and _cmsFree functions in current environment
-static void * (* MallocPtr)(cmsContext ContextID, cmsUInt32Number size)                     = _cmsMallocDefaultFn;
-static void * (* MallocZeroPtr)(cmsContext ContextID, cmsUInt32Number size)                 = _cmsMallocZeroDefaultFn;
-static void   (* FreePtr)(cmsContext ContextID, void *Ptr)                                  = _cmsFreeDefaultFn;
-static void * (* ReallocPtr)(cmsContext ContextID, void *Ptr, cmsUInt32Number NewSize)      = _cmsReallocDefaultFn;
-static void * (* CallocPtr)(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Number size)= _cmsCallocDefaultFn;
-static void * (* DupPtr)(cmsContext ContextID, const void* Org, cmsUInt32Number size)       = _cmsDupDefaultFn;
+
+// Pointers to memory manager functions in Context0
+_cmsMemPluginChunkType _cmsMemPluginChunk = { _cmsMallocDefaultFn, _cmsMallocZeroDefaultFn, _cmsFreeDefaultFn,
+                                              _cmsReallocDefaultFn, _cmsCallocDefaultFn,    _cmsDupDefaultFn
+                                            };
+
+
+// Reset and duplicate memory manager
+void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx, const struct _cmsContext_struct* src)
+{
+    _cmsAssert(ctx != NULL);
+
+    if (src != NULL) {
+
+        // Duplicate
+        ctx ->chunks[MemPlugin] = _cmsSubAllocDup(ctx ->MemPool, src ->chunks[MemPlugin], sizeof(_cmsMemPluginChunkType));
+    }
+    else {
+
+        // To reset it, we use the default allocators, which cannot be overriden
+        ctx ->chunks[MemPlugin] = &ctx ->DefaultMemoryManager;
+    }
+}
+
+// Auxiliar to fill memory management functions from plugin (or context 0 defaults)
+void _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr)
+{
+    if (Plugin == NULL) {
+
+        memcpy(ptr, &_cmsMemPluginChunk, sizeof(_cmsMemPluginChunk));
+    }
+    else {
+
+        ptr ->MallocPtr  = Plugin -> MallocPtr;
+        ptr ->FreePtr    = Plugin -> FreePtr;
+        ptr ->ReallocPtr = Plugin -> ReallocPtr;
+
+        // Make sure we revert to defaults
+        ptr ->MallocZeroPtr= _cmsMallocZeroDefaultFn;
+        ptr ->CallocPtr    = _cmsCallocDefaultFn;
+        ptr ->DupPtr       = _cmsDupDefaultFn;
+
+        if (Plugin ->MallocZeroPtr != NULL) ptr ->MallocZeroPtr = Plugin -> MallocZeroPtr;
+        if (Plugin ->CallocPtr != NULL)     ptr ->CallocPtr     = Plugin -> CallocPtr;
+        if (Plugin ->DupPtr != NULL)        ptr ->DupPtr        = Plugin -> DupPtr;
+
+    }
+}
+
 
 // Plug-in replacement entry
-cmsBool  _cmsRegisterMemHandlerPlugin(cmsPluginBase *Data)
+cmsBool  _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase *Data)
 {
     cmsPluginMemHandler* Plugin = (cmsPluginMemHandler*) Data;
+    _cmsMemPluginChunkType* ptr;
 
-    // NULL forces to reset to defaults
+    // NULL forces to reset to defaults. In this special case, the defaults are stored in the context structure.
+    // Remaining plug-ins does NOT have any copy in the context structure, but this is somehow special as the
+    // context internal data should be malloce'd by using those functions.
     if (Data == NULL) {
 
-        MallocPtr    = _cmsMallocDefaultFn;
-        MallocZeroPtr= _cmsMallocZeroDefaultFn;
-        FreePtr      = _cmsFreeDefaultFn;
-        ReallocPtr   = _cmsReallocDefaultFn;
-        CallocPtr    = _cmsCallocDefaultFn;
-        DupPtr       = _cmsDupDefaultFn;
+       struct _cmsContext_struct* ctx = ( struct _cmsContext_struct*) ContextID;
+
+       // Return to the default allocators
+        if (ContextID != NULL) {
+            ctx->chunks[MemPlugin] = (void*) &ctx->DefaultMemoryManager;
+        }
         return TRUE;
     }
 
@@ -227,51 +272,56 @@
         Plugin -> ReallocPtr == NULL) return FALSE;
 
     // Set replacement functions
-    MallocPtr  = Plugin -> MallocPtr;
-    FreePtr    = Plugin -> FreePtr;
-    ReallocPtr = Plugin -> ReallocPtr;
+    ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin);
+    if (ptr == NULL)
+        return FALSE;
 
-    if (Plugin ->MallocZeroPtr != NULL) MallocZeroPtr = Plugin ->MallocZeroPtr;
-    if (Plugin ->CallocPtr != NULL)     CallocPtr     = Plugin -> CallocPtr;
-    if (Plugin ->DupPtr != NULL)        DupPtr        = Plugin -> DupPtr;
-
+    _cmsInstallAllocFunctions(Plugin, ptr);
     return TRUE;
 }
 
 // Generic allocate
 void* CMSEXPORT _cmsMalloc(cmsContext ContextID, cmsUInt32Number size)
 {
-    return MallocPtr(ContextID, size);
+    _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin);
+    return ptr ->MallocPtr(ContextID, size);
 }
 
 // Generic allocate & zero
 void* CMSEXPORT _cmsMallocZero(cmsContext ContextID, cmsUInt32Number size)
 {
-    return MallocZeroPtr(ContextID, size);
+    _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin);
+    return ptr->MallocZeroPtr(ContextID, size);
 }
 
 // Generic calloc
 void* CMSEXPORT _cmsCalloc(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Number size)
 {
-    return CallocPtr(ContextID, num, size);
+    _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin);
+    return ptr->CallocPtr(ContextID, num, size);
 }
 
 // Generic reallocate
 void* CMSEXPORT _cmsRealloc(cmsContext ContextID, void* Ptr, cmsUInt32Number size)
 {
-    return ReallocPtr(ContextID, Ptr, size);
+    _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin);
+    return ptr->ReallocPtr(ContextID, Ptr, size);
 }
 
 // Generic free memory
 void CMSEXPORT _cmsFree(cmsContext ContextID, void* Ptr)
 {
-    if (Ptr != NULL) FreePtr(ContextID, Ptr);
+    if (Ptr != NULL) {
+        _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin);
+        ptr ->FreePtr(ContextID, Ptr);
+    }
 }
 
 // Generic block duplication
 void* CMSEXPORT _cmsDupMem(cmsContext ContextID, const void* Org, cmsUInt32Number size)
 {
-    return DupPtr(ContextID, Org, size);
+    _cmsMemPluginChunkType* ptr = (_cmsMemPluginChunkType*) _cmsContextGetClientChunk(ContextID, MemPlugin);
+    return ptr ->DupPtr(ContextID, Org, size);
 }
 
 // ********************************************************************************************
@@ -380,6 +430,26 @@
     return (void*) ptr;
 }
 
+// Duplicate in pool
+void* _cmsSubAllocDup(_cmsSubAllocator* s, const void *ptr, cmsUInt32Number size)
+{
+    void *NewPtr;
+
+    // Dup of null pointer is also NULL
+    if (ptr == NULL)
+        return NULL;
+
+    NewPtr = _cmsSubAlloc(s, size);
+
+    if (ptr != NULL && NewPtr != NULL) {
+        memcpy(NewPtr, ptr, size);
+    }
+
+    return NewPtr;
+}
+
+
+
 // Error logging ******************************************************************
 
 // There is no error handling at all. When a funtion fails, it returns proper value.
@@ -401,8 +471,26 @@
 // This is our default log error
 static void DefaultLogErrorHandlerFunction(cmsContext ContextID, cmsUInt32Number ErrorCode, const char *Text);
 
-// The current handler in actual environment
-static cmsLogErrorHandlerFunction LogErrorHandler   = DefaultLogErrorHandlerFunction;
+// Context0 storage, which is global
+_cmsLogErrorChunkType _cmsLogErrorChunk = { DefaultLogErrorHandlerFunction };
+
+// Allocates and inits error logger container for a given context. If src is NULL, only initializes the value
+// to the default. Otherwise, it duplicates the value. The interface is standard across all context clients
+void _cmsAllocLogErrorChunk(struct _cmsContext_struct* ctx,
+                            const struct _cmsContext_struct* src)
+{
+    static _cmsLogErrorChunkType LogErrorChunk = { DefaultLogErrorHandlerFunction };
+    void* from;
+
+     if (src != NULL) {
+        from = src ->chunks[Logger];
+    }
+    else {
+       from = &LogErrorChunk;
+    }
+
+    ctx ->chunks[Logger] = _cmsSubAllocDup(ctx ->MemPool, from, sizeof(_cmsLogErrorChunkType));
+}
 
 // The default error logger does nothing.
 static
@@ -416,13 +504,24 @@
      cmsUNUSED_PARAMETER(Text);
 }
 
-// Change log error
+// Change log error, context based
+void CMSEXPORT cmsSetLogErrorHandlerTHR(cmsContext ContextID, cmsLogErrorHandlerFunction Fn)
+{
+    _cmsLogErrorChunkType* lhg = (_cmsLogErrorChunkType*) _cmsContextGetClientChunk(ContextID, Logger);
+
+    if (lhg != NULL) {
+
+        if (Fn == NULL)
+            lhg -> LogErrorHandler = DefaultLogErrorHandlerFunction;
+        else
+            lhg -> LogErrorHandler = Fn;
+    }
+}
+
+// Change log error, legacy
 void CMSEXPORT cmsSetLogErrorHandler(cmsLogErrorHandlerFunction Fn)
 {
-    if (Fn == NULL)
-        LogErrorHandler = DefaultLogErrorHandlerFunction;
-    else
-        LogErrorHandler = Fn;
+    cmsSetLogErrorHandlerTHR(NULL, Fn);
 }
 
 // Log an error
@@ -431,13 +530,18 @@
 {
     va_list args;
     char Buffer[MAX_ERROR_MESSAGE_LEN];
+    _cmsLogErrorChunkType* lhg;
+
 
     va_start(args, ErrorText);
     vsnprintf(Buffer, MAX_ERROR_MESSAGE_LEN-1, ErrorText, args);
     va_end(args);
 
-    // Call handler
-    LogErrorHandler(ContextID, ErrorCode, Buffer);
+    // Check for the context, if specified go there. If not, go for the global
+    lhg = (_cmsLogErrorChunkType*) _cmsContextGetClientChunk(ContextID, Logger);
+    if (lhg ->LogErrorHandler) {
+        lhg ->LogErrorHandler(ContextID, ErrorCode, Buffer);
+    }
 }
 
 // Utility function to print signatures
@@ -455,3 +559,125 @@
     String[4] = 0;
 }
 
+//--------------------------------------------------------------------------------------------------
+
+
+static
+void* defMtxCreate(cmsContext id)
+{
+    _cmsMutex* ptr_mutex = (_cmsMutex*) _cmsMalloc(id, sizeof(_cmsMutex));
+    _cmsInitMutexPrimitive(ptr_mutex);
+    return (void*) ptr_mutex;
+}
+
+static
+void defMtxDestroy(cmsContext id, void* mtx)
+{
+    _cmsDestroyMutexPrimitive((_cmsMutex *) mtx);
+    _cmsFree(id, mtx);
+}
+
+static
+cmsBool defMtxLock(cmsContext id, void* mtx)
+{
+    cmsUNUSED_PARAMETER(id);
+    return _cmsLockPrimitive((_cmsMutex *) mtx) == 0;
+}
+
+static
+void defMtxUnlock(cmsContext id, void* mtx)
+{
+    cmsUNUSED_PARAMETER(id);
+    _cmsUnlockPrimitive((_cmsMutex *) mtx);
+}
+
+
+
+// Pointers to memory manager functions in Context0
+_cmsMutexPluginChunkType _cmsMutexPluginChunk = { defMtxCreate, defMtxDestroy, defMtxLock, defMtxUnlock };
+
+// Allocate and init mutex container.
+void _cmsAllocMutexPluginChunk(struct _cmsContext_struct* ctx,
+                                        const struct _cmsContext_struct* src)
+{
+    static _cmsMutexPluginChunkType MutexChunk = {defMtxCreate, defMtxDestroy, defMtxLock, defMtxUnlock };
+    void* from;
+
+     if (src != NULL) {
+        from = src ->chunks[MutexPlugin];
+    }
+    else {
+       from = &MutexChunk;
+    }
+
+    ctx ->chunks[MutexPlugin] = _cmsSubAllocDup(ctx ->MemPool, from, sizeof(_cmsMutexPluginChunkType));
+}
+
+// Register new ways to transform
+cmsBool  _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Data)
+{
+    cmsPluginMutex* Plugin = (cmsPluginMutex*) Data;
+    _cmsMutexPluginChunkType* ctx = ( _cmsMutexPluginChunkType*) _cmsContextGetClientChunk(ContextID, MutexPlugin);
+
+    if (Data == NULL) {
+
+        // No lock routines
+        ctx->CreateMutexPtr = NULL;
+        ctx->DestroyMutexPtr = NULL;
+        ctx->LockMutexPtr = NULL;
+        ctx ->UnlockMutexPtr = NULL;
+        return TRUE;
+    }
+
+    // Factory callback is required
+    if (Plugin ->CreateMutexPtr == NULL || Plugin ->DestroyMutexPtr == NULL ||
+        Plugin ->LockMutexPtr == NULL || Plugin ->UnlockMutexPtr == NULL) return FALSE;
+
+
+    ctx->CreateMutexPtr  = Plugin->CreateMutexPtr;
+    ctx->DestroyMutexPtr = Plugin ->DestroyMutexPtr;
+    ctx ->LockMutexPtr   = Plugin ->LockMutexPtr;
+    ctx ->UnlockMutexPtr = Plugin ->UnlockMutexPtr;
+
+    // All is ok
+    return TRUE;
+}
+
+// Generic Mutex fns
+void* CMSEXPORT _cmsCreateMutex(cmsContext ContextID)
+{
+    _cmsMutexPluginChunkType* ptr = (_cmsMutexPluginChunkType*) _cmsContextGetClientChunk(ContextID, MutexPlugin);
+
+    if (ptr ->CreateMutexPtr == NULL) return NULL;
+
+    return ptr ->CreateMutexPtr(ContextID);
+}
+
+void CMSEXPORT _cmsDestroyMutex(cmsContext ContextID, void* mtx)
+{
+    _cmsMutexPluginChunkType* ptr = (_cmsMutexPluginChunkType*) _cmsContextGetClientChunk(ContextID, MutexPlugin);
+
+    if (ptr ->DestroyMutexPtr != NULL) {
+
+        ptr ->DestroyMutexPtr(ContextID, mtx);
+    }
+}
+
+cmsBool CMSEXPORT _cmsLockMutex(cmsContext ContextID, void* mtx)
+{
+    _cmsMutexPluginChunkType* ptr = (_cmsMutexPluginChunkType*) _cmsContextGetClientChunk(ContextID, MutexPlugin);
+
+    if (ptr ->LockMutexPtr == NULL) return TRUE;
+
+    return ptr ->LockMutexPtr(ContextID, mtx);
+}
+
+void CMSEXPORT _cmsUnlockMutex(cmsContext ContextID, void* mtx)
+{
+    _cmsMutexPluginChunkType* ptr = (_cmsMutexPluginChunkType*) _cmsContextGetClientChunk(ContextID, MutexPlugin);
+
+    if (ptr ->UnlockMutexPtr != NULL) {
+
+        ptr ->UnlockMutexPtr(ContextID, mtx);
+    }
+}
--- a/jdk/src/java.desktop/share/native/liblcms/cmsgamma.c	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.desktop/share/native/liblcms/cmsgamma.c	Wed Jul 05 20:01:50 2017 +0200
@@ -82,7 +82,6 @@
 
 } _cmsParametricCurvesCollection;
 
-
 // This is the default (built-in) evaluator
 static cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Number Params[], cmsFloat64Number R);
 
@@ -95,22 +94,77 @@
     NULL                                // Next in chain
 };
 
+// Duplicates the zone of memory used by the plug-in in the new context
+static
+void DupPluginCurvesList(struct _cmsContext_struct* ctx,
+                                               const struct _cmsContext_struct* src)
+{
+   _cmsCurvesPluginChunkType newHead = { NULL };
+   _cmsParametricCurvesCollection*  entry;
+   _cmsParametricCurvesCollection*  Anterior = NULL;
+   _cmsCurvesPluginChunkType* head = (_cmsCurvesPluginChunkType*) src->chunks[CurvesPlugin];
+
+    _cmsAssert(head != NULL);
+
+    // Walk the list copying all nodes
+   for (entry = head->ParametricCurves;
+        entry != NULL;
+        entry = entry ->Next) {
+
+            _cmsParametricCurvesCollection *newEntry = ( _cmsParametricCurvesCollection *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(_cmsParametricCurvesCollection));
+
+            if (newEntry == NULL)
+                return;
+
+            // We want to keep the linked list order, so this is a little bit tricky
+            newEntry -> Next = NULL;
+            if (Anterior)
+                Anterior -> Next = newEntry;
+
+            Anterior = newEntry;
+
+            if (newHead.ParametricCurves == NULL)
+                newHead.ParametricCurves = newEntry;
+    }
+
+  ctx ->chunks[CurvesPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsCurvesPluginChunkType));
+}
+
+// The allocator have to follow the chain
+void _cmsAllocCurvesPluginChunk(struct _cmsContext_struct* ctx,
+                                const struct _cmsContext_struct* src)
+{
+    _cmsAssert(ctx != NULL);
+
+    if (src != NULL) {
+
+        // Copy all linked list
+       DupPluginCurvesList(ctx, src);
+    }
+    else {
+        static _cmsCurvesPluginChunkType CurvesPluginChunk = { NULL };
+        ctx ->chunks[CurvesPlugin] = _cmsSubAllocDup(ctx ->MemPool, &CurvesPluginChunk, sizeof(_cmsCurvesPluginChunkType));
+    }
+}
+
+
 // The linked list head
-static _cmsParametricCurvesCollection* ParametricCurves = &DefaultCurves;
+_cmsCurvesPluginChunkType _cmsCurvesPluginChunk = { NULL };
 
 // As a way to install new parametric curves
-cmsBool _cmsRegisterParametricCurvesPlugin(cmsContext id, cmsPluginBase* Data)
+cmsBool _cmsRegisterParametricCurvesPlugin(cmsContext ContextID, cmsPluginBase* Data)
 {
+    _cmsCurvesPluginChunkType* ctx = ( _cmsCurvesPluginChunkType*) _cmsContextGetClientChunk(ContextID, CurvesPlugin);
     cmsPluginParametricCurves* Plugin = (cmsPluginParametricCurves*) Data;
     _cmsParametricCurvesCollection* fl;
 
     if (Data == NULL) {
 
-          ParametricCurves =  &DefaultCurves;
+          ctx -> ParametricCurves =  NULL;
           return TRUE;
     }
 
-    fl = (_cmsParametricCurvesCollection*) _cmsPluginMalloc(id, sizeof(_cmsParametricCurvesCollection));
+    fl = (_cmsParametricCurvesCollection*) _cmsPluginMalloc(ContextID, sizeof(_cmsParametricCurvesCollection));
     if (fl == NULL) return FALSE;
 
     // Copy the parameters
@@ -126,8 +180,8 @@
     memmove(fl->ParameterCount, Plugin ->ParameterCount,  fl->nFunctions * sizeof(cmsUInt32Number));
 
     // Keep linked list
-    fl ->Next = ParametricCurves;
-    ParametricCurves = fl;
+    fl ->Next = ctx->ParametricCurves;
+    ctx->ParametricCurves = fl;
 
     // All is ok
     return TRUE;
@@ -149,12 +203,24 @@
 
 // Search for the collection which contains a specific type
 static
-_cmsParametricCurvesCollection *GetParametricCurveByType(int Type, int* index)
+_cmsParametricCurvesCollection *GetParametricCurveByType(cmsContext ContextID, int Type, int* index)
 {
     _cmsParametricCurvesCollection* c;
     int Position;
+    _cmsCurvesPluginChunkType* ctx = ( _cmsCurvesPluginChunkType*) _cmsContextGetClientChunk(ContextID, CurvesPlugin);
 
-    for (c = ParametricCurves; c != NULL; c = c ->Next) {
+    for (c = ctx->ParametricCurves; c != NULL; c = c ->Next) {
+
+        Position = IsInSet(Type, c);
+
+        if (Position != -1) {
+            if (index != NULL)
+                *index = Position;
+            return c;
+        }
+    }
+    // If none found, revert for defaults
+    for (c = &DefaultCurves; c != NULL; c = c ->Next) {
 
         Position = IsInSet(Type, c);
 
@@ -251,7 +317,7 @@
                 p ->Segments[i].SampledPoints = NULL;
 
 
-            c = GetParametricCurveByType(Segments[i].Type, NULL);
+            c = GetParametricCurveByType(ContextID, Segments[i].Type, NULL);
             if (c != NULL)
                     p ->Evals[i] = c ->Evaluator;
         }
@@ -677,12 +743,12 @@
     cmsCurveSegment Seg0;
     int Pos = 0;
     cmsUInt32Number size;
-    _cmsParametricCurvesCollection* c = GetParametricCurveByType(Type, &Pos);
+    _cmsParametricCurvesCollection* c = GetParametricCurveByType(ContextID, Type, &Pos);
 
     _cmsAssert(Params != NULL);
 
     if (c == NULL) {
-         cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Invalid parametric curve type %d", Type);
+        cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Invalid parametric curve type %d", Type);
         return NULL;
     }
 
@@ -872,7 +938,10 @@
     _cmsAssert(InCurve != NULL);
 
     // Try to reverse it analytically whatever possible
-    if (InCurve ->nSegments == 1 && InCurve ->Segments[0].Type > 0 && InCurve -> Segments[0].Type <= 5) {
+
+    if (InCurve ->nSegments == 1 && InCurve ->Segments[0].Type > 0 &&
+        /* InCurve -> Segments[0].Type <= 5 */
+        GetParametricCurveByType(InCurve ->InterpParams->ContextID, InCurve ->Segments[0].Type, NULL) != NULL) {
 
         return cmsBuildParametricToneCurve(InCurve ->InterpParams->ContextID,
                                        -(InCurve -> Segments[0].Type),
--- a/jdk/src/java.desktop/share/native/liblcms/cmsgmt.c	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.desktop/share/native/liblcms/cmsgmt.c	Wed Jul 05 20:01:50 2017 +0200
@@ -191,7 +191,7 @@
 
     out = ComputeKToLstar(ContextID, nPoints, 1,
                             Intents + (nProfiles - 1),
-                            hProfiles + (nProfiles - 1),
+                            &hProfiles [nProfiles - 1],
                             BPC + (nProfiles - 1),
                             AdaptationStates + (nProfiles - 1),
                             dwFlags);
--- a/jdk/src/java.desktop/share/native/liblcms/cmsintrp.c	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.desktop/share/native/liblcms/cmsintrp.c	Wed Jul 05 20:01:50 2017 +0200
@@ -62,31 +62,57 @@
 static cmsInterpFunction DefaultInterpolatorsFactory(cmsUInt32Number nInputChannels, cmsUInt32Number nOutputChannels, cmsUInt32Number dwFlags);
 
 // This is the default factory
-static cmsInterpFnFactory Interpolators = DefaultInterpolatorsFactory;
+_cmsInterpPluginChunkType _cmsInterpPluginChunk = { NULL };
+
+// The interpolation plug-in memory chunk allocator/dup
+void _cmsAllocInterpPluginChunk(struct _cmsContext_struct* ctx, const struct _cmsContext_struct* src)
+{
+    void* from;
+
+    _cmsAssert(ctx != NULL);
+
+    if (src != NULL) {
+        from = src ->chunks[InterpPlugin];
+    }
+    else {
+        static _cmsInterpPluginChunkType InterpPluginChunk = { NULL };
+
+        from = &InterpPluginChunk;
+    }
+
+    _cmsAssert(from != NULL);
+    ctx ->chunks[InterpPlugin] = _cmsSubAllocDup(ctx ->MemPool, from, sizeof(_cmsInterpPluginChunkType));
+}
 
 
 // Main plug-in entry
-cmsBool  _cmsRegisterInterpPlugin(cmsPluginBase* Data)
+cmsBool  _cmsRegisterInterpPlugin(cmsContext ContextID, cmsPluginBase* Data)
 {
     cmsPluginInterpolation* Plugin = (cmsPluginInterpolation*) Data;
+    _cmsInterpPluginChunkType* ptr = (_cmsInterpPluginChunkType*) _cmsContextGetClientChunk(ContextID, InterpPlugin);
 
     if (Data == NULL) {
 
-        Interpolators = DefaultInterpolatorsFactory;
+        ptr ->Interpolators = NULL;
         return TRUE;
     }
 
     // Set replacement functions
-    Interpolators = Plugin ->InterpolatorsFactory;
+    ptr ->Interpolators = Plugin ->InterpolatorsFactory;
     return TRUE;
 }
 
 
 // Set the interpolation method
-cmsBool _cmsSetInterpolationRoutine(cmsInterpParams* p)
+cmsBool _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p)
 {
-    // Invoke factory, possibly in the Plug-in
-    p ->Interpolation = Interpolators(p -> nInputs, p ->nOutputs, p ->dwFlags);
+    _cmsInterpPluginChunkType* ptr = (_cmsInterpPluginChunkType*) _cmsContextGetClientChunk(ContextID, InterpPlugin);
+
+    p ->Interpolation.Lerp16 = NULL;
+
+   // Invoke factory, possibly in the Plug-in
+    if (ptr ->Interpolators != NULL)
+        p ->Interpolation = ptr->Interpolators(p -> nInputs, p ->nOutputs, p ->dwFlags);
 
     // If unsupported by the plug-in, go for the LittleCMS default.
     // If happens only if an extern plug-in is being used
@@ -97,6 +123,7 @@
     if (p ->Interpolation.Lerp16 == NULL) {
             return FALSE;
     }
+
     return TRUE;
 }
 
@@ -141,7 +168,7 @@
         p ->opta[i] = p ->opta[i-1] * nSamples[InputChan-i];
 
 
-    if (!_cmsSetInterpolationRoutine(p)) {
+    if (!_cmsSetInterpolationRoutine(ContextID, p)) {
          cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported interpolation (%d->%d channels)", InputChan, OutputChan);
         _cmsFree(ContextID, p);
         return NULL;
--- a/jdk/src/java.desktop/share/native/liblcms/cmsio0.c	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.desktop/share/native/liblcms/cmsio0.c	Wed Jul 05 20:01:50 2017 +0200
@@ -229,15 +229,14 @@
     if (ResData == NULL) return FALSE; // Housekeeping
 
     // Check for available space. Clip.
-    if (iohandler ->UsedSpace + size > ResData->Size) {
-        size = ResData ->Size - iohandler ->UsedSpace;
+    if (ResData->Pointer + size > ResData->Size) {
+        size = ResData ->Size - ResData->Pointer;
     }
 
     if (size == 0) return TRUE;     // Write zero bytes is ok, but does nothing
 
     memmove(ResData ->Block + ResData ->Pointer, Ptr, size);
     ResData ->Pointer += size;
-    iohandler->UsedSpace += size;
 
     if (ResData ->Pointer > iohandler->UsedSpace)
         iohandler->UsedSpace = ResData ->Pointer;
@@ -371,7 +370,7 @@
 static
 cmsUInt32Number FileTell(cmsIOHANDLER* iohandler)
 {
-    return ftell((FILE*)iohandler ->stream);
+    return (cmsUInt32Number) ftell((FILE*)iohandler ->stream);
 }
 
 // Writes data to stream, also keeps used space for further reference. Returns TRUE on success, FALSE on error
@@ -414,7 +413,7 @@
              cmsSignalError(ContextID, cmsERROR_FILE, "File '%s' not found", FileName);
             return NULL;
         }
-        iohandler -> ReportedSize = cmsfilelength(fm);
+        iohandler -> ReportedSize = (cmsUInt32Number) cmsfilelength(fm);
         break;
 
     case 'w':
@@ -461,7 +460,7 @@
     iohandler -> ContextID = ContextID;
     iohandler -> stream = (void*) Stream;
     iohandler -> UsedSpace = 0;
-    iohandler -> ReportedSize = cmsfilelength(Stream);
+    iohandler -> ReportedSize = (cmsUInt32Number) cmsfilelength(Stream);
     iohandler -> PhysicalFile[0] = 0;
 
     iohandler ->Read    = FileRead;
@@ -501,6 +500,9 @@
     // Set creation date/time
     memmove(&Icc ->Created, gmtime(&now), sizeof(Icc ->Created));
 
+    // Create a mutex if the user provided proper plugin. NULL otherwise
+    Icc ->UsrMutex = _cmsCreateMutex(ContextID);
+
     // Return the handle
     return (cmsHPROFILE) Icc;
 }
@@ -579,9 +581,39 @@
     return n;
 }
 
+// Deletes a tag entry
 
-// Create a new tag entry
+static
+void _cmsDeleteTagByPos(_cmsICCPROFILE* Icc, int i)
+{
+    _cmsAssert(Icc != NULL);
+    _cmsAssert(i >= 0);
+
+
+    if (Icc -> TagPtrs[i] != NULL) {
+
+        // Free previous version
+        if (Icc ->TagSaveAsRaw[i]) {
+            _cmsFree(Icc ->ContextID, Icc ->TagPtrs[i]);
+        }
+        else {
+            cmsTagTypeHandler* TypeHandler = Icc ->TagTypeHandlers[i];
 
+            if (TypeHandler != NULL) {
+
+                cmsTagTypeHandler LocalTypeHandler = *TypeHandler;
+                LocalTypeHandler.ContextID = Icc ->ContextID;              // As an additional parameter
+                LocalTypeHandler.ICCVersion = Icc ->Version;
+                LocalTypeHandler.FreePtr(&LocalTypeHandler, Icc -> TagPtrs[i]);
+                Icc ->TagPtrs[i] = NULL;
+            }
+        }
+
+    }
+}
+
+
+// Creates a new tag entry
 static
 cmsBool _cmsNewTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, int* NewPos)
 {
@@ -589,15 +621,15 @@
 
     // Search for the tag
     i = _cmsSearchTag(Icc, sig, FALSE);
+    if (i >= 0) {
 
-    // Now let's do it easy. If the tag has been already written, that's an error
-    if (i >= 0) {
-        cmsSignalError(Icc ->ContextID, cmsERROR_ALREADY_DEFINED, "Tag '%x' already exists", sig);
-        return FALSE;
+        // Already exists? delete it
+        _cmsDeleteTagByPos(Icc, i);
+        *NewPos = i;
     }
     else  {
 
-        // New one
+        // No, make a new one
 
         if (Icc -> TagCount >= MAX_TABLE_TAG) {
             cmsSignalError(Icc ->ContextID, cmsERROR_RANGE, "Too many tags (%d)", MAX_TABLE_TAG);
@@ -979,7 +1011,7 @@
 
     // 4.2 -> 0x4200000
 
-    Icc -> Version = BaseToBase((cmsUInt32Number) floor(Version * 100.0), 10, 16) << 16;
+    Icc -> Version = BaseToBase((cmsUInt32Number) floor(Version * 100.0 + 0.5), 10, 16) << 16;
 }
 
 cmsFloat64Number CMSEXPORT cmsGetProfileVersion(cmsHPROFILE hProfile)
@@ -1011,6 +1043,32 @@
     return NULL;
 }
 
+// Create profile from IOhandler
+cmsHPROFILE CMSEXPORT cmsOpenProfileFromIOhandler2THR(cmsContext ContextID, cmsIOHANDLER* io, cmsBool write)
+{
+    _cmsICCPROFILE* NewIcc;
+    cmsHPROFILE hEmpty = cmsCreateProfilePlaceholder(ContextID);
+
+    if (hEmpty == NULL) return NULL;
+
+    NewIcc = (_cmsICCPROFILE*) hEmpty;
+
+    NewIcc ->IOhandler = io;
+    if (write) {
+
+        NewIcc -> IsWrite = TRUE;
+        return hEmpty;
+    }
+
+    if (!_cmsReadHeader(NewIcc)) goto Error;
+    return hEmpty;
+
+Error:
+    cmsCloseProfile(hEmpty);
+    return NULL;
+}
+
+
 // Create profile from disk file
 cmsHPROFILE CMSEXPORT cmsOpenProfileFromFileTHR(cmsContext ContextID, const char *lpFileName, const char *sAccess)
 {
@@ -1202,7 +1260,7 @@
         else {
 
             // Search for support on this tag
-            TagDescriptor = _cmsGetTagDescriptor(Icc -> TagNames[i]);
+            TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, Icc -> TagNames[i]);
             if (TagDescriptor == NULL) continue;                        // Unsupported, ignore it
 
             if (TagDescriptor ->DecideType != NULL) {
@@ -1214,7 +1272,7 @@
                 Type = TagDescriptor ->SupportedTypes[0];
             }
 
-            TypeHandler =  _cmsGetTagTypeHandler(Type);
+            TypeHandler =  _cmsGetTagTypeHandler(Icc->ContextID, Type);
 
             if (TypeHandler == NULL) {
                 cmsSignalError(Icc ->ContextID, cmsERROR_INTERNAL, "(Internal) no handler for tag %x", Icc -> TagNames[i]);
@@ -1282,10 +1340,12 @@
 {
     _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile;
     _cmsICCPROFILE Keep;
-    cmsIOHANDLER* PrevIO;
+    cmsIOHANDLER* PrevIO = NULL;
     cmsUInt32Number UsedSpace;
     cmsContext ContextID;
 
+    _cmsAssert(hProfile != NULL);
+
     memmove(&Keep, Icc, sizeof(_cmsICCPROFILE));
 
     ContextID = cmsGetProfileContextID(hProfile);
@@ -1294,18 +1354,19 @@
 
     // Pass #1 does compute offsets
 
-    if (!_cmsWriteHeader(Icc, 0)) return 0;
-    if (!SaveTags(Icc, &Keep)) return 0;
+    if (!_cmsWriteHeader(Icc, 0)) goto Error;
+    if (!SaveTags(Icc, &Keep)) goto Error;
 
     UsedSpace = PrevIO ->UsedSpace;
 
     // Pass #2 does save to iohandler
 
     if (io != NULL) {
+
         Icc ->IOhandler = io;
-        if (!SetLinks(Icc)) goto CleanUp;
-        if (!_cmsWriteHeader(Icc, UsedSpace)) goto CleanUp;
-        if (!SaveTags(Icc, &Keep)) goto CleanUp;
+        if (!SetLinks(Icc)) goto Error;
+        if (!_cmsWriteHeader(Icc, UsedSpace)) goto Error;
+        if (!SaveTags(Icc, &Keep)) goto Error;
     }
 
     memmove(Icc, &Keep, sizeof(_cmsICCPROFILE));
@@ -1314,7 +1375,7 @@
     return UsedSpace;
 
 
-CleanUp:
+Error:
     cmsCloseIOhandler(PrevIO);
     memmove(Icc, &Keep, sizeof(_cmsICCPROFILE));
     return 0;
@@ -1362,11 +1423,13 @@
     cmsIOHANDLER* io;
     cmsContext ContextID = cmsGetProfileContextID(hProfile);
 
+    _cmsAssert(BytesNeeded != NULL);
+
     // Should we just calculate the needed space?
     if (MemPtr == NULL) {
 
            *BytesNeeded =  cmsSaveProfileToIOhandler(hProfile, NULL);
-            return (*BytesNeeded == 0 ? FALSE : TRUE);
+            return (*BytesNeeded == 0) ? FALSE : TRUE;
     }
 
     // That is a real write operation
@@ -1419,6 +1482,8 @@
         rc &= cmsCloseIOhandler(Icc->IOhandler);
     }
 
+    _cmsDestroyMutex(Icc->ContextID, Icc->UsrMutex);
+
     _cmsFree(Icc ->ContextID, Icc);   // Free placeholder memory
 
     return rc;
@@ -1459,14 +1524,18 @@
     cmsUInt32Number ElemCount;
     int n;
 
+    if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return NULL;
+
     n = _cmsSearchTag(Icc, sig, TRUE);
-    if (n < 0) return NULL;                 // Not found, return NULL
+    if (n < 0) goto Error;               // Not found, return NULL
 
 
     // If the element is already in memory, return the pointer
     if (Icc -> TagPtrs[n]) {
 
-        if (Icc ->TagSaveAsRaw[n]) return NULL;  // We don't support read raw tags as cooked
+        if (Icc ->TagSaveAsRaw[n]) goto Error;  // We don't support read raw tags as cooked
+
+        _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
         return Icc -> TagPtrs[n];
     }
 
@@ -1476,23 +1545,32 @@
 
     // Seek to its location
     if (!io -> Seek(io, Offset))
-        return NULL;
+        goto Error;
 
     // Search for support on this tag
-    TagDescriptor = _cmsGetTagDescriptor(sig);
-    if (TagDescriptor == NULL) return NULL;     // Unsupported.
+    TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, sig);
+    if (TagDescriptor == NULL) {
+
+        char String[5];
+
+        _cmsTagSignature2String(String, sig);
+
+        // An unknown element was found.
+        cmsSignalError(Icc ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown tag type '%s' found.", String);
+        goto Error;     // Unsupported.
+    }
 
     // if supported, get type and check if in list
     BaseType = _cmsReadTypeBase(io);
-    if (BaseType == 0) return NULL;
+    if (BaseType == 0) goto Error;
 
-    if (!IsTypeSupported(TagDescriptor, BaseType)) return NULL;
+    if (!IsTypeSupported(TagDescriptor, BaseType)) goto Error;
 
     TagSize  -= 8;                      // Alredy read by the type base logic
 
     // Get type handler
-    TypeHandler = _cmsGetTagTypeHandler(BaseType);
-    if (TypeHandler == NULL) return NULL;
+    TypeHandler = _cmsGetTagTypeHandler(Icc ->ContextID, BaseType);
+    if (TypeHandler == NULL) goto Error;
     LocalTypeHandler = *TypeHandler;
 
 
@@ -1511,7 +1589,7 @@
 
         _cmsTagSignature2String(String, sig);
         cmsSignalError(Icc ->ContextID, cmsERROR_CORRUPTION_DETECTED, "Corrupted tag '%s'", String);
-        return NULL;
+        goto Error;
     }
 
     // This is a weird error that may be a symptom of something more serious, the number of
@@ -1527,7 +1605,14 @@
 
 
     // Return the data
+    _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
     return Icc -> TagPtrs[n];
+
+
+    // Return error and unlock tha data
+Error:
+    _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
+    return NULL;
 }
 
 
@@ -1561,49 +1646,26 @@
     cmsFloat64Number Version;
     char TypeString[5], SigString[5];
 
+    if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return FALSE;
 
+    // To delete tags.
     if (data == NULL) {
 
+         // Delete the tag
          i = _cmsSearchTag(Icc, sig, FALSE);
-         if (i >= 0)
+         if (i >= 0) {
+
+             // Use zero as a mark of deleted
+             _cmsDeleteTagByPos(Icc, i);
              Icc ->TagNames[i] = (cmsTagSignature) 0;
-         // Unsupported by now, reserved for future ampliations (delete)
-         return FALSE;
+             _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
+             return TRUE;
+         }
+         // Didn't find the tag
+        goto Error;
     }
 
-    i = _cmsSearchTag(Icc, sig, FALSE);
-    if (i >=0) {
-
-        if (Icc -> TagPtrs[i] != NULL) {
-
-            // Already exists. Free previous version
-            if (Icc ->TagSaveAsRaw[i]) {
-                _cmsFree(Icc ->ContextID, Icc ->TagPtrs[i]);
-            }
-            else {
-                TypeHandler = Icc ->TagTypeHandlers[i];
-
-                if (TypeHandler != NULL) {
-
-                    LocalTypeHandler = *TypeHandler;
-                    LocalTypeHandler.ContextID = Icc ->ContextID;              // As an additional parameter
-                    LocalTypeHandler.ICCVersion = Icc ->Version;
-                    LocalTypeHandler.FreePtr(&LocalTypeHandler, Icc -> TagPtrs[i]);
-                }
-            }
-        }
-    }
-    else  {
-        // New one
-        i = Icc -> TagCount;
-
-        if (i >= MAX_TABLE_TAG) {
-            cmsSignalError(Icc ->ContextID, cmsERROR_RANGE, "Too many tags (%d)", MAX_TABLE_TAG);
-            return FALSE;
-        }
-
-        Icc -> TagCount++;
-    }
+    if (!_cmsNewTag(Icc, sig, &i)) goto Error;
 
     // This is not raw
     Icc ->TagSaveAsRaw[i] = FALSE;
@@ -1612,10 +1674,10 @@
     Icc ->TagLinked[i] = (cmsTagSignature) 0;
 
     // Get information about the TAG.
-    TagDescriptor = _cmsGetTagDescriptor(sig);
+    TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, sig);
     if (TagDescriptor == NULL){
          cmsSignalError(Icc ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported tag '%x'", sig);
-        return FALSE;
+        goto Error;
     }
 
 
@@ -1633,7 +1695,6 @@
     }
     else {
 
-
         Type = TagDescriptor ->SupportedTypes[0];
     }
 
@@ -1644,18 +1705,18 @@
         _cmsTagSignature2String(SigString,  sig);
 
         cmsSignalError(Icc ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported type '%s' for tag '%s'", TypeString, SigString);
-        return FALSE;
+        goto Error;
     }
 
     // Does we have a handler for this type?
-    TypeHandler =  _cmsGetTagTypeHandler(Type);
+    TypeHandler =  _cmsGetTagTypeHandler(Icc->ContextID, Type);
     if (TypeHandler == NULL) {
 
         _cmsTagSignature2String(TypeString, (cmsTagSignature) Type);
         _cmsTagSignature2String(SigString,  sig);
 
         cmsSignalError(Icc ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported type '%s' for tag '%s'", TypeString, SigString);
-        return FALSE;           // Should never happen
+        goto Error;           // Should never happen
     }
 
 
@@ -1668,7 +1729,7 @@
     LocalTypeHandler = *TypeHandler;
     LocalTypeHandler.ContextID  = Icc ->ContextID;
     LocalTypeHandler.ICCVersion = Icc ->Version;
-    Icc ->TagPtrs[i]         = LocalTypeHandler.DupPtr(&LocalTypeHandler, data, TagDescriptor ->ElemCount);
+    Icc ->TagPtrs[i]            = LocalTypeHandler.DupPtr(&LocalTypeHandler, data, TagDescriptor ->ElemCount);
 
     if (Icc ->TagPtrs[i] == NULL)  {
 
@@ -1676,10 +1737,16 @@
         _cmsTagSignature2String(SigString,  sig);
         cmsSignalError(Icc ->ContextID, cmsERROR_CORRUPTION_DETECTED, "Malformed struct in type '%s' for tag '%s'", TypeString, SigString);
 
-        return FALSE;
+        goto Error;
     }
 
+    _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
     return TRUE;
+
+Error:
+    _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
+    return FALSE;
+
 }
 
 // Read and write raw data. The only way those function would work and keep consistence with normal read and write
@@ -1700,9 +1767,11 @@
     cmsUInt32Number rc;
     cmsUInt32Number Offset, TagSize;
 
+    if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return 0;
+
     // Search for given tag in ICC profile directory
     i = _cmsSearchTag(Icc, sig, TRUE);
-    if (i < 0) return 0;                 // Not found, return 0
+    if (i < 0) goto Error;                 // Not found,
 
     // It is already read?
     if (Icc -> TagPtrs[i] == NULL) {
@@ -1717,12 +1786,14 @@
             if (BufferSize < TagSize)
                 TagSize = BufferSize;
 
-            if (!Icc ->IOhandler ->Seek(Icc ->IOhandler, Offset)) return 0;
-            if (!Icc ->IOhandler ->Read(Icc ->IOhandler, data, 1, TagSize)) return 0;
+            if (!Icc ->IOhandler ->Seek(Icc ->IOhandler, Offset)) goto Error;
+            if (!Icc ->IOhandler ->Read(Icc ->IOhandler, data, 1, TagSize)) goto Error;
 
+            _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
             return TagSize;
         }
 
+        _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
         return Icc ->TagSizes[i];
     }
 
@@ -1738,16 +1809,22 @@
 
             memmove(data, Icc ->TagPtrs[i], TagSize);
 
+            _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
             return TagSize;
         }
 
+        _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
         return Icc ->TagSizes[i];
     }
 
     // Already readed, or previously set by cmsWriteTag(). We need to serialize that
     // data to raw in order to maintain consistency.
+
+    _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
     Object = cmsReadTag(hProfile, sig);
-    if (Object == NULL) return 0;
+    if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return 0;
+
+    if (Object == NULL) goto Error;
 
     // Now we need to serialize to a memory block: just use a memory iohandler
 
@@ -1756,17 +1833,18 @@
     } else{
         MemIO = cmsOpenIOhandlerFromMem(cmsGetProfileContextID(hProfile), data, BufferSize, "w");
     }
-    if (MemIO == NULL) return 0;
+    if (MemIO == NULL) goto Error;
 
     // Obtain type handling for the tag
     TypeHandler = Icc ->TagTypeHandlers[i];
-    TagDescriptor = _cmsGetTagDescriptor(sig);
+    TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, sig);
     if (TagDescriptor == NULL) {
         cmsCloseIOhandler(MemIO);
-        return 0;
+        goto Error;
     }
 
-    // FIXME: No handling for TypeHandler == NULL here?
+    if (TypeHandler == NULL) goto Error;
+
     // Serialize
     LocalTypeHandler = *TypeHandler;
     LocalTypeHandler.ContextID  = Icc ->ContextID;
@@ -1774,19 +1852,24 @@
 
     if (!_cmsWriteTypeBase(MemIO, TypeHandler ->Signature)) {
         cmsCloseIOhandler(MemIO);
-        return 0;
+        goto Error;
     }
 
     if (!LocalTypeHandler.WritePtr(&LocalTypeHandler, MemIO, Object, TagDescriptor ->ElemCount)) {
         cmsCloseIOhandler(MemIO);
-        return 0;
+        goto Error;
     }
 
     // Get Size and close
     rc = MemIO ->Tell(MemIO);
     cmsCloseIOhandler(MemIO);      // Ignore return code this time
 
+    _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
     return rc;
+
+Error:
+    _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
+    return 0;
 }
 
 // Similar to the anterior. This function allows to write directly to the ICC profile any data, without
@@ -1798,7 +1881,12 @@
     _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile;
     int i;
 
-    if (!_cmsNewTag(Icc, sig, &i)) return FALSE;
+    if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return 0;
+
+    if (!_cmsNewTag(Icc, sig, &i)) {
+        _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
+         return FALSE;
+    }
 
     // Mark the tag as being written as RAW
     Icc ->TagSaveAsRaw[i] = TRUE;
@@ -1809,6 +1897,7 @@
     Icc ->TagPtrs[i]  = _cmsDupMem(Icc ->ContextID, data, Size);
     Icc ->TagSizes[i] = Size;
 
+    _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
     return TRUE;
 }
 
@@ -1818,7 +1907,12 @@
     _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile;
     int i;
 
-    if (!_cmsNewTag(Icc, sig, &i)) return FALSE;
+     if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return FALSE;
+
+    if (!_cmsNewTag(Icc, sig, &i)) {
+        _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
+        return FALSE;
+    }
 
     // Keep necessary information
     Icc ->TagSaveAsRaw[i] = FALSE;
@@ -1829,6 +1923,7 @@
     Icc ->TagSizes[i]   = 0;
     Icc ->TagOffsets[i] = 0;
 
+    _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
     return TRUE;
 }
 
--- a/jdk/src/java.desktop/share/native/liblcms/cmsio1.c	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.desktop/share/native/liblcms/cmsio1.c	Wed Jul 05 20:01:50 2017 +0200
@@ -334,7 +334,8 @@
 
 
 // Read and create a BRAND NEW MPE LUT from a given profile. All stuff dependent of version, etc
-// is adjusted here in order to create a LUT that takes care of all those details
+// is adjusted here in order to create a LUT that takes care of all those details.
+// We add intent = -1 as a way to read matrix shaper always, no matter of other LUT
 cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent)
 {
     cmsTagTypeSignature OriginalType;
@@ -364,49 +365,54 @@
         return Lut;
     }
 
-    if (cmsIsTag(hProfile, tagFloat)) {  // Float tag takes precedence
+    // This is an attempt to reuse this funtion to retrieve the matrix-shaper as pipeline no
+    // matter other LUT are present and have precedence. Intent = -1 means just this.
+    if (Intent != -1) {
 
-        // Floating point LUT are always V4, but the encoding range is no
-        // longer 0..1.0, so we need to add an stage depending on the color space
-         return _cmsReadFloatInputTag(hProfile, tagFloat);
-    }
+        if (cmsIsTag(hProfile, tagFloat)) {  // Float tag takes precedence
+
+            // Floating point LUT are always V4, but the encoding range is no
+            // longer 0..1.0, so we need to add an stage depending on the color space
+            return _cmsReadFloatInputTag(hProfile, tagFloat);
+        }
 
-    // Revert to perceptual if no tag is found
-    if (!cmsIsTag(hProfile, tag16)) {
-        tag16 = Device2PCS16[0];
-    }
+        // Revert to perceptual if no tag is found
+        if (!cmsIsTag(hProfile, tag16)) {
+            tag16 = Device2PCS16[0];
+        }
 
-    if (cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table?
+        if (cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table?
 
-        // Check profile version and LUT type. Do the necessary adjustments if needed
+            // Check profile version and LUT type. Do the necessary adjustments if needed
 
-        // First read the tag
-        cmsPipeline* Lut = (cmsPipeline*) cmsReadTag(hProfile, tag16);
-        if (Lut == NULL) return NULL;
+            // First read the tag
+            cmsPipeline* Lut = (cmsPipeline*) cmsReadTag(hProfile, tag16);
+            if (Lut == NULL) return NULL;
 
-        // After reading it, we have now info about the original type
-        OriginalType =  _cmsGetTagTrueType(hProfile, tag16);
+            // After reading it, we have now info about the original type
+            OriginalType =  _cmsGetTagTrueType(hProfile, tag16);
 
-        // The profile owns the Lut, so we need to copy it
-        Lut = cmsPipelineDup(Lut);
+            // The profile owns the Lut, so we need to copy it
+            Lut = cmsPipelineDup(Lut);
 
-        // We need to adjust data only for Lab16 on output
-        if (OriginalType != cmsSigLut16Type || cmsGetPCS(hProfile) != cmsSigLabData)
-            return Lut;
+            // We need to adjust data only for Lab16 on output
+            if (OriginalType != cmsSigLut16Type || cmsGetPCS(hProfile) != cmsSigLabData)
+                return Lut;
 
-        // If the input is Lab, add also a conversion at the begin
-        if (cmsGetColorSpace(hProfile) == cmsSigLabData &&
-            !cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID)))
-            goto Error;
+            // If the input is Lab, add also a conversion at the begin
+            if (cmsGetColorSpace(hProfile) == cmsSigLabData &&
+                !cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID)))
+                goto Error;
 
-        // Add a matrix for conversion V2 to V4 Lab PCS
-        if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID)))
-            goto Error;
+            // Add a matrix for conversion V2 to V4 Lab PCS
+            if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID)))
+                goto Error;
 
-        return Lut;
+            return Lut;
 Error:
-        cmsPipelineFree(Lut);
-        return NULL;
+            cmsPipelineFree(Lut);
+            return NULL;
+        }
     }
 
     // Lut was not found, try to create a matrix-shaper
@@ -551,7 +557,7 @@
                 _cmsStageCLutData* CLUT = (_cmsStageCLutData*) Stage ->Data;
 
                 CLUT ->Params->dwFlags |= CMS_LERP_FLAGS_TRILINEAR;
-                _cmsSetInterpolationRoutine(CLUT ->Params);
+                _cmsSetInterpolationRoutine(Lut->ContextID, CLUT ->Params);
             }
     }
 }
@@ -609,54 +615,58 @@
     cmsTagSignature tagFloat = PCS2DeviceFloat[Intent];
     cmsContext ContextID     = cmsGetProfileContextID(hProfile);
 
-    if (cmsIsTag(hProfile, tagFloat)) {  // Float tag takes precedence
+
+    if (Intent != -1) {
 
-        // Floating point LUT are always V4
-        return _cmsReadFloatOutputTag(hProfile, tagFloat);
-    }
+        if (cmsIsTag(hProfile, tagFloat)) {  // Float tag takes precedence
+
+            // Floating point LUT are always V4
+            return _cmsReadFloatOutputTag(hProfile, tagFloat);
+        }
 
-    // Revert to perceptual if no tag is found
-    if (!cmsIsTag(hProfile, tag16)) {
-        tag16 = PCS2Device16[0];
-    }
+        // Revert to perceptual if no tag is found
+        if (!cmsIsTag(hProfile, tag16)) {
+            tag16 = PCS2Device16[0];
+        }
 
-    if (cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table?
-
-        // Check profile version and LUT type. Do the necessary adjustments if needed
+        if (cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table?
 
-        // First read the tag
-        cmsPipeline* Lut = (cmsPipeline*) cmsReadTag(hProfile, tag16);
-        if (Lut == NULL) return NULL;
+            // Check profile version and LUT type. Do the necessary adjustments if needed
 
-        // After reading it, we have info about the original type
-        OriginalType =  _cmsGetTagTrueType(hProfile, tag16);
+            // First read the tag
+            cmsPipeline* Lut = (cmsPipeline*) cmsReadTag(hProfile, tag16);
+            if (Lut == NULL) return NULL;
 
-        // The profile owns the Lut, so we need to copy it
-        Lut = cmsPipelineDup(Lut);
-        if (Lut == NULL) return NULL;
+            // After reading it, we have info about the original type
+            OriginalType =  _cmsGetTagTrueType(hProfile, tag16);
 
-        // Now it is time for a controversial stuff. I found that for 3D LUTS using
-        // Lab used as indexer space,  trilinear interpolation should be used
-        if (cmsGetPCS(hProfile) == cmsSigLabData)
-            ChangeInterpolationToTrilinear(Lut);
+            // The profile owns the Lut, so we need to copy it
+            Lut = cmsPipelineDup(Lut);
+            if (Lut == NULL) return NULL;
 
-        // We need to adjust data only for Lab and Lut16 type
-        if (OriginalType != cmsSigLut16Type || cmsGetPCS(hProfile) != cmsSigLabData)
-            return Lut;
+            // Now it is time for a controversial stuff. I found that for 3D LUTS using
+            // Lab used as indexer space,  trilinear interpolation should be used
+            if (cmsGetPCS(hProfile) == cmsSigLabData)
+                ChangeInterpolationToTrilinear(Lut);
 
-        // Add a matrix for conversion V4 to V2 Lab PCS
-        if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID)))
-            goto Error;
+            // We need to adjust data only for Lab and Lut16 type
+            if (OriginalType != cmsSigLut16Type || cmsGetPCS(hProfile) != cmsSigLabData)
+                return Lut;
 
-        // If the output is Lab, add also a conversion at the end
-        if (cmsGetColorSpace(hProfile) == cmsSigLabData)
-            if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID)))
+            // Add a matrix for conversion V4 to V2 Lab PCS
+            if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID)))
                 goto Error;
 
-        return Lut;
+            // If the output is Lab, add also a conversion at the end
+            if (cmsGetColorSpace(hProfile) == cmsSigLabData)
+                if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID)))
+                    goto Error;
+
+            return Lut;
 Error:
-        cmsPipelineFree(Lut);
-        return NULL;
+            cmsPipelineFree(Lut);
+            return NULL;
+        }
     }
 
     // Lut not found, try to create a matrix-shaper
@@ -782,7 +792,7 @@
 
     // Now it is time for a controversial stuff. I found that for 3D LUTS using
     // Lab used as indexer space,  trilinear interpolation should be used
-    if (cmsGetColorSpace(hProfile) == cmsSigLabData)
+    if (cmsGetPCS(hProfile) == cmsSigLabData)
         ChangeInterpolationToTrilinear(Lut);
 
     // After reading it, we have info about the original type
@@ -793,12 +803,12 @@
 
     // Here it is possible to get Lab on both sides
 
-    if (cmsGetPCS(hProfile) == cmsSigLabData) {
+    if (cmsGetColorSpace(hProfile) == cmsSigLabData) {
         if(!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID)))
             goto Error2;
     }
 
-    if (cmsGetColorSpace(hProfile) == cmsSigLabData) {
+    if (cmsGetPCS(hProfile) == cmsSigLabData) {
         if(!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID)))
             goto Error2;
     }
--- a/jdk/src/java.desktop/share/native/liblcms/cmsopt.c	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.desktop/share/native/liblcms/cmsopt.c	Wed Jul 05 20:01:50 2017 +0200
@@ -542,11 +542,13 @@
 
             cmsToneCurve* InversePostLin = cmsReverseToneCurve(Curves[i]);
             if (InversePostLin == NULL) {
-                WhiteOut[i] = 0;
-                continue;
+                WhiteOut[i] = WhitePointOut[i];
+
+            } else {
+
+                WhiteOut[i] = cmsEvalToneCurve16(InversePostLin, WhitePointOut[i]);
+                cmsFreeToneCurve(InversePostLin);
             }
-            WhiteOut[i] = cmsEvalToneCurve16(InversePostLin, WhitePointOut[i]);
-            cmsFreeToneCurve(InversePostLin);
         }
     }
     else {
@@ -1666,44 +1668,102 @@
 };
 
 // The linked list head
-static _cmsOptimizationCollection* OptimizationCollection = DefaultOptimization;
+_cmsOptimizationPluginChunkType _cmsOptimizationPluginChunk = { NULL };
+
+
+// Duplicates the zone of memory used by the plug-in in the new context
+static
+void DupPluginOptimizationList(struct _cmsContext_struct* ctx,
+                               const struct _cmsContext_struct* src)
+{
+   _cmsOptimizationPluginChunkType newHead = { NULL };
+   _cmsOptimizationCollection*  entry;
+   _cmsOptimizationCollection*  Anterior = NULL;
+   _cmsOptimizationPluginChunkType* head = (_cmsOptimizationPluginChunkType*) src->chunks[OptimizationPlugin];
+
+    _cmsAssert(ctx != NULL);
+    _cmsAssert(head != NULL);
+
+    // Walk the list copying all nodes
+   for (entry = head->OptimizationCollection;
+        entry != NULL;
+        entry = entry ->Next) {
+
+            _cmsOptimizationCollection *newEntry = ( _cmsOptimizationCollection *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(_cmsOptimizationCollection));
+
+            if (newEntry == NULL)
+                return;
+
+            // We want to keep the linked list order, so this is a little bit tricky
+            newEntry -> Next = NULL;
+            if (Anterior)
+                Anterior -> Next = newEntry;
+
+            Anterior = newEntry;
+
+            if (newHead.OptimizationCollection == NULL)
+                newHead.OptimizationCollection = newEntry;
+    }
+
+  ctx ->chunks[OptimizationPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsOptimizationPluginChunkType));
+}
+
+void  _cmsAllocOptimizationPluginChunk(struct _cmsContext_struct* ctx,
+                                         const struct _cmsContext_struct* src)
+{
+  if (src != NULL) {
+
+        // Copy all linked list
+       DupPluginOptimizationList(ctx, src);
+    }
+    else {
+        static _cmsOptimizationPluginChunkType OptimizationPluginChunkType = { NULL };
+        ctx ->chunks[OptimizationPlugin] = _cmsSubAllocDup(ctx ->MemPool, &OptimizationPluginChunkType, sizeof(_cmsOptimizationPluginChunkType));
+    }
+}
+
 
 // Register new ways to optimize
-cmsBool  _cmsRegisterOptimizationPlugin(cmsContext id, cmsPluginBase* Data)
+cmsBool  _cmsRegisterOptimizationPlugin(cmsContext ContextID, cmsPluginBase* Data)
 {
     cmsPluginOptimization* Plugin = (cmsPluginOptimization*) Data;
+    _cmsOptimizationPluginChunkType* ctx = ( _cmsOptimizationPluginChunkType*) _cmsContextGetClientChunk(ContextID, OptimizationPlugin);
     _cmsOptimizationCollection* fl;
 
     if (Data == NULL) {
 
-        OptimizationCollection = DefaultOptimization;
+        ctx->OptimizationCollection = NULL;
         return TRUE;
     }
 
     // Optimizer callback is required
     if (Plugin ->OptimizePtr == NULL) return FALSE;
 
-    fl = (_cmsOptimizationCollection*) _cmsPluginMalloc(id, sizeof(_cmsOptimizationCollection));
+    fl = (_cmsOptimizationCollection*) _cmsPluginMalloc(ContextID, sizeof(_cmsOptimizationCollection));
     if (fl == NULL) return FALSE;
 
     // Copy the parameters
     fl ->OptimizePtr = Plugin ->OptimizePtr;
 
     // Keep linked list
-    fl ->Next = OptimizationCollection;
-    OptimizationCollection = fl;
+    fl ->Next = ctx->OptimizationCollection;
+
+    // Set the head
+    ctx ->OptimizationCollection = fl;
 
     // All is ok
     return TRUE;
 }
 
 // The entry point for LUT optimization
-cmsBool _cmsOptimizePipeline(cmsPipeline**    PtrLut,
+cmsBool _cmsOptimizePipeline(cmsContext ContextID,
+                             cmsPipeline**    PtrLut,
                              int              Intent,
                              cmsUInt32Number* InputFormat,
                              cmsUInt32Number* OutputFormat,
                              cmsUInt32Number* dwFlags)
 {
+    _cmsOptimizationPluginChunkType* ctx = ( _cmsOptimizationPluginChunkType*) _cmsContextGetClientChunk(ContextID, OptimizationPlugin);
     _cmsOptimizationCollection* Opts;
     cmsBool AnySuccess = FALSE;
 
@@ -1733,8 +1793,8 @@
     if (*dwFlags & cmsFLAGS_NOOPTIMIZE)
         return FALSE;
 
-    // Try built-in optimizations and plug-in
-    for (Opts = OptimizationCollection;
+    // Try plug-in optimizations
+    for (Opts = ctx->OptimizationCollection;
          Opts != NULL;
          Opts = Opts ->Next) {
 
@@ -1745,6 +1805,17 @@
             }
     }
 
+   // Try built-in optimizations
+    for (Opts = DefaultOptimization;
+         Opts != NULL;
+         Opts = Opts ->Next) {
+
+            if (Opts ->OptimizePtr(PtrLut, Intent, InputFormat, OutputFormat, dwFlags)) {
+
+                return TRUE;
+            }
+    }
+
     // Only simple optimizations succeeded
     return AnySuccess;
 }
--- a/jdk/src/java.desktop/share/native/liblcms/cmspack.c	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.desktop/share/native/liblcms/cmspack.c	Wed Jul 05 20:01:50 2017 +0200
@@ -883,6 +883,42 @@
     }
 }
 
+// This is a conversion of XYZ float to 16 bits
+static
+cmsUInt8Number* UnrollXYZFloatTo16(register _cmsTRANSFORM* info,
+                                   register cmsUInt16Number wIn[],
+                                   register cmsUInt8Number* accum,
+                                   register cmsUInt32Number Stride)
+{
+    if (T_PLANAR(info -> InputFormat)) {
+
+        cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
+        cmsCIEXYZ XYZ;
+
+        XYZ.X = Pt[0];
+        XYZ.Y = Pt[Stride];
+        XYZ.Z = Pt[Stride*2];
+        cmsFloat2XYZEncoded(wIn, &XYZ);
+
+        return accum + sizeof(cmsFloat32Number);
+
+    }
+
+    else {
+        cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
+        cmsCIEXYZ XYZ;
+
+        XYZ.X = Pt[0];
+        XYZ.Y = Pt[1];
+        XYZ.Z = Pt[2];
+        cmsFloat2XYZEncoded(wIn, &XYZ);
+
+        accum += 3 * sizeof(cmsFloat32Number) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat32Number);
+
+        return accum;
+    }
+}
+
 // Check if space is marked as ink
 cmsINLINE cmsBool IsInkSpace(cmsUInt32Number Type)
 {
@@ -2334,6 +2370,39 @@
 }
 
 static
+cmsUInt8Number* PackXYZFloatFrom16(register _cmsTRANSFORM* Info,
+                                   register cmsUInt16Number wOut[],
+                                   register cmsUInt8Number* output,
+                                   register cmsUInt32Number Stride)
+{
+    if (T_PLANAR(Info -> OutputFormat)) {
+
+        cmsCIEXYZ XYZ;
+        cmsFloat32Number* Out = (cmsFloat32Number*) output;
+        cmsXYZEncoded2Float(&XYZ, wOut);
+
+        Out[0]        = (cmsFloat32Number) XYZ.X;
+        Out[Stride]   = (cmsFloat32Number) XYZ.Y;
+        Out[Stride*2] = (cmsFloat32Number) XYZ.Z;
+
+        return output + sizeof(cmsFloat32Number);
+
+    }
+    else {
+
+        cmsCIEXYZ XYZ;
+        cmsFloat32Number* Out = (cmsFloat32Number*) output;
+        cmsXYZEncoded2Float(&XYZ, wOut);
+
+        Out[0] = (cmsFloat32Number) XYZ.X;
+        Out[1] = (cmsFloat32Number) XYZ.Y;
+        Out[2] = (cmsFloat32Number) XYZ.Z;
+
+        return output + (3 * sizeof(cmsFloat32Number) + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number));
+    }
+}
+
+static
 cmsUInt8Number* PackDoubleFrom16(register _cmsTRANSFORM* info,
                                 register cmsUInt16Number wOut[],
                                 register cmsUInt8Number* output,
@@ -2893,6 +2962,7 @@
     { TYPE_Lab_DBL,                                 ANYPLANAR|ANYEXTRA,   UnrollLabDoubleTo16},
     { TYPE_XYZ_DBL,                                 ANYPLANAR|ANYEXTRA,   UnrollXYZDoubleTo16},
     { TYPE_Lab_FLT,                                 ANYPLANAR|ANYEXTRA,   UnrollLabFloatTo16},
+    { TYPE_XYZ_FLT,                                 ANYPLANAR|ANYEXTRA,   UnrollXYZFloatTo16},
     { TYPE_GRAY_DBL,                                                 0,   UnrollDouble1Chan},
     { FLOAT_SH(1)|BYTES_SH(0), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR|
                                              ANYSWAP|ANYEXTRA|ANYSPACE,   UnrollDoubleTo16},
@@ -3027,6 +3097,7 @@
     { TYPE_XYZ_DBL,                                      ANYPLANAR|ANYEXTRA,  PackXYZDoubleFrom16},
 
     { TYPE_Lab_FLT,                                      ANYPLANAR|ANYEXTRA,  PackLabFloatFrom16},
+    { TYPE_XYZ_FLT,                                      ANYPLANAR|ANYEXTRA,  PackXYZFloatFrom16},
 
     { FLOAT_SH(1)|BYTES_SH(0),      ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
                                     ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE,  PackDoubleFrom16},
@@ -3182,40 +3253,98 @@
 
 } cmsFormattersFactoryList;
 
-static cmsFormattersFactoryList* FactoryList = NULL;
+_cmsFormattersPluginChunkType _cmsFormattersPluginChunk = { NULL };
+
+
+// Duplicates the zone of memory used by the plug-in in the new context
+static
+void DupFormatterFactoryList(struct _cmsContext_struct* ctx,
+                                               const struct _cmsContext_struct* src)
+{
+   _cmsFormattersPluginChunkType newHead = { NULL };
+   cmsFormattersFactoryList*  entry;
+   cmsFormattersFactoryList*  Anterior = NULL;
+   _cmsFormattersPluginChunkType* head = (_cmsFormattersPluginChunkType*) src->chunks[FormattersPlugin];
+
+     _cmsAssert(head != NULL);
+
+   // Walk the list copying all nodes
+   for (entry = head->FactoryList;
+       entry != NULL;
+       entry = entry ->Next) {
+
+           cmsFormattersFactoryList *newEntry = ( cmsFormattersFactoryList *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(cmsFormattersFactoryList));
+
+           if (newEntry == NULL)
+               return;
+
+           // We want to keep the linked list order, so this is a little bit tricky
+           newEntry -> Next = NULL;
+           if (Anterior)
+               Anterior -> Next = newEntry;
+
+           Anterior = newEntry;
+
+           if (newHead.FactoryList == NULL)
+               newHead.FactoryList = newEntry;
+   }
+
+   ctx ->chunks[FormattersPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsFormattersPluginChunkType));
+}
+
+// The interpolation plug-in memory chunk allocator/dup
+void _cmsAllocFormattersPluginChunk(struct _cmsContext_struct* ctx,
+                                    const struct _cmsContext_struct* src)
+{
+      _cmsAssert(ctx != NULL);
+
+     if (src != NULL) {
+
+         // Duplicate the LIST
+         DupFormatterFactoryList(ctx, src);
+     }
+     else {
+          static _cmsFormattersPluginChunkType FormattersPluginChunk = { NULL };
+          ctx ->chunks[FormattersPlugin] = _cmsSubAllocDup(ctx ->MemPool, &FormattersPluginChunk, sizeof(_cmsFormattersPluginChunkType));
+     }
+}
+
 
 
 // Formatters management
-cmsBool  _cmsRegisterFormattersPlugin(cmsContext id, cmsPluginBase* Data)
+cmsBool  _cmsRegisterFormattersPlugin(cmsContext ContextID, cmsPluginBase* Data)
 {
+    _cmsFormattersPluginChunkType* ctx = ( _cmsFormattersPluginChunkType*) _cmsContextGetClientChunk(ContextID, FormattersPlugin);
     cmsPluginFormatters* Plugin = (cmsPluginFormatters*) Data;
     cmsFormattersFactoryList* fl ;
 
-    // Reset
+    // Reset to built-in defaults
     if (Data == NULL) {
 
-          FactoryList = NULL;
+          ctx ->FactoryList = NULL;
           return TRUE;
     }
 
-    fl = (cmsFormattersFactoryList*) _cmsPluginMalloc(id, sizeof(cmsFormattersFactoryList));
+    fl = (cmsFormattersFactoryList*) _cmsPluginMalloc(ContextID, sizeof(cmsFormattersFactoryList));
     if (fl == NULL) return FALSE;
 
     fl ->Factory    = Plugin ->FormattersFactory;
 
-    fl ->Next = FactoryList;
-    FactoryList = fl;
+    fl ->Next = ctx -> FactoryList;
+    ctx ->FactoryList = fl;
 
     return TRUE;
 }
 
-cmsFormatter _cmsGetFormatter(cmsUInt32Number Type,         // Specific type, i.e. TYPE_RGB_8
+cmsFormatter _cmsGetFormatter(cmsContext ContextID,
+                             cmsUInt32Number Type,         // Specific type, i.e. TYPE_RGB_8
                              cmsFormatterDirection Dir,
                              cmsUInt32Number dwFlags)
 {
+    _cmsFormattersPluginChunkType* ctx = ( _cmsFormattersPluginChunkType*) _cmsContextGetClientChunk(ContextID, FormattersPlugin);
     cmsFormattersFactoryList* f;
 
-    for (f = FactoryList; f != NULL; f = f ->Next) {
+    for (f =ctx->FactoryList; f != NULL; f = f ->Next) {
 
         cmsFormatter fn = f ->Factory(Type, Dir, dwFlags);
         if (fn.Fmt16 != NULL) return fn;
--- a/jdk/src/java.desktop/share/native/liblcms/cmsplugin.c	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.desktop/share/native/liblcms/cmsplugin.c	Wed Jul 05 20:01:50 2017 +0200
@@ -544,22 +544,31 @@
 
 // Plugin memory management -------------------------------------------------------------------------------------------------
 
-static _cmsSubAllocator* PluginPool = NULL;
-
 // Specialized malloc for plug-ins, that is freed upon exit.
-void* _cmsPluginMalloc(cmsContext id, cmsUInt32Number size)
+void* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size)
 {
-    if (PluginPool == NULL)
-        PluginPool = _cmsCreateSubAlloc(id, 4*1024);
+    struct _cmsContext_struct* ctx = _cmsGetContext(ContextID);
+
+    if (ctx ->MemPool == NULL) {
+
+        if (ContextID == NULL) {
 
-    return _cmsSubAlloc(PluginPool, size);
+            ctx->MemPool = _cmsCreateSubAlloc(0, 2*1024);
+        }
+        else {
+            cmsSignalError(ContextID, cmsERROR_CORRUPTION_DETECTED, "NULL memory pool on context");
+            return NULL;
+        }
+    }
+
+    return _cmsSubAlloc(ctx->MemPool, size);
 }
 
 
 // Main plug-in dispatcher
 cmsBool CMSEXPORT cmsPlugin(void* Plug_in)
 {
-  return cmsPluginTHR(NULL, Plug_in);
+    return cmsPluginTHR(NULL, Plug_in);
 }
 
 cmsBool CMSEXPORT cmsPluginTHR(cmsContext id, void* Plug_in)
@@ -571,12 +580,12 @@
          Plugin = Plugin -> Next) {
 
             if (Plugin -> Magic != cmsPluginMagicNumber) {
-                cmsSignalError(0, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin");
+                cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin");
                 return FALSE;
             }
 
             if (Plugin ->ExpectedVersion > LCMS_VERSION) {
-                cmsSignalError(0, cmsERROR_UNKNOWN_EXTENSION, "plugin needs Little CMS %d, current  version is %d",
+                cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "plugin needs Little CMS %d, current version is %d",
                     Plugin ->ExpectedVersion, LCMS_VERSION);
                 return FALSE;
             }
@@ -584,11 +593,11 @@
             switch (Plugin -> Type) {
 
                 case cmsPluginMemHandlerSig:
-                    if (!_cmsRegisterMemHandlerPlugin(Plugin)) return FALSE;
+                    if (!_cmsRegisterMemHandlerPlugin(id, Plugin)) return FALSE;
                     break;
 
                 case cmsPluginInterpolationSig:
-                    if (!_cmsRegisterInterpPlugin(Plugin)) return FALSE;
+                    if (!_cmsRegisterInterpPlugin(id, Plugin)) return FALSE;
                     break;
 
                 case cmsPluginTagTypeSig:
@@ -623,8 +632,12 @@
                     if (!_cmsRegisterTransformPlugin(id, Plugin)) return FALSE;
                     break;
 
+                case cmsPluginMutexSig:
+                    if (!_cmsRegisterMutexPlugin(id, Plugin)) return FALSE;
+                    break;
+
                 default:
-                    cmsSignalError(0, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin type '%X'", Plugin -> Type);
+                    cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin type '%X'", Plugin -> Type);
                     return FALSE;
             }
     }
@@ -637,19 +650,337 @@
 // Revert all plug-ins to default
 void CMSEXPORT cmsUnregisterPlugins(void)
 {
-    _cmsRegisterMemHandlerPlugin(NULL);
-    _cmsRegisterInterpPlugin(NULL);
-    _cmsRegisterTagTypePlugin(NULL, NULL);
-    _cmsRegisterTagPlugin(NULL, NULL);
-    _cmsRegisterFormattersPlugin(NULL, NULL);
-    _cmsRegisterRenderingIntentPlugin(NULL, NULL);
-    _cmsRegisterParametricCurvesPlugin(NULL, NULL);
-    _cmsRegisterMultiProcessElementPlugin(NULL, NULL);
-    _cmsRegisterOptimizationPlugin(NULL, NULL);
-    _cmsRegisterTransformPlugin(NULL, NULL);
+    cmsUnregisterPluginsTHR(NULL);
+}
+
+
+// The Global storage for system context. This is the one and only global variable
+// pointers structure. All global vars are referenced here.
+static struct _cmsContext_struct globalContext = {
+
+    NULL,                              // Not in the linked list
+    NULL,                              // No suballocator
+    {
+        NULL,                          //  UserPtr,
+        &_cmsLogErrorChunk,            //  Logger,
+        &_cmsAlarmCodesChunk,          //  AlarmCodes,
+        &_cmsAdaptationStateChunk,     //  AdaptationState,
+        &_cmsMemPluginChunk,           //  MemPlugin,
+        &_cmsInterpPluginChunk,        //  InterpPlugin,
+        &_cmsCurvesPluginChunk,        //  CurvesPlugin,
+        &_cmsFormattersPluginChunk,    //  FormattersPlugin,
+        &_cmsTagTypePluginChunk,       //  TagTypePlugin,
+        &_cmsTagPluginChunk,           //  TagPlugin,
+        &_cmsIntentsPluginChunk,       //  IntentPlugin,
+        &_cmsMPETypePluginChunk,       //  MPEPlugin,
+        &_cmsOptimizationPluginChunk,  //  OptimizationPlugin,
+        &_cmsTransformPluginChunk,     //  TransformPlugin,
+        &_cmsMutexPluginChunk          //  MutexPlugin
+    },
+
+    { NULL, NULL, NULL, NULL, NULL, NULL } // The default memory allocator is not used for context 0
+};
+
+
+// The context pool (linked list head)
+static _cmsMutex _cmsContextPoolHeadMutex = CMS_MUTEX_INITIALIZER;
+static struct _cmsContext_struct* _cmsContextPoolHead = NULL;
+
+// Internal, get associated pointer, with guessing. Never returns NULL.
+struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID)
+{
+    struct _cmsContext_struct* id = (struct _cmsContext_struct*) ContextID;
+    struct _cmsContext_struct* ctx;
+
+
+    // On 0, use global settings
+    if (id == NULL)
+        return &globalContext;
+
+    // Search
+    for (ctx = _cmsContextPoolHead;
+         ctx != NULL;
+         ctx = ctx ->Next) {
+
+            // Found it?
+            if (id == ctx)
+                return ctx; // New-style context,
+    }
+
+    return &globalContext;
+}
+
+
+// Internal: get the memory area associanted with each context client
+// Returns the block assigned to the specific zone.
+void* _cmsContextGetClientChunk(cmsContext ContextID, _cmsMemoryClient mc)
+{
+    struct _cmsContext_struct* ctx;
+    void *ptr;
+
+    if (mc < 0 || mc >= MemoryClientMax) {
+        cmsSignalError(ContextID, cmsERROR_RANGE, "Bad context client");
+        return NULL;
+    }
+
+    ctx = _cmsGetContext(ContextID);
+    ptr = ctx ->chunks[mc];
+
+    if (ptr != NULL)
+        return ptr;
+
+    // A null ptr means no special settings for that context, and this
+    // reverts to Context0 globals
+    return globalContext.chunks[mc];
+}
+
+
+// This function returns the given context its default pristine state,
+// as no plug-ins were declared. There is no way to unregister a single
+// plug-in, as a single call to cmsPluginTHR() function may register
+// many different plug-ins simultaneously, then there is no way to
+// identify which plug-in to unregister.
+void CMSEXPORT cmsUnregisterPluginsTHR(cmsContext ContextID)
+{
+    _cmsRegisterMemHandlerPlugin(ContextID, NULL);
+    _cmsRegisterInterpPlugin(ContextID, NULL);
+    _cmsRegisterTagTypePlugin(ContextID, NULL);
+    _cmsRegisterTagPlugin(ContextID, NULL);
+    _cmsRegisterFormattersPlugin(ContextID, NULL);
+    _cmsRegisterRenderingIntentPlugin(ContextID, NULL);
+    _cmsRegisterParametricCurvesPlugin(ContextID, NULL);
+    _cmsRegisterMultiProcessElementPlugin(ContextID, NULL);
+    _cmsRegisterOptimizationPlugin(ContextID, NULL);
+    _cmsRegisterTransformPlugin(ContextID, NULL);
+    _cmsRegisterMutexPlugin(ContextID, NULL);
+}
+
+
+// Returns the memory manager plug-in, if any, from the Plug-in bundle
+static
+cmsPluginMemHandler* _cmsFindMemoryPlugin(void* PluginBundle)
+{
+    cmsPluginBase* Plugin;
+
+    for (Plugin = (cmsPluginBase*) PluginBundle;
+        Plugin != NULL;
+        Plugin = Plugin -> Next) {
+
+            if (Plugin -> Magic == cmsPluginMagicNumber &&
+                Plugin -> ExpectedVersion <= LCMS_VERSION &&
+                Plugin -> Type == cmsPluginMemHandlerSig) {
+
+                    // Found!
+                    return (cmsPluginMemHandler*) Plugin;
+            }
+    }
+
+    // Nope, revert to defaults
+    return NULL;
+}
+
+
+// Creates a new context with optional associated plug-ins. Caller may also specify an optional pointer to user-defined
+// data that will be forwarded to plug-ins and logger.
+cmsContext CMSEXPORT cmsCreateContext(void* Plugin, void* UserData)
+{
+    struct _cmsContext_struct* ctx;
+    struct _cmsContext_struct  fakeContext;
+
+    _cmsInstallAllocFunctions(_cmsFindMemoryPlugin(Plugin), &fakeContext.DefaultMemoryManager);
+
+    fakeContext.chunks[UserPtr]     = UserData;
+    fakeContext.chunks[MemPlugin]   = &fakeContext.DefaultMemoryManager;
+
+    // Create the context structure.
+    ctx = (struct _cmsContext_struct*) _cmsMalloc(&fakeContext, sizeof(struct _cmsContext_struct));
+    if (ctx == NULL)
+        return NULL;     // Something very wrong happened!
+
+    // Init the structure and the memory manager
+    memset(ctx, 0, sizeof(struct _cmsContext_struct));
+
+    // Keep memory manager
+    memcpy(&ctx->DefaultMemoryManager, &fakeContext.DefaultMemoryManager, sizeof(_cmsMemPluginChunk));
+
+    // Maintain the linked list (with proper locking)
+    _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
+       ctx ->Next = _cmsContextPoolHead;
+       _cmsContextPoolHead = ctx;
+    _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
+
+    ctx ->chunks[UserPtr]     = UserData;
+    ctx ->chunks[MemPlugin]   = &ctx->DefaultMemoryManager;
+
+    // Now we can allocate the pool by using default memory manager
+    ctx ->MemPool = _cmsCreateSubAlloc(ctx, 22 * sizeof(void*));  // default size about 32 pointers
+    if (ctx ->MemPool == NULL) {
 
-    if (PluginPool != NULL)
-        _cmsSubAllocDestroy(PluginPool);
+         cmsDeleteContext(ctx);
+        return NULL;
+    }
+
+    _cmsAllocLogErrorChunk(ctx, NULL);
+    _cmsAllocAlarmCodesChunk(ctx, NULL);
+    _cmsAllocAdaptationStateChunk(ctx, NULL);
+    _cmsAllocMemPluginChunk(ctx, NULL);
+    _cmsAllocInterpPluginChunk(ctx, NULL);
+    _cmsAllocCurvesPluginChunk(ctx, NULL);
+    _cmsAllocFormattersPluginChunk(ctx, NULL);
+    _cmsAllocTagTypePluginChunk(ctx, NULL);
+    _cmsAllocMPETypePluginChunk(ctx, NULL);
+    _cmsAllocTagPluginChunk(ctx, NULL);
+    _cmsAllocIntentsPluginChunk(ctx, NULL);
+    _cmsAllocOptimizationPluginChunk(ctx, NULL);
+    _cmsAllocTransformPluginChunk(ctx, NULL);
+    _cmsAllocMutexPluginChunk(ctx, NULL);
+
+    // Setup the plug-ins
+    if (!cmsPluginTHR(ctx, Plugin)) {
+
+        cmsDeleteContext(ctx);
+        return NULL;
+    }
+
+    return (cmsContext) ctx;
+}
+
+// Duplicates a context with all associated plug-ins.
+// Caller may specify an optional pointer to user-defined
+// data that will be forwarded to plug-ins and logger.
+cmsContext CMSEXPORT cmsDupContext(cmsContext ContextID, void* NewUserData)
+{
+    int i;
+    struct _cmsContext_struct* ctx;
+    const struct _cmsContext_struct* src = _cmsGetContext(ContextID);
+
+    void* userData = (NewUserData != NULL) ? NewUserData : src -> chunks[UserPtr];
+
+
+    ctx = (struct _cmsContext_struct*) _cmsMalloc(ContextID, sizeof(struct _cmsContext_struct));
+    if (ctx == NULL)
+        return NULL;     // Something very wrong happened
+
+    // Setup default memory allocators
+    memcpy(&ctx->DefaultMemoryManager, &src->DefaultMemoryManager, sizeof(ctx->DefaultMemoryManager));
+
+    // Maintain the linked list
+    _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
+       ctx ->Next = _cmsContextPoolHead;
+       _cmsContextPoolHead = ctx;
+    _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
+
+    ctx ->chunks[UserPtr]    = userData;
+    ctx ->chunks[MemPlugin]  = &ctx->DefaultMemoryManager;
+
+    ctx ->MemPool = _cmsCreateSubAlloc(ctx, 22 * sizeof(void*));
+    if (ctx ->MemPool == NULL) {
+
+         cmsDeleteContext(ctx);
+        return NULL;
+    }
+
+    // Allocate all required chunks.
+    _cmsAllocLogErrorChunk(ctx, src);
+    _cmsAllocAlarmCodesChunk(ctx, src);
+    _cmsAllocAdaptationStateChunk(ctx, src);
+    _cmsAllocMemPluginChunk(ctx, src);
+    _cmsAllocInterpPluginChunk(ctx, src);
+    _cmsAllocCurvesPluginChunk(ctx, src);
+    _cmsAllocFormattersPluginChunk(ctx, src);
+    _cmsAllocTagTypePluginChunk(ctx, src);
+    _cmsAllocMPETypePluginChunk(ctx, src);
+    _cmsAllocTagPluginChunk(ctx, src);
+    _cmsAllocIntentsPluginChunk(ctx, src);
+    _cmsAllocOptimizationPluginChunk(ctx, src);
+    _cmsAllocTransformPluginChunk(ctx, src);
+    _cmsAllocMutexPluginChunk(ctx, src);
+
+    // Make sure no one failed
+    for (i=Logger; i < MemoryClientMax; i++) {
 
-    PluginPool = NULL;
+        if (src ->chunks[i] == NULL) {
+            cmsDeleteContext((cmsContext) ctx);
+            return NULL;
+        }
+    }
+
+    return (cmsContext) ctx;
+}
+
+
+
+static
+struct _cmsContext_struct* FindPrev(struct _cmsContext_struct* id)
+{
+    struct _cmsContext_struct* prev;
+
+    // Search for previous
+    for (prev = _cmsContextPoolHead;
+             prev != NULL;
+             prev = prev ->Next)
+    {
+        if (prev ->Next == id)
+            return prev;
+    }
+
+    return NULL;  // List is empty or only one element!
 }
+
+// Frees any resources associated with the given context,
+// and destroys the context placeholder.
+// The ContextID can no longer be used in any THR operation.
+void CMSEXPORT cmsDeleteContext(cmsContext ContextID)
+{
+    if (ContextID != NULL) {
+
+        struct _cmsContext_struct* ctx = (struct _cmsContext_struct*) ContextID;
+        struct _cmsContext_struct  fakeContext;
+        struct _cmsContext_struct* prev;
+
+        memcpy(&fakeContext.DefaultMemoryManager, &ctx->DefaultMemoryManager, sizeof(ctx->DefaultMemoryManager));
+
+        fakeContext.chunks[UserPtr]     = ctx ->chunks[UserPtr];
+        fakeContext.chunks[MemPlugin]   = &fakeContext.DefaultMemoryManager;
+
+        // Get rid of plugins
+        cmsUnregisterPluginsTHR(ContextID);
+
+        // Since all memory is allocated in the private pool, all what we need to do is destroy the pool
+        if (ctx -> MemPool != NULL)
+              _cmsSubAllocDestroy(ctx ->MemPool);
+        ctx -> MemPool = NULL;
+
+        // Maintain list
+        _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
+        if (_cmsContextPoolHead == ctx) {
+
+            _cmsContextPoolHead = ctx->Next;
+        }
+        else {
+
+            // Search for previous
+            for (prev = _cmsContextPoolHead;
+                prev != NULL;
+                prev = prev ->Next)
+            {
+                if (prev -> Next == ctx) {
+                    prev -> Next = ctx ->Next;
+                    break;
+                }
+            }
+        }
+        _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
+
+        // free the memory block itself
+        _cmsFree(&fakeContext, ctx);
+    }
+}
+
+// Returns the user data associated to the given ContextID, or NULL if no user data was attached on context creation
+void* CMSEXPORT cmsGetContextUserData(cmsContext ContextID)
+{
+    return _cmsContextGetClientChunk(ContextID, UserPtr);
+}
+
+
--- a/jdk/src/java.desktop/share/native/liblcms/cmsps2.c	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.desktop/share/native/liblcms/cmsps2.c	Wed Jul 05 20:01:50 2017 +0200
@@ -942,7 +942,7 @@
             if (DeviceLink == NULL) return 0;
 
             dwFlags |= cmsFLAGS_FORCE_CLUT;
-            _cmsOptimizePipeline(&DeviceLink, Intent, &InputFormat, &OutFrm, &dwFlags);
+            _cmsOptimizePipeline(m->ContextID, &DeviceLink, Intent, &InputFormat, &OutFrm, &dwFlags);
 
             rc = EmitCIEBasedDEF(m, DeviceLink, Intent, &BlackPointAdaptedToD50);
             cmsPipelineFree(DeviceLink);
@@ -1359,7 +1359,7 @@
 
     // We need a CLUT
     dwFlags |= cmsFLAGS_FORCE_CLUT;
-    _cmsOptimizePipeline(&DeviceLink, RelativeEncodingIntent, &InFrm, &OutputFormat, &dwFlags);
+    _cmsOptimizePipeline(m->ContextID, &DeviceLink, RelativeEncodingIntent, &InFrm, &OutputFormat, &dwFlags);
 
     _cmsIOPrintf(m, "<<\n");
     _cmsIOPrintf(m, "/ColorRenderingType 1\n");
--- a/jdk/src/java.desktop/share/native/liblcms/cmstypes.c	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.desktop/share/native/liblcms/cmstypes.c	Wed Jul 05 20:01:50 2017 +0200
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2011 Marti Maria Saguer
+//  Copyright (c) 1998-2014 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -61,7 +61,7 @@
 // are no profiles holding them. The programmer can also extend this list by defining his own types
 // by using the appropiate plug-in. There are three types of plug ins regarding that. First type
 // allows to define new tags using any existing type. Next plug-in type allows to define new types
-// and the third one is very specific: allows to extend the number of elements in the multiprofile
+// and the third one is very specific: allows to extend the number of elements in the multiprocessing
 // elements special type.
 //--------------------------------------------------------------------------------------------------
 
@@ -89,54 +89,49 @@
 // Helper macro to define a MPE handler. Callbacks do have a fixed naming convention
 #define TYPE_MPE_HANDLER(t, x)  { (t), READ_FN(x), WRITE_FN(x), GenericMPEdup, GenericMPEfree, NULL, 0 }
 
-// Register a new type handler. This routine is shared between normal types and MPE
+// Register a new type handler. This routine is shared between normal types and MPE. LinkedList points to the optional list head
 static
-cmsBool RegisterTypesPlugin(cmsContext id, cmsPluginBase* Data, _cmsTagTypeLinkedList* LinkedList, cmsUInt32Number DefaultListCount)
+cmsBool RegisterTypesPlugin(cmsContext id, cmsPluginBase* Data, _cmsMemoryClient pos)
 {
     cmsPluginTagType* Plugin = (cmsPluginTagType*) Data;
-    _cmsTagTypeLinkedList *pt, *Anterior = NULL;
+    _cmsTagTypePluginChunkType* ctx = ( _cmsTagTypePluginChunkType*) _cmsContextGetClientChunk(id, pos);
+    _cmsTagTypeLinkedList *pt;
 
     // Calling the function with NULL as plug-in would unregister the plug in.
     if (Data == NULL) {
 
-        LinkedList[DefaultListCount-1].Next = NULL;
+        // There is no need to set free the memory, as pool is destroyed as a whole.
+        ctx ->TagTypes = NULL;
         return TRUE;
     }
 
-    pt = Anterior = LinkedList;
-    while (pt != NULL) {
-
-        if (Plugin->Handler.Signature == pt -> Handler.Signature) {
-            pt ->Handler = Plugin ->Handler;    // Replace old behaviour.
-            // Note that since no memory is allocated, unregister does not
-            // reset this action.
-            return TRUE;
-        }
-
-        Anterior = pt;
-        pt = pt ->Next;
-    }
-
-    // Registering happens in plug-in memory pool
+    // Registering happens in plug-in memory pool.
     pt = (_cmsTagTypeLinkedList*) _cmsPluginMalloc(id, sizeof(_cmsTagTypeLinkedList));
     if (pt == NULL) return FALSE;
 
     pt ->Handler   = Plugin ->Handler;
-    pt ->Next      = NULL;
-
-    if (Anterior)
-        Anterior -> Next = pt;
+    pt ->Next      = ctx ->TagTypes;
+
+    ctx ->TagTypes = pt;
 
     return TRUE;
 }
 
-// Return handler for a given type or NULL if not found. Shared between normal types and MPE
+// Return handler for a given type or NULL if not found. Shared between normal types and MPE. It first tries the additons
+// made by plug-ins and then the built-in defaults.
 static
-cmsTagTypeHandler* GetHandler(cmsTagTypeSignature sig, _cmsTagTypeLinkedList* LinkedList)
+cmsTagTypeHandler* GetHandler(cmsTagTypeSignature sig, _cmsTagTypeLinkedList* PluginLinkedList, _cmsTagTypeLinkedList* DefaultLinkedList)
 {
     _cmsTagTypeLinkedList* pt;
 
-    for (pt = LinkedList;
+    for (pt = PluginLinkedList;
+         pt != NULL;
+         pt = pt ->Next) {
+
+            if (sig == pt -> Handler.Signature) return &pt ->Handler;
+    }
+
+    for (pt = DefaultLinkedList;
          pt != NULL;
          pt = pt ->Next) {
 
@@ -163,6 +158,7 @@
     return TRUE;
 }
 
+// Auxiliar to read an array of wchar_t
 static
 cmsBool _cmsReadWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, wchar_t* Array)
 {
@@ -777,6 +773,8 @@
 
     // Create memory
     Text = (char*) _cmsMalloc(self ->ContextID, size);
+    if (Text == NULL) return FALSE;
+
     cmsMLUgetASCII(mlu, cmsNoLanguage, cmsNoCountry, Text, size);
 
     // Write it, including separator
@@ -1783,7 +1781,6 @@
     if (!_cmsReadUInt8Number(io, NULL)) goto Error;
 
     // Do some checking
-
     if (InputChannels > cmsMAXCHANNELS)  goto Error;
     if (OutputChannels > cmsMAXCHANNELS) goto Error;
 
@@ -1824,9 +1821,16 @@
         if (T  == NULL) goto Error;
 
         Temp = (cmsUInt8Number*) _cmsMalloc(self ->ContextID, nTabSize);
-        if (Temp == NULL) goto Error;
-
-        if (io ->Read(io, Temp, nTabSize, 1) != 1) goto Error;
+        if (Temp == NULL) {
+            _cmsFree(self ->ContextID, T);
+            goto Error;
+        }
+
+        if (io ->Read(io, Temp, nTabSize, 1) != 1) {
+            _cmsFree(self ->ContextID, T);
+            _cmsFree(self ->ContextID, Temp);
+            goto Error;
+        }
 
         for (i = 0; i < nTabSize; i++) {
 
@@ -2371,27 +2375,30 @@
     // Precision can be 1 or 2 bytes
     if (Precision == 1) {
 
-       cmsUInt8Number  v;
+        cmsUInt8Number  v;
 
         for (i=0; i < Data ->nEntries; i++) {
 
-                if (io ->Read(io, &v, sizeof(cmsUInt8Number), 1) != 1) return NULL;
-                Data ->Tab.T[i] = FROM_8_TO_16(v);
+            if (io ->Read(io, &v, sizeof(cmsUInt8Number), 1) != 1) return NULL;
+            Data ->Tab.T[i] = FROM_8_TO_16(v);
         }
 
     }
     else
         if (Precision == 2) {
 
-            if (!_cmsReadUInt16Array(io, Data->nEntries, Data ->Tab.T)) return NULL;
-    }
-    else {
-        cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown precision of '%d'", Precision);
-        return NULL;
-    }
-
-
-    return CLUT;
+            if (!_cmsReadUInt16Array(io, Data->nEntries, Data ->Tab.T)) {
+                cmsStageFree(CLUT);
+                return NULL;
+            }
+        }
+        else {
+            cmsStageFree(CLUT);
+            cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown precision of '%d'", Precision);
+            return NULL;
+        }
+
+        return CLUT;
 }
 
 static
@@ -4374,7 +4381,7 @@
 {TYPE_MPE_HANDLER((cmsTagTypeSignature) cmsSigCLutElemType,         MPEclut),        NULL },
 };
 
-#define DEFAULT_MPE_TYPE_COUNT  (sizeof(SupportedMPEtypes) / sizeof(_cmsTagTypeLinkedList))
+_cmsTagTypePluginChunkType _cmsMPETypePluginChunk = { NULL };
 
 static
 cmsBool ReadMPEElem(struct _cms_typehandler_struct* self,
@@ -4387,6 +4394,8 @@
     cmsTagTypeHandler* TypeHandler;
     cmsUInt32Number nItems;
     cmsPipeline *NewLUT = (cmsPipeline *) Cargo;
+    _cmsTagTypePluginChunkType* MPETypePluginChunk  = ( _cmsTagTypePluginChunkType*) _cmsContextGetClientChunk(self->ContextID, MPEPlugin);
+
 
     // Take signature and channels for each element.
     if (!_cmsReadUInt32Number(io, (cmsUInt32Number*) &ElementSig)) return FALSE;
@@ -4395,7 +4404,7 @@
     if (!_cmsReadUInt32Number(io, NULL)) return FALSE;
 
     // Read diverse MPE types
-    TypeHandler = GetHandler((cmsTagTypeSignature) ElementSig, SupportedMPEtypes);
+    TypeHandler = GetHandler((cmsTagTypeSignature) ElementSig, MPETypePluginChunk ->TagTypes, SupportedMPEtypes);
     if (TypeHandler == NULL)  {
 
         char String[5];
@@ -4472,6 +4481,7 @@
     cmsPipeline* Lut = (cmsPipeline*) Ptr;
     cmsStage* Elem = Lut ->Elements;
     cmsTagTypeHandler* TypeHandler;
+    _cmsTagTypePluginChunkType* MPETypePluginChunk  = ( _cmsTagTypePluginChunkType*) _cmsContextGetClientChunk(self->ContextID, MPEPlugin);
 
     BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase);
 
@@ -4505,7 +4515,7 @@
 
         ElementSig = Elem ->Type;
 
-        TypeHandler = GetHandler((cmsTagTypeSignature) ElementSig, SupportedMPEtypes);
+        TypeHandler = GetHandler((cmsTagTypeSignature) ElementSig, MPETypePluginChunk->TagTypes, SupportedMPEtypes);
         if (TypeHandler == NULL)  {
 
                 char String[5];
@@ -5125,7 +5135,7 @@
         }
         else {
 
-        rc = cmsDictAddEntry(hDict, NameWCS, ValueWCS, DisplayNameMLU, DisplayValueMLU);
+            rc = cmsDictAddEntry(hDict, NameWCS, ValueWCS, DisplayNameMLU, DisplayValueMLU);
         }
 
         if (NameWCS != NULL) _cmsFree(self ->ContextID, NameWCS);
@@ -5282,24 +5292,95 @@
 {TYPE_HANDLER(cmsSigVcgtType,                  vcgt),                NULL }
 };
 
-#define DEFAULT_TAG_TYPE_COUNT  (sizeof(SupportedTagTypes) / sizeof(_cmsTagTypeLinkedList))
+
+_cmsTagTypePluginChunkType _cmsTagTypePluginChunk = { NULL };
+
+
+
+// Duplicates the zone of memory used by the plug-in in the new context
+static
+void DupTagTypeList(struct _cmsContext_struct* ctx,
+                    const struct _cmsContext_struct* src,
+                    int loc)
+{
+   _cmsTagTypePluginChunkType newHead = { NULL };
+   _cmsTagTypeLinkedList*  entry;
+   _cmsTagTypeLinkedList*  Anterior = NULL;
+   _cmsTagTypePluginChunkType* head = (_cmsTagTypePluginChunkType*) src->chunks[loc];
+
+   // Walk the list copying all nodes
+   for (entry = head->TagTypes;
+       entry != NULL;
+       entry = entry ->Next) {
+
+           _cmsTagTypeLinkedList *newEntry = ( _cmsTagTypeLinkedList *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(_cmsTagTypeLinkedList));
+
+           if (newEntry == NULL)
+               return;
+
+           // We want to keep the linked list order, so this is a little bit tricky
+           newEntry -> Next = NULL;
+           if (Anterior)
+               Anterior -> Next = newEntry;
+
+           Anterior = newEntry;
+
+           if (newHead.TagTypes == NULL)
+               newHead.TagTypes = newEntry;
+   }
+
+   ctx ->chunks[loc] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsTagTypePluginChunkType));
+}
+
+
+void _cmsAllocTagTypePluginChunk(struct _cmsContext_struct* ctx,
+                                 const struct _cmsContext_struct* src)
+{
+    if (src != NULL) {
+
+        // Duplicate the LIST
+        DupTagTypeList(ctx, src, TagTypePlugin);
+    }
+    else {
+        static _cmsTagTypePluginChunkType TagTypePluginChunk = { NULL };
+        ctx ->chunks[TagTypePlugin] = _cmsSubAllocDup(ctx ->MemPool, &TagTypePluginChunk, sizeof(_cmsTagTypePluginChunkType));
+    }
+}
+
+void _cmsAllocMPETypePluginChunk(struct _cmsContext_struct* ctx,
+                               const struct _cmsContext_struct* src)
+{
+    if (src != NULL) {
+
+        // Duplicate the LIST
+        DupTagTypeList(ctx, src, MPEPlugin);
+    }
+    else {
+        static _cmsTagTypePluginChunkType TagTypePluginChunk = { NULL };
+        ctx ->chunks[MPEPlugin] = _cmsSubAllocDup(ctx ->MemPool, &TagTypePluginChunk, sizeof(_cmsTagTypePluginChunkType));
+    }
+
+}
+
 
 // Both kind of plug-ins share same structure
 cmsBool  _cmsRegisterTagTypePlugin(cmsContext id, cmsPluginBase* Data)
 {
-    return RegisterTypesPlugin(id, Data, SupportedTagTypes, DEFAULT_TAG_TYPE_COUNT);
+    return RegisterTypesPlugin(id, Data, TagTypePlugin);
 }
 
 cmsBool  _cmsRegisterMultiProcessElementPlugin(cmsContext id, cmsPluginBase* Data)
 {
-    return RegisterTypesPlugin(id, Data, SupportedMPEtypes, DEFAULT_MPE_TYPE_COUNT);
+    return RegisterTypesPlugin(id, Data,MPEPlugin);
 }
 
 
 // Wrapper for tag types
-cmsTagTypeHandler* _cmsGetTagTypeHandler(cmsTagTypeSignature sig)
-{
-    return GetHandler(sig, SupportedTagTypes);
+cmsTagTypeHandler* _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig)
+{
+    _cmsTagTypePluginChunkType* ctx = ( _cmsTagTypePluginChunkType*) _cmsContextGetClientChunk(ContextID, TagTypePlugin);
+
+    return GetHandler(sig, ctx->TagTypes, SupportedTagTypes);
 }
 
 // ********************************************************************************
@@ -5414,48 +5495,94 @@
     cmsSigDeviceSettingsTag   ==> Deprecated, useless
 */
 
-#define DEFAULT_TAG_COUNT  (sizeof(SupportedTags) / sizeof(_cmsTagLinkedList))
+
+_cmsTagPluginChunkType _cmsTagPluginChunk = { NULL };
+
+
+// Duplicates the zone of memory used by the plug-in in the new context
+static
+void DupTagList(struct _cmsContext_struct* ctx,
+                    const struct _cmsContext_struct* src)
+{
+   _cmsTagPluginChunkType newHead = { NULL };
+   _cmsTagLinkedList*  entry;
+   _cmsTagLinkedList*  Anterior = NULL;
+   _cmsTagPluginChunkType* head = (_cmsTagPluginChunkType*) src->chunks[TagPlugin];
+
+   // Walk the list copying all nodes
+   for (entry = head->Tag;
+       entry != NULL;
+       entry = entry ->Next) {
+
+           _cmsTagLinkedList *newEntry = ( _cmsTagLinkedList *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(_cmsTagLinkedList));
+
+           if (newEntry == NULL)
+               return;
+
+           // We want to keep the linked list order, so this is a little bit tricky
+           newEntry -> Next = NULL;
+           if (Anterior)
+               Anterior -> Next = newEntry;
+
+           Anterior = newEntry;
+
+           if (newHead.Tag == NULL)
+               newHead.Tag = newEntry;
+   }
+
+   ctx ->chunks[TagPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsTagPluginChunkType));
+}
+
+void _cmsAllocTagPluginChunk(struct _cmsContext_struct* ctx,
+                                 const struct _cmsContext_struct* src)
+{
+    if (src != NULL) {
+
+        DupTagList(ctx, src);
+    }
+    else {
+        static _cmsTagPluginChunkType TagPluginChunk = { NULL };
+        ctx ->chunks[TagPlugin] = _cmsSubAllocDup(ctx ->MemPool, &TagPluginChunk, sizeof(_cmsTagPluginChunkType));
+    }
+
+}
 
 cmsBool  _cmsRegisterTagPlugin(cmsContext id, cmsPluginBase* Data)
 {
     cmsPluginTag* Plugin = (cmsPluginTag*) Data;
-    _cmsTagLinkedList *pt, *Anterior;
-
+    _cmsTagLinkedList *pt;
+    _cmsTagPluginChunkType* TagPluginChunk = ( _cmsTagPluginChunkType*) _cmsContextGetClientChunk(id, TagPlugin);
 
     if (Data == NULL) {
 
-        SupportedTags[DEFAULT_TAG_COUNT-1].Next = NULL;
+        TagPluginChunk->Tag = NULL;
         return TRUE;
     }
 
-    pt = Anterior = SupportedTags;
-    while (pt != NULL) {
-
-        if (Plugin->Signature == pt -> Signature) {
-            pt ->Descriptor = Plugin ->Descriptor;  // Replace old behaviour
-            return TRUE;
-        }
-
-        Anterior = pt;
-        pt = pt ->Next;
-    }
-
     pt = (_cmsTagLinkedList*) _cmsPluginMalloc(id, sizeof(_cmsTagLinkedList));
     if (pt == NULL) return FALSE;
 
     pt ->Signature  = Plugin ->Signature;
     pt ->Descriptor = Plugin ->Descriptor;
-    pt ->Next       = NULL;
-
-    if (Anterior != NULL) Anterior -> Next = pt;
+    pt ->Next       = TagPluginChunk ->Tag;
+
+    TagPluginChunk ->Tag = pt;
 
     return TRUE;
 }
 
 // Return a descriptor for a given tag or NULL
-cmsTagDescriptor* _cmsGetTagDescriptor(cmsTagSignature sig)
+cmsTagDescriptor* _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig)
 {
     _cmsTagLinkedList* pt;
+    _cmsTagPluginChunkType* TagPluginChunk = ( _cmsTagPluginChunkType*) _cmsContextGetClientChunk(ContextID, TagPlugin);
+
+    for (pt = TagPluginChunk->Tag;
+             pt != NULL;
+             pt = pt ->Next) {
+
+                if (sig == pt -> Signature) return &pt ->Descriptor;
+    }
 
     for (pt = SupportedTags;
             pt != NULL;
--- a/jdk/src/java.desktop/share/native/liblcms/cmsvirt.c	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.desktop/share/native/liblcms/cmsvirt.c	Wed Jul 05 20:01:50 2017 +0200
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2011 Marti Maria Saguer
+//  Copyright (c) 1998-2014 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -1019,7 +1019,7 @@
 
 static const cmsAllowedLUT AllowedLUTTypes[] = {
 
-    { FALSE, 0,              cmsSigLut16Type,    4,  { cmsSigMatrixElemType,  cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType}},
+    { FALSE, 0,              cmsSigLut16Type,    4,  { cmsSigMatrixElemType,   cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType}},
     { FALSE, 0,              cmsSigLut16Type,    3,  { cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType}},
     { FALSE, 0,              cmsSigLut16Type,    2,  { cmsSigCurveSetElemType, cmsSigCLutElemType}},
     { TRUE , 0,              cmsSigLutAtoBType,  1,  { cmsSigCurveSetElemType }},
@@ -1150,7 +1150,7 @@
     if (AllowedLUT == NULL) {
 
         // Try to optimize
-        _cmsOptimizePipeline(&LUT, xform ->RenderingIntent, &FrmIn, &FrmOut, &dwFlags);
+        _cmsOptimizePipeline(ContextID, &LUT, xform ->RenderingIntent, &FrmIn, &FrmOut, &dwFlags);
         AllowedLUT = FindCombination(LUT, Version >= 4.0, DestinationTag);
 
     }
@@ -1159,7 +1159,7 @@
     if (AllowedLUT == NULL) {
 
         dwFlags |= cmsFLAGS_FORCE_CLUT;
-        _cmsOptimizePipeline(&LUT, xform ->RenderingIntent, &FrmIn, &FrmOut, &dwFlags);
+        _cmsOptimizePipeline(ContextID, &LUT, xform ->RenderingIntent, &FrmIn, &FrmOut, &dwFlags);
 
         // Put identity curves if needed
         if (cmsPipelineGetPtrToFirstStage(LUT) ->Type != cmsSigCurveSetElemType)
--- a/jdk/src/java.desktop/share/native/liblcms/cmswtpnt.c	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.desktop/share/native/liblcms/cmswtpnt.c	Wed Jul 05 20:01:50 2017 +0200
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2012 Marti Maria Saguer
+//  Copyright (c) 1998-2014 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
--- a/jdk/src/java.desktop/share/native/liblcms/cmsxform.c	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.desktop/share/native/liblcms/cmsxform.c	Wed Jul 05 20:01:50 2017 +0200
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2011 Marti Maria Saguer
+//  Copyright (c) 1998-2014 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -58,44 +58,120 @@
 // Transformations stuff
 // -----------------------------------------------------------------------
 
-// Alarm codes for 16-bit transformations, because the fixed range of containers there are
-// no values left to mark out of gamut. volatile is C99 per 6.2.5
-static volatile cmsUInt16Number Alarm[cmsMAXCHANNELS] = { 0x7F00, 0x7F00, 0x7F00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-static volatile cmsFloat64Number GlobalAdaptationState = 1;
+#define DEFAULT_OBSERVER_ADAPTATION_STATE 1.0
+
+// The Context0 observer adaptation state.
+_cmsAdaptationStateChunkType _cmsAdaptationStateChunk = { DEFAULT_OBSERVER_ADAPTATION_STATE };
+
+// Init and duplicate observer adaptation state
+void _cmsAllocAdaptationStateChunk(struct _cmsContext_struct* ctx,
+                                   const struct _cmsContext_struct* src)
+{
+    static _cmsAdaptationStateChunkType AdaptationStateChunk = { DEFAULT_OBSERVER_ADAPTATION_STATE };
+    void* from;
+
+    if (src != NULL) {
+        from = src ->chunks[AdaptationStateContext];
+    }
+    else {
+       from = &AdaptationStateChunk;
+    }
+
+    ctx ->chunks[AdaptationStateContext] = _cmsSubAllocDup(ctx ->MemPool, from, sizeof(_cmsAdaptationStateChunkType));
+}
+
+
+// Sets adaptation state for absolute colorimetric intent in the given context.  Adaptation state applies on all
+// but cmsCreateExtendedTransformTHR().  Little CMS can handle incomplete adaptation states.
+cmsFloat64Number CMSEXPORT cmsSetAdaptationStateTHR(cmsContext ContextID, cmsFloat64Number d)
+{
+    cmsFloat64Number prev;
+    _cmsAdaptationStateChunkType* ptr = (_cmsAdaptationStateChunkType*) _cmsContextGetClientChunk(ContextID, AdaptationStateContext);
+
+    // Get previous value for return
+    prev = ptr ->AdaptationState;
+
+    // Set the value if d is positive or zero
+    if (d >= 0.0) {
+
+        ptr ->AdaptationState = d;
+    }
+
+    // Always return previous value
+    return prev;
+}
+
 
 // The adaptation state may be defaulted by this function. If you don't like it, use the extended transform routine
 cmsFloat64Number CMSEXPORT cmsSetAdaptationState(cmsFloat64Number d)
 {
-    cmsFloat64Number OldVal = GlobalAdaptationState;
-
-    if (d >= 0)
-        GlobalAdaptationState = d;
-
-    return OldVal;
+    return cmsSetAdaptationStateTHR(NULL, d);
 }
 
-// Alarm codes are always global
-void CMSEXPORT cmsSetAlarmCodes(cmsUInt16Number NewAlarm[cmsMAXCHANNELS])
+// -----------------------------------------------------------------------
+
+// Alarm codes for 16-bit transformations, because the fixed range of containers there are
+// no values left to mark out of gamut.
+
+#define DEFAULT_ALARM_CODES_VALUE {0x7F00, 0x7F00, 0x7F00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+
+_cmsAlarmCodesChunkType _cmsAlarmCodesChunk = { DEFAULT_ALARM_CODES_VALUE };
+
+// Sets the codes used to mark out-out-gamut on Proofing transforms for a given context. Values are meant to be
+// encoded in 16 bits.
+void CMSEXPORT cmsSetAlarmCodesTHR(cmsContext ContextID, const cmsUInt16Number AlarmCodesP[cmsMAXCHANNELS])
 {
-    int i;
+    _cmsAlarmCodesChunkType* ContextAlarmCodes = (_cmsAlarmCodesChunkType*) _cmsContextGetClientChunk(ContextID, AlarmCodesContext);
+
+    _cmsAssert(ContextAlarmCodes != NULL); // Can't happen
+
+    memcpy(ContextAlarmCodes->AlarmCodes, AlarmCodesP, sizeof(ContextAlarmCodes->AlarmCodes));
+}
 
+// Gets the current codes used to mark out-out-gamut on Proofing transforms for the given context.
+// Values are meant to be encoded in 16 bits.
+void CMSEXPORT cmsGetAlarmCodesTHR(cmsContext ContextID, cmsUInt16Number AlarmCodesP[cmsMAXCHANNELS])
+{
+    _cmsAlarmCodesChunkType* ContextAlarmCodes = (_cmsAlarmCodesChunkType*) _cmsContextGetClientChunk(ContextID, AlarmCodesContext);
+
+    _cmsAssert(ContextAlarmCodes != NULL); // Can't happen
+
+    memcpy(AlarmCodesP, ContextAlarmCodes->AlarmCodes, sizeof(ContextAlarmCodes->AlarmCodes));
+}
+
+void CMSEXPORT cmsSetAlarmCodes(const cmsUInt16Number NewAlarm[cmsMAXCHANNELS])
+{
     _cmsAssert(NewAlarm != NULL);
 
-    for (i=0; i < cmsMAXCHANNELS; i++)
-        Alarm[i] = NewAlarm[i];
+    cmsSetAlarmCodesTHR(NULL, NewAlarm);
 }
 
-// You can get the codes cas well
 void CMSEXPORT cmsGetAlarmCodes(cmsUInt16Number OldAlarm[cmsMAXCHANNELS])
 {
-    int i;
+    _cmsAssert(OldAlarm != NULL);
+    cmsGetAlarmCodesTHR(NULL, OldAlarm);
+}
+
 
-    _cmsAssert(OldAlarm != NULL);
+// Init and duplicate alarm codes
+void _cmsAllocAlarmCodesChunk(struct _cmsContext_struct* ctx,
+                              const struct _cmsContext_struct* src)
+{
+    static _cmsAlarmCodesChunkType AlarmCodesChunk = { DEFAULT_ALARM_CODES_VALUE };
+    void* from;
 
-    for (i=0; i < cmsMAXCHANNELS; i++)
-        OldAlarm[i] = Alarm[i];
+    if (src != NULL) {
+        from = src ->chunks[AlarmCodesContext];
+    }
+    else {
+       from = &AlarmCodesChunk;
+    }
+
+    ctx ->chunks[AlarmCodesContext] = _cmsSubAllocDup(ctx ->MemPool, from, sizeof(_cmsAlarmCodesChunkType));
 }
 
+// -----------------------------------------------------------------------
+
 // Get rid of transform resources
 void CMSEXPORT cmsDeleteTransform(cmsHTRANSFORM hTransform)
 {
@@ -202,6 +278,30 @@
     }
 }
 
+
+static
+void NullFloatXFORM(_cmsTRANSFORM* p,
+                    const void* in,
+                    void* out,
+                    cmsUInt32Number Size,
+                    cmsUInt32Number Stride)
+{
+    cmsUInt8Number* accum;
+    cmsUInt8Number* output;
+    cmsFloat32Number fIn[cmsMAXCHANNELS];
+    cmsUInt32Number i, n;
+
+    accum  = (cmsUInt8Number*)  in;
+    output = (cmsUInt8Number*)  out;
+    n = Size;
+
+    for (i=0; i < n; i++) {
+
+        accum  = p -> FromInputFloat(p, fIn, accum, Stride);
+        output = p -> ToOutputFloat(p, fIn, output, Stride);
+    }
+}
+
 // 16 bit precision -----------------------------------------------------------------------------------------------------------
 
 // Null transformation, only applies formatters. No caché
@@ -252,7 +352,7 @@
 }
 
 
-// Auxiliar: Handle precalculated gamut check
+// Auxiliar: Handle precalculated gamut check. The retrieval of context may be alittle bit slow, but this function is not critical.
 static
 void TransformOnePixelWithGamutCheck(_cmsTRANSFORM* p,
                                      const cmsUInt16Number wIn[],
@@ -264,9 +364,12 @@
     if (wOutOfGamut >= 1) {
 
         cmsUInt16Number i;
+        _cmsAlarmCodesChunkType* ContextAlarmCodes = (_cmsAlarmCodesChunkType*) _cmsContextGetClientChunk(p->ContextID, AlarmCodesContext);
 
-        for (i=0; i < p ->Lut->OutputChannels; i++)
-            wOut[i] = Alarm[i];
+        for (i=0; i < p ->Lut->OutputChannels; i++) {
+
+            wOut[i] = ContextAlarmCodes ->AlarmCodes[i];
+        }
     }
     else
         p ->Lut ->Eval16Fn(wIn, wOut, p -> Lut->Data);
@@ -393,34 +496,86 @@
 } _cmsTransformCollection;
 
 // The linked list head
-static _cmsTransformCollection* TransformCollection = NULL;
+_cmsTransformPluginChunkType _cmsTransformPluginChunk = { NULL };
+
+
+// Duplicates the zone of memory used by the plug-in in the new context
+static
+void DupPluginTransformList(struct _cmsContext_struct* ctx,
+                                               const struct _cmsContext_struct* src)
+{
+   _cmsTransformPluginChunkType newHead = { NULL };
+   _cmsTransformCollection*  entry;
+   _cmsTransformCollection*  Anterior = NULL;
+   _cmsTransformPluginChunkType* head = (_cmsTransformPluginChunkType*) src->chunks[TransformPlugin];
+
+    // Walk the list copying all nodes
+   for (entry = head->TransformCollection;
+        entry != NULL;
+        entry = entry ->Next) {
+
+            _cmsTransformCollection *newEntry = ( _cmsTransformCollection *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(_cmsTransformCollection));
+
+            if (newEntry == NULL)
+                return;
+
+            // We want to keep the linked list order, so this is a little bit tricky
+            newEntry -> Next = NULL;
+            if (Anterior)
+                Anterior -> Next = newEntry;
+
+            Anterior = newEntry;
+
+            if (newHead.TransformCollection == NULL)
+                newHead.TransformCollection = newEntry;
+    }
+
+  ctx ->chunks[TransformPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsTransformPluginChunkType));
+}
+
+void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx,
+                                        const struct _cmsContext_struct* src)
+{
+    if (src != NULL) {
+
+        // Copy all linked list
+        DupPluginTransformList(ctx, src);
+    }
+    else {
+        static _cmsTransformPluginChunkType TransformPluginChunkType = { NULL };
+        ctx ->chunks[TransformPlugin] = _cmsSubAllocDup(ctx ->MemPool, &TransformPluginChunkType, sizeof(_cmsTransformPluginChunkType));
+    }
+}
+
+
 
 // Register new ways to transform
-cmsBool  _cmsRegisterTransformPlugin(cmsContext id, cmsPluginBase* Data)
+cmsBool  _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Data)
 {
     cmsPluginTransform* Plugin = (cmsPluginTransform*) Data;
     _cmsTransformCollection* fl;
+    _cmsTransformPluginChunkType* ctx = ( _cmsTransformPluginChunkType*) _cmsContextGetClientChunk(ContextID,TransformPlugin);
 
-      if (Data == NULL) {
+    if (Data == NULL) {
 
         // Free the chain. Memory is safely freed at exit
-        TransformCollection = NULL;
+        ctx->TransformCollection = NULL;
         return TRUE;
     }
 
     // Factory callback is required
-   if (Plugin ->Factory == NULL) return FALSE;
+    if (Plugin ->Factory == NULL) return FALSE;
 
 
-    fl = (_cmsTransformCollection*) _cmsPluginMalloc(id, sizeof(_cmsTransformCollection));
+    fl = (_cmsTransformCollection*) _cmsPluginMalloc(ContextID, sizeof(_cmsTransformCollection));
     if (fl == NULL) return FALSE;
 
-      // Copy the parameters
+    // Copy the parameters
     fl ->Factory = Plugin ->Factory;
 
     // Keep linked list
-    fl ->Next = TransformCollection;
-    TransformCollection = fl;
+    fl ->Next = ctx->TransformCollection;
+    ctx->TransformCollection = fl;
 
     // All is ok
     return TRUE;
@@ -463,6 +618,7 @@
 _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
                                                cmsUInt32Number Intent, cmsUInt32Number* InputFormat, cmsUInt32Number* OutputFormat, cmsUInt32Number* dwFlags)
 {
+     _cmsTransformPluginChunkType* ctx = ( _cmsTransformPluginChunkType*) _cmsContextGetClientChunk(ContextID, TransformPlugin);
      _cmsTransformCollection* Plugin;
 
     // Allocate needed memory
@@ -473,7 +629,7 @@
     p ->Lut = lut;
 
     // Let's see if any plug-in want to do the transform by itself
-    for (Plugin = TransformCollection;
+    for (Plugin = ctx ->TransformCollection;
         Plugin != NULL;
         Plugin = Plugin ->Next) {
 
@@ -493,10 +649,10 @@
                 // Fill the formatters just in case the optimized routine is interested.
                 // No error is thrown if the formatter doesn't exist. It is up to the optimization
                 // factory to decide what to do in those cases.
-                p ->FromInput      = _cmsGetFormatter(*InputFormat,  cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16;
-                p ->ToOutput       = _cmsGetFormatter(*OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16;
-                p ->FromInputFloat = _cmsGetFormatter(*InputFormat,  cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
-                p ->ToOutputFloat  = _cmsGetFormatter(*OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
+                p ->FromInput      = _cmsGetFormatter(ContextID, *InputFormat,  cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16;
+                p ->ToOutput       = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16;
+                p ->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat,  cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
+                p ->ToOutputFloat  = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
 
                 return p;
             }
@@ -504,14 +660,14 @@
 
     // Not suitable for the transform plug-in, let's check  the pipeline plug-in
     if (p ->Lut != NULL)
-        _cmsOptimizePipeline(&p->Lut, Intent, InputFormat, OutputFormat, dwFlags);
+        _cmsOptimizePipeline(ContextID, &p->Lut, Intent, InputFormat, OutputFormat, dwFlags);
 
     // Check whatever this is a true floating point transform
     if (_cmsFormatterIsFloat(*InputFormat) && _cmsFormatterIsFloat(*OutputFormat)) {
 
         // Get formatter function always return a valid union, but the contents of this union may be NULL.
-        p ->FromInputFloat = _cmsGetFormatter(*InputFormat,  cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
-        p ->ToOutputFloat  = _cmsGetFormatter(*OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
+        p ->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat,  cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
+        p ->ToOutputFloat  = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
         *dwFlags |= cmsFLAGS_CAN_CHANGE_FORMATTER;
 
         if (p ->FromInputFloat == NULL || p ->ToOutputFloat == NULL) {
@@ -521,8 +677,15 @@
             return NULL;
         }
 
-        // Float transforms don't use caché, always are non-NULL
-        p ->xform = FloatXFORM;
+        if (*dwFlags & cmsFLAGS_NULLTRANSFORM) {
+
+            p ->xform = NullFloatXFORM;
+        }
+        else {
+            // Float transforms don't use caché, always are non-NULL
+            p ->xform = FloatXFORM;
+        }
+
     }
     else {
 
@@ -534,8 +697,8 @@
 
             int BytesPerPixelInput;
 
-            p ->FromInput = _cmsGetFormatter(*InputFormat,  cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16;
-            p ->ToOutput  = _cmsGetFormatter(*OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16;
+            p ->FromInput = _cmsGetFormatter(ContextID, *InputFormat,  cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16;
+            p ->ToOutput  = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16;
 
             if (p ->FromInput == NULL || p ->ToOutput == NULL) {
 
@@ -727,6 +890,7 @@
     // Check channel count
     if ((cmsChannelsOf(EntryColorSpace) != cmsPipelineInputChannels(Lut)) ||
         (cmsChannelsOf(ExitColorSpace)  != cmsPipelineOutputChannels(Lut))) {
+        cmsPipelineFree(Lut);
         cmsSignalError(ContextID, cmsERROR_NOT_SUITABLE, "Channel count doesn't match. Profile is corrupted");
         return NULL;
     }
@@ -829,7 +993,7 @@
     for (i=0; i < nProfiles; i++) {
         BPC[i] = dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION ? TRUE : FALSE;
         Intents[i] = Intent;
-        AdaptationStates[i] = GlobalAdaptationState;
+        AdaptationStates[i] = cmsSetAdaptationStateTHR(ContextID, -1);
     }
 
 
@@ -909,7 +1073,7 @@
     Intents[0] = nIntent;      Intents[1] = nIntent;        Intents[2] = INTENT_RELATIVE_COLORIMETRIC;  Intents[3] = ProofingIntent;
     BPC[0]     = DoBPC;        BPC[1] = DoBPC;              BPC[2] = 0;                                 BPC[3] = 0;
 
-    Adaptation[0] = Adaptation[1] = Adaptation[2] = Adaptation[3] = GlobalAdaptationState;
+    Adaptation[0] = Adaptation[1] = Adaptation[2] = Adaptation[3] = cmsSetAdaptationStateTHR(ContextID, -1);
 
     if (!(dwFlags & (cmsFLAGS_SOFTPROOFING|cmsFLAGS_GAMUTCHECK)))
         return cmsCreateTransformTHR(ContextID, InputProfile, InputFormat, OutputProfile, OutputFormat, nIntent, dwFlags);
@@ -984,8 +1148,8 @@
         return FALSE;
     }
 
-    FromInput = _cmsGetFormatter(InputFormat,  cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16;
-    ToOutput  = _cmsGetFormatter(OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16;
+    FromInput = _cmsGetFormatter(xform->ContextID, InputFormat,  cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16;
+    ToOutput  = _cmsGetFormatter(xform->ContextID, OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16;
 
     if (FromInput == NULL || ToOutput == NULL) {
 
--- a/jdk/src/java.desktop/share/native/liblcms/lcms2.h	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.desktop/share/native/liblcms/lcms2.h	Wed Jul 05 20:01:50 2017 +0200
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2013 Marti Maria Saguer
+//  Copyright (c) 1998-2014 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -52,7 +52,7 @@
 //
 //---------------------------------------------------------------------------------
 //
-// Version 2.5
+// Version 2.6
 //
 
 #ifndef _lcms2_H
@@ -84,6 +84,9 @@
 // Uncomment to get rid of the tables for "half" float support
 // #define CMS_NO_HALF_SUPPORT 1
 
+// Uncomment to get rid of pthreads/windows dependency
+// #define CMS_NO_PTHREADS  1
+
 // ********** End of configuration toggles ******************************
 
 // Needed for streams
@@ -101,7 +104,7 @@
 #endif
 
 // Version/release
-#define LCMS_VERSION        2050
+#define LCMS_VERSION        2060
 
 // I will give the chance of redefining basic types for compilers that are not fully C99 compliant
 #ifndef CMS_BASIC_TYPES_ALREADY_DEFINED
@@ -202,28 +205,42 @@
 // Try to detect big endian platforms. This list can be endless, so only some checks are performed over here.
 // you can pass this toggle to the compiler by using -DCMS_USE_BIG_ENDIAN or something similar
 
-#if defined(_HOST_BIG_ENDIAN) || defined(__BIG_ENDIAN__) || defined(WORDS_BIGENDIAN)
-#   define CMS_USE_BIG_ENDIAN      1
-#endif
-
-#if defined(__sgi__) || defined(__sgi) || defined(__powerpc__) || defined(sparc)
+#if defined(__sgi__) || defined(__sgi) || defined(sparc)
 #   define CMS_USE_BIG_ENDIAN      1
 #endif
 
-#if defined(__ppc__) || defined(__s390__) || defined(__s390x__)
+#if defined(__s390__) || defined(__s390x__)
 #   define CMS_USE_BIG_ENDIAN   1
 #endif
 
-#ifdef TARGET_CPU_PPC
-# if TARGET_CPU_PPC
+#  ifdef TARGET_CPU_PPC
+#    if TARGET_CPU_PPC
+#      define CMS_USE_BIG_ENDIAN   1
+#    endif
+#  endif
+
+#if defined(__powerpc__) || defined(__ppc__) || defined(TARGET_CPU_PPC)
 #   define CMS_USE_BIG_ENDIAN   1
-# endif
+#   if defined (__GNUC__) && defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN)
+#       if __BYTE_ORDER  == __LITTLE_ENDIAN
+//               // Don't use big endian for PowerPC little endian mode
+#                undef CMS_USE_BIG_ENDIAN
+#       endif
+#   endif
+#endif
+
+// WORDS_BIGENDIAN takes precedence
+#if defined(_HOST_BIG_ENDIAN) || defined(__BIG_ENDIAN__) || defined(WORDS_BIGENDIAN)
+#   define CMS_USE_BIG_ENDIAN      1
 #endif
 
 #ifdef macintosh
 # ifdef __BIG_ENDIAN__
 #   define CMS_USE_BIG_ENDIAN      1
 # endif
+# ifdef __LITTLE_ENDIAN__
+#   undef CMS_USE_BIG_ENDIAN
+# endif
 #endif
 
 // Calling convention -- this is hardly platform and compiler dependent
@@ -249,6 +266,14 @@
 # define CMSAPI
 #endif
 
+#ifdef HasTHREADS
+# if HasTHREADS == 1
+#    undef CMS_NO_PTHREADS
+# else
+#    define CMS_NO_PTHREADS 1
+# endif
+#endif
+
 // Some common definitions
 #define cmsMAX_PATH     256
 
@@ -642,7 +667,6 @@
 
 // Little CMS specific typedefs
 
-typedef void* cmsContext;              // Context identifier for multithreaded environments
 typedef void* cmsHANDLE ;              // Generic handle
 typedef void* cmsHPROFILE;             // Opaque typedefs to hide internals
 typedef void* cmsHTRANSFORM;
@@ -1012,11 +1036,25 @@
 CMSAPI int               CMSEXPORT cmsstrcasecmp(const char* s1, const char* s2);
 CMSAPI long int          CMSEXPORT cmsfilelength(FILE* f);
 
-// Plug-In registering  ---------------------------------------------------------------------------------------------------
+
+// Context handling --------------------------------------------------------------------------------------------------------
+
+// Each context holds its owns globals and its own plug-ins. There is a global context with the id = 0 for lecacy compatibility
+// though using the global context is not recomended. Proper context handling makes lcms more thread-safe.
+
+typedef struct _cmsContext_struct* cmsContext;
+
+CMSAPI cmsContext       CMSEXPORT cmsCreateContext(void* Plugin, void* UserData);
+CMSAPI void             CMSEXPORT cmsDeleteContext(cmsContext ContexID);
+CMSAPI cmsContext       CMSEXPORT cmsDupContext(cmsContext ContextID, void* NewUserData);
+CMSAPI void*            CMSEXPORT cmsGetContextUserData(cmsContext ContextID);
+
+// Plug-In registering  --------------------------------------------------------------------------------------------------
 
 CMSAPI cmsBool           CMSEXPORT cmsPlugin(void* Plugin);
 CMSAPI cmsBool           CMSEXPORT cmsPluginTHR(cmsContext ContextID, void* Plugin);
 CMSAPI void              CMSEXPORT cmsUnregisterPlugins(void);
+CMSAPI void              CMSEXPORT cmsUnregisterPluginsTHR(cmsContext ContextID);
 
 // Error logging ----------------------------------------------------------------------------------------------------------
 
@@ -1053,6 +1091,7 @@
 
 // Allows user to set any specific logger
 CMSAPI void              CMSEXPORT cmsSetLogErrorHandler(cmsLogErrorHandlerFunction Fn);
+CMSAPI void              CMSEXPORT cmsSetLogErrorHandlerTHR(cmsContext ContextID, cmsLogErrorHandlerFunction Fn);
 
 // Conversions --------------------------------------------------------------------------------------------------------------
 
@@ -1514,6 +1553,7 @@
 CMSAPI cmsHPROFILE      CMSEXPORT cmsOpenProfileFromMem(const void * MemPtr, cmsUInt32Number dwSize);
 CMSAPI cmsHPROFILE      CMSEXPORT cmsOpenProfileFromMemTHR(cmsContext ContextID, const void * MemPtr, cmsUInt32Number dwSize);
 CMSAPI cmsHPROFILE      CMSEXPORT cmsOpenProfileFromIOhandlerTHR(cmsContext ContextID, cmsIOHANDLER* io);
+CMSAPI cmsHPROFILE      CMSEXPORT cmsOpenProfileFromIOhandler2THR(cmsContext ContextID, cmsIOHANDLER* io, cmsBool write);
 CMSAPI cmsBool          CMSEXPORT cmsCloseProfile(cmsHPROFILE hProfile);
 
 CMSAPI cmsBool          CMSEXPORT cmsSaveProfileToFile(cmsHPROFILE hProfile, const char* FileName);
@@ -1604,6 +1644,7 @@
 
 // Call with NULL as parameters to get the intent count
 CMSAPI cmsUInt32Number  CMSEXPORT cmsGetSupportedIntents(cmsUInt32Number nMax, cmsUInt32Number* Codes, char** Descriptions);
+CMSAPI cmsUInt32Number  CMSEXPORT cmsGetSupportedIntentsTHR(cmsContext ContextID, cmsUInt32Number nMax, cmsUInt32Number* Codes, char** Descriptions);
 
 // Flags
 
@@ -1715,11 +1756,22 @@
                                                  cmsUInt32Number Stride);
 
 
-CMSAPI void             CMSEXPORT cmsSetAlarmCodes(cmsUInt16Number NewAlarm[cmsMAXCHANNELS]);
+CMSAPI void             CMSEXPORT cmsSetAlarmCodes(const cmsUInt16Number NewAlarm[cmsMAXCHANNELS]);
 CMSAPI void             CMSEXPORT cmsGetAlarmCodes(cmsUInt16Number NewAlarm[cmsMAXCHANNELS]);
 
+
+CMSAPI void             CMSEXPORT cmsSetAlarmCodesTHR(cmsContext ContextID,
+                                                          const cmsUInt16Number AlarmCodes[cmsMAXCHANNELS]);
+CMSAPI void             CMSEXPORT cmsGetAlarmCodesTHR(cmsContext ContextID,
+                                                          cmsUInt16Number AlarmCodes[cmsMAXCHANNELS]);
+
+
+
 // Adaptation state for absolute colorimetric intent
 CMSAPI cmsFloat64Number CMSEXPORT cmsSetAdaptationState(cmsFloat64Number d);
+CMSAPI cmsFloat64Number CMSEXPORT cmsSetAdaptationStateTHR(cmsContext ContextID, cmsFloat64Number d);
+
+
 
 // Grab the ContextID from an open transform. Returns NULL if a NULL transform is passed
 CMSAPI cmsContext       CMSEXPORT cmsGetTransformContextID(cmsHTRANSFORM hTransform);
--- a/jdk/src/java.desktop/share/native/liblcms/lcms2_internal.h	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.desktop/share/native/liblcms/lcms2_internal.h	Wed Jul 05 20:01:50 2017 +0200
@@ -30,7 +30,7 @@
 
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2011 Marti Maria Saguer
+//  Copyright (c) 1998-2014 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -193,16 +193,171 @@
     return _cmsQuickFloorWord(d);
 }
 
-// Plug-In registering ---------------------------------------------------------------
+
+// Pthread support --------------------------------------------------------------------
+#ifndef CMS_NO_PTHREADS
+
+// This is the threading support. Unfortunately, it has to be platform-dependent because
+// windows does not support pthreads.
+
+#ifdef CMS_IS_WINDOWS_
+
+#define WIN32_LEAN_AND_MEAN 1
+#include <windows.h>
+
+
+// From: http://locklessinc.com/articles/pthreads_on_windows/
+// The pthreads API has an initialization macro that has no correspondence to anything in
+// the windows API. By investigating the internal definition of the critical section type,
+// one may work out how to initialize one without calling InitializeCriticalSection().
+// The trick here is that InitializeCriticalSection() is not allowed to fail. It tries
+// to allocate a critical section debug object, but if no memory is available, it sets
+// the pointer to a specific value. (One would expect that value to be NULL, but it is
+// actually (void *)-1 for some reason.) Thus we can use this special value for that
+// pointer, and the critical section code will work.
+
+// The other important part of the critical section type to initialize is the number
+// of waiters. This controls whether or not the mutex is locked. Fortunately, this
+// part of the critical section is unlikely to change. Apparently, many programs
+// already test critical sections to see if they are locked using this value, so
+// Microsoft felt that it was necessary to keep it set at -1 for an unlocked critical
+// section, even when they changed the underlying algorithm to be more scalable.
+// The final parts of the critical section object are unimportant, and can be set
+// to zero for their defaults. This yields an initialization macro:
+
+typedef CRITICAL_SECTION _cmsMutex;
+
+#define CMS_MUTEX_INITIALIZER {(void*) -1,-1,0,0,0,0}
+
+cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
+{
+        EnterCriticalSection(m);
+        return 0;
+}
+
+cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
+{
+        LeaveCriticalSection(m);
+        return 0;
+}
+
+cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
+{
+        InitializeCriticalSection(m);
+        return 0;
+}
+
+cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
+{
+        DeleteCriticalSection(m);
+        return 0;
+}
+
+cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
+{
+        EnterCriticalSection(m);
+        return 0;
+}
+
+cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
+{
+        LeaveCriticalSection(m);
+        return 0;
+}
+
+#else
+
+// Rest of the wide world
+#include <pthread.h>
+
+#define CMS_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
+typedef pthread_mutex_t _cmsMutex;
+
+
+cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
+{
+        return pthread_mutex_lock(m);
+}
+
+cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
+{
+        return pthread_mutex_unlock(m);
+}
+
+cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
+{
+        return pthread_mutex_init(m, NULL);
+}
+
+cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
+{
+        return pthread_mutex_destroy(m);
+}
+
+cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
+{
+        return pthread_mutex_lock(m);
+}
+
+cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
+{
+        return pthread_mutex_unlock(m);
+}
+
+#endif
+#else
+
+#define CMS_MUTEX_INITIALIZER 0
+typedef int _cmsMutex;
+
+
+cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
+{
+        return 0;
+    cmsUNUSED_PARAMETER(m);
+}
+
+cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
+{
+        return 0;
+    cmsUNUSED_PARAMETER(m);
+}
+
+cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
+{
+        return 0;
+    cmsUNUSED_PARAMETER(m);
+}
+
+cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
+{
+        return 0;
+    cmsUNUSED_PARAMETER(m);
+}
+
+cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
+{
+        return 0;
+    cmsUNUSED_PARAMETER(m);
+}
+
+cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
+{
+        return 0;
+    cmsUNUSED_PARAMETER(m);
+}
+#endif
+
+// Plug-In registration ---------------------------------------------------------------
 
 // Specialized function for plug-in memory management. No pairing free() since whole pool is freed at once.
 void* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size);
 
 // Memory management
-cmsBool   _cmsRegisterMemHandlerPlugin(cmsPluginBase* Plugin);
+cmsBool   _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 
 // Interpolation
-cmsBool  _cmsRegisterInterpPlugin(cmsPluginBase* Plugin);
+cmsBool  _cmsRegisterInterpPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 
 // Parametric curves
 cmsBool  _cmsRegisterParametricCurvesPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
@@ -228,9 +383,12 @@
 // Transform
 cmsBool  _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
 
+// Mutex
+cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
+
 // ---------------------------------------------------------------------------------------------------------
 
-// Suballocators. Those are blocks of memory that is freed at the end on whole block.
+// Suballocators.
 typedef struct _cmsSubAllocator_chunk_st {
 
     cmsUInt8Number* Block;
@@ -253,9 +411,264 @@
 _cmsSubAllocator* _cmsCreateSubAlloc(cmsContext ContextID, cmsUInt32Number Initial);
 void              _cmsSubAllocDestroy(_cmsSubAllocator* s);
 void*             _cmsSubAlloc(_cmsSubAllocator* s, cmsUInt32Number size);
+void*             _cmsSubAllocDup(_cmsSubAllocator* s, const void *ptr, cmsUInt32Number size);
 
 // ----------------------------------------------------------------------------------
 
+// The context clients.
+typedef enum {
+
+    UserPtr,            // User-defined pointer
+    Logger,
+    AlarmCodesContext,
+    AdaptationStateContext,
+    MemPlugin,
+    InterpPlugin,
+    CurvesPlugin,
+    FormattersPlugin,
+    TagTypePlugin,
+    TagPlugin,
+    IntentPlugin,
+    MPEPlugin,
+    OptimizationPlugin,
+    TransformPlugin,
+    MutexPlugin,
+
+    // Last in list
+    MemoryClientMax
+
+} _cmsMemoryClient;
+
+
+// Container for memory management plug-in.
+typedef struct {
+
+    _cmsMallocFnPtrType     MallocPtr;
+    _cmsMalloZerocFnPtrType MallocZeroPtr;
+    _cmsFreeFnPtrType       FreePtr;
+    _cmsReallocFnPtrType    ReallocPtr;
+    _cmsCallocFnPtrType     CallocPtr;
+    _cmsDupFnPtrType        DupPtr;
+
+} _cmsMemPluginChunkType;
+
+// Copy memory management function pointers from plug-in to chunk, taking care of missing routines
+void  _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr);
+
+// Internal structure for context
+struct _cmsContext_struct {
+
+    struct _cmsContext_struct* Next;  // Points to next context in the new style
+    _cmsSubAllocator* MemPool;        // The memory pool that stores context data
+
+    void* chunks[MemoryClientMax];    // array of pointers to client chunks. Memory itself is hold in the suballocator.
+                                      // If NULL, then it reverts to global Context0
+
+    _cmsMemPluginChunkType DefaultMemoryManager;  // The allocators used for creating the context itself. Cannot be overriden
+};
+
+// Returns a pointer to a valid context structure, including the global one if id is zero.
+// Verifies the magic number.
+struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID);
+
+// Returns the block assigned to the specific zone.
+void*     _cmsContextGetClientChunk(cmsContext id, _cmsMemoryClient mc);
+
+
+// Chunks of context memory by plug-in client -------------------------------------------------------
+
+// Those structures encapsulates all variables needed by the several context clients (mostly plug-ins)
+
+// Container for error logger -- not a plug-in
+typedef struct {
+
+    cmsLogErrorHandlerFunction LogErrorHandler;  // Set to NULL for Context0 fallback
+
+} _cmsLogErrorChunkType;
+
+// The global Context0 storage for error logger
+extern  _cmsLogErrorChunkType  _cmsLogErrorChunk;
+
+// Allocate and init error logger container.
+void _cmsAllocLogErrorChunk(struct _cmsContext_struct* ctx,
+                            const struct _cmsContext_struct* src);
+
+// Container for alarm codes -- not a plug-in
+typedef struct {
+
+    cmsUInt16Number AlarmCodes[cmsMAXCHANNELS];
+
+} _cmsAlarmCodesChunkType;
+
+// The global Context0 storage for alarm codes
+extern  _cmsAlarmCodesChunkType _cmsAlarmCodesChunk;
+
+// Allocate and init alarm codes container.
+void _cmsAllocAlarmCodesChunk(struct _cmsContext_struct* ctx,
+                            const struct _cmsContext_struct* src);
+
+// Container for adaptation state -- not a plug-in
+typedef struct {
+
+    cmsFloat64Number  AdaptationState;
+
+} _cmsAdaptationStateChunkType;
+
+// The global Context0 storage for adaptation state
+extern  _cmsAdaptationStateChunkType    _cmsAdaptationStateChunk;
+
+// Allocate and init adaptation state container.
+void _cmsAllocAdaptationStateChunk(struct _cmsContext_struct* ctx,
+                                   const struct _cmsContext_struct* src);
+
+
+// The global Context0 storage for memory management
+extern  _cmsMemPluginChunkType _cmsMemPluginChunk;
+
+// Allocate and init memory management container.
+void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx,
+                             const struct _cmsContext_struct* src);
+
+// Container for interpolation plug-in
+typedef struct {
+
+    cmsInterpFnFactory Interpolators;
+
+} _cmsInterpPluginChunkType;
+
+// The global Context0 storage for interpolation plug-in
+extern  _cmsInterpPluginChunkType _cmsInterpPluginChunk;
+
+// Allocate and init interpolation container.
+void _cmsAllocInterpPluginChunk(struct _cmsContext_struct* ctx,
+                                const struct _cmsContext_struct* src);
+
+// Container for parametric curves plug-in
+typedef struct {
+
+    struct _cmsParametricCurvesCollection_st* ParametricCurves;
+
+} _cmsCurvesPluginChunkType;
+
+// The global Context0 storage for tone curves plug-in
+extern  _cmsCurvesPluginChunkType _cmsCurvesPluginChunk;
+
+// Allocate and init parametric curves container.
+void _cmsAllocCurvesPluginChunk(struct _cmsContext_struct* ctx,
+                                                      const struct _cmsContext_struct* src);
+
+// Container for formatters plug-in
+typedef struct {
+
+    struct _cms_formatters_factory_list* FactoryList;
+
+} _cmsFormattersPluginChunkType;
+
+// The global Context0 storage for formatters plug-in
+extern  _cmsFormattersPluginChunkType _cmsFormattersPluginChunk;
+
+// Allocate and init formatters container.
+void _cmsAllocFormattersPluginChunk(struct _cmsContext_struct* ctx,
+                                                       const struct _cmsContext_struct* src);
+
+// This chunk type is shared by TagType plug-in and MPE Plug-in
+typedef struct {
+
+    struct _cmsTagTypeLinkedList_st* TagTypes;
+
+} _cmsTagTypePluginChunkType;
+
+
+// The global Context0 storage for tag types plug-in
+extern  _cmsTagTypePluginChunkType      _cmsTagTypePluginChunk;
+
+
+// The global Context0 storage for mult process elements plug-in
+extern  _cmsTagTypePluginChunkType      _cmsMPETypePluginChunk;
+
+// Allocate and init Tag types container.
+void _cmsAllocTagTypePluginChunk(struct _cmsContext_struct* ctx,
+                                                        const struct _cmsContext_struct* src);
+// Allocate and init MPE container.
+void _cmsAllocMPETypePluginChunk(struct _cmsContext_struct* ctx,
+                                                        const struct _cmsContext_struct* src);
+// Container for tag plug-in
+typedef struct {
+
+    struct _cmsTagLinkedList_st* Tag;
+
+} _cmsTagPluginChunkType;
+
+
+// The global Context0 storage for tag plug-in
+extern  _cmsTagPluginChunkType _cmsTagPluginChunk;
+
+// Allocate and init Tag container.
+void _cmsAllocTagPluginChunk(struct _cmsContext_struct* ctx,
+                                                      const struct _cmsContext_struct* src);
+
+// Container for intents plug-in
+typedef struct {
+
+    struct _cms_intents_list* Intents;
+
+} _cmsIntentsPluginChunkType;
+
+
+// The global Context0 storage for intents plug-in
+extern  _cmsIntentsPluginChunkType _cmsIntentsPluginChunk;
+
+// Allocate and init intents container.
+void _cmsAllocIntentsPluginChunk(struct _cmsContext_struct* ctx,
+                                                        const struct _cmsContext_struct* src);
+
+// Container for optimization plug-in
+typedef struct {
+
+    struct _cmsOptimizationCollection_st* OptimizationCollection;
+
+} _cmsOptimizationPluginChunkType;
+
+
+// The global Context0 storage for optimizers plug-in
+extern  _cmsOptimizationPluginChunkType _cmsOptimizationPluginChunk;
+
+// Allocate and init optimizers container.
+void _cmsAllocOptimizationPluginChunk(struct _cmsContext_struct* ctx,
+                                         const struct _cmsContext_struct* src);
+
+// Container for transform plug-in
+typedef struct {
+
+    struct _cmsTransformCollection_st* TransformCollection;
+
+} _cmsTransformPluginChunkType;
+
+// The global Context0 storage for full-transform replacement plug-in
+extern  _cmsTransformPluginChunkType _cmsTransformPluginChunk;
+
+// Allocate and init transform container.
+void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx,
+                                        const struct _cmsContext_struct* src);
+
+// Container for mutex plug-in
+typedef struct {
+
+    _cmsCreateMutexFnPtrType  CreateMutexPtr;
+    _cmsDestroyMutexFnPtrType DestroyMutexPtr;
+    _cmsLockMutexFnPtrType    LockMutexPtr;
+    _cmsUnlockMutexFnPtrType  UnlockMutexPtr;
+
+} _cmsMutexPluginChunkType;
+
+// The global Context0 storage for mutex plug-in
+extern  _cmsMutexPluginChunkType _cmsMutexPluginChunk;
+
+// Allocate and init mutex container.
+void _cmsAllocMutexPluginChunk(struct _cmsContext_struct* ctx,
+                                        const struct _cmsContext_struct* src);
+
+// ----------------------------------------------------------------------------------
 // MLU internal representation
 typedef struct {
 
@@ -347,10 +760,14 @@
     cmsBool                  TagSaveAsRaw[MAX_TABLE_TAG];        // True to write uncooked
     void *                   TagPtrs[MAX_TABLE_TAG];
     cmsTagTypeHandler*       TagTypeHandlers[MAX_TABLE_TAG];     // Same structure may be serialized on different types
-                                                                 // depending on profile version, so we keep track of the                                                             // type handler for each tag in the list.
+                                                                 // depending on profile version, so we keep track of the
+                                                                 // type handler for each tag in the list.
     // Special
     cmsBool                  IsWrite;
 
+    // Keep a mutex for cmsReadTag -- Note that this only works if the user includes a mutex plugin
+    void *                   UsrMutex;
+
 } _cmsICCPROFILE;
 
 // IO helpers for profiles
@@ -359,9 +776,9 @@
 int                  _cmsSearchTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, cmsBool lFollowLinks);
 
 // Tag types
-cmsTagTypeHandler*   _cmsGetTagTypeHandler(cmsTagTypeSignature sig);
+cmsTagTypeHandler*   _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig);
 cmsTagTypeSignature  _cmsGetTagTrueType(cmsHPROFILE hProfile, cmsTagSignature sig);
-cmsTagDescriptor*    _cmsGetTagDescriptor(cmsTagSignature sig);
+cmsTagDescriptor*    _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig);
 
 // Error logging ---------------------------------------------------------------------------------------------------------
 
@@ -372,7 +789,7 @@
 cmsInterpParams*     _cmsComputeInterpParams(cmsContext ContextID, int nSamples, int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags);
 cmsInterpParams*     _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags);
 void                 _cmsFreeInterpParams(cmsInterpParams* p);
-cmsBool              _cmsSetInterpolationRoutine(cmsInterpParams* p);
+cmsBool              _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p);
 
 // Curves ----------------------------------------------------------------------------------------------------------------
 
@@ -503,7 +920,8 @@
                                       cmsUInt16Number **Black,
                                       cmsUInt32Number *nOutputs);
 
-cmsBool          _cmsOptimizePipeline(cmsPipeline**    Lut,
+cmsBool          _cmsOptimizePipeline(cmsContext ContextID,
+                                      cmsPipeline**    Lut,
                                       int              Intent,
                                       cmsUInt32Number* InputFormat,
                                       cmsUInt32Number* OutputFormat,
@@ -528,7 +946,8 @@
 cmsBool         _cmsFormatterIsFloat(cmsUInt32Number Type);
 cmsBool         _cmsFormatterIs8bit(cmsUInt32Number Type);
 
-cmsFormatter    _cmsGetFormatter(cmsUInt32Number Type,          // Specific type, i.e. TYPE_RGB_8
+cmsFormatter    _cmsGetFormatter(cmsContext ContextID,
+                                 cmsUInt32Number Type,          // Specific type, i.e. TYPE_RGB_8
                                  cmsFormatterDirection Dir,
                                  cmsUInt32Number dwFlags);
 
--- a/jdk/src/java.desktop/share/native/liblcms/lcms2_plugin.h	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.desktop/share/native/liblcms/lcms2_plugin.h	Wed Jul 05 20:01:50 2017 +0200
@@ -231,6 +231,7 @@
 #define cmsPluginMultiProcessElementSig      0x6D706548     // 'mpeH'
 #define cmsPluginOptimizationSig             0x6F707448     // 'optH'
 #define cmsPluginTransformSig                0x7A666D48     // 'xfmH'
+#define cmsPluginMutexSig                    0x6D747A48     // 'mtxH'
 
 typedef struct _cmsPluginBaseStruct {
 
@@ -247,19 +248,28 @@
 //----------------------------------------------------------------------------------------------------------
 
 // Memory handler. Each new plug-in type replaces current behaviour
+
+typedef void* (* _cmsMallocFnPtrType)(cmsContext ContextID, cmsUInt32Number size);
+typedef void  (* _cmsFreeFnPtrType)(cmsContext ContextID, void *Ptr);
+typedef void* (* _cmsReallocFnPtrType)(cmsContext ContextID, void* Ptr, cmsUInt32Number NewSize);
+
+typedef void* (* _cmsMalloZerocFnPtrType)(cmsContext ContextID, cmsUInt32Number size);
+typedef void* (* _cmsCallocFnPtrType)(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Number size);
+typedef void* (* _cmsDupFnPtrType)(cmsContext ContextID, const void* Org, cmsUInt32Number size);
+
 typedef struct {
 
         cmsPluginBase base;
 
         // Required
-        void * (* MallocPtr)(cmsContext ContextID, cmsUInt32Number size);
-        void   (* FreePtr)(cmsContext ContextID, void *Ptr);
-        void * (* ReallocPtr)(cmsContext ContextID, void* Ptr, cmsUInt32Number NewSize);
+        _cmsMallocFnPtrType  MallocPtr;
+        _cmsFreeFnPtrType    FreePtr;
+        _cmsReallocFnPtrType ReallocPtr;
 
         // Optional
-        void * (* MallocZeroPtr)(cmsContext ContextID, cmsUInt32Number size);
-        void * (* CallocPtr)(cmsContext ContextID, cmsUInt32Number num, cmsUInt32Number size);
-        void * (* DupPtr)(cmsContext ContextID, const void* Org, cmsUInt32Number size);
+       _cmsMalloZerocFnPtrType MallocZeroPtr;
+       _cmsCallocFnPtrType     CallocPtr;
+       _cmsDupFnPtrType        DupPtr;
 
 } cmsPluginMemHandler;
 
@@ -622,6 +632,29 @@
 
 }  cmsPluginTransform;
 
+//----------------------------------------------------------------------------------------------------------
+// Mutex
+
+typedef void*    (* _cmsCreateMutexFnPtrType)(cmsContext ContextID);
+typedef void     (* _cmsDestroyMutexFnPtrType)(cmsContext ContextID, void* mtx);
+typedef cmsBool  (* _cmsLockMutexFnPtrType)(cmsContext ContextID, void* mtx);
+typedef void     (* _cmsUnlockMutexFnPtrType)(cmsContext ContextID, void* mtx);
+
+typedef struct {
+      cmsPluginBase     base;
+
+     _cmsCreateMutexFnPtrType  CreateMutexPtr;
+     _cmsDestroyMutexFnPtrType DestroyMutexPtr;
+     _cmsLockMutexFnPtrType    LockMutexPtr;
+     _cmsUnlockMutexFnPtrType  UnlockMutexPtr;
+
+}  cmsPluginMutex;
+
+CMSAPI void*   CMSEXPORT _cmsCreateMutex(cmsContext ContextID);
+CMSAPI void    CMSEXPORT _cmsDestroyMutex(cmsContext ContextID, void* mtx);
+CMSAPI cmsBool CMSEXPORT _cmsLockMutex(cmsContext ContextID, void* mtx);
+CMSAPI void    CMSEXPORT _cmsUnlockMutex(cmsContext ContextID, void* mtx);
+
 
 #ifndef CMS_USE_CPP_API
 #   ifdef __cplusplus
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindow.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindow.java	Wed Jul 05 20:01:50 2017 +0200
@@ -55,7 +55,6 @@
    */
     private final static int AWT_MULTICLICK_SMUDGE = 4;
     // ButtonXXX events stuff
-    static int rbutton = 0;
     static int lastX = 0, lastY = 0;
     static long lastTime = 0;
     static long lastButton = 0;
@@ -632,23 +631,6 @@
         return res;
     }
 
-    /**
-     * Returns true if this event is disabled and shouldn't be passed to Java.
-     * Default implementation returns false for all events.
-     */
-    static int getRightButtonNumber() {
-        if (rbutton == 0) { // not initialized yet
-            XToolkit.awtLock();
-            try {
-                rbutton = XlibWrapper.XGetPointerMapping(XToolkit.getDisplay(), XlibWrapper.ibuffer, 3);
-            }
-            finally {
-                XToolkit.awtUnlock();
-            }
-        }
-        return rbutton;
-    }
-
     static int getMouseMovementSmudge() {
         //TODO: It's possible to read corresponding settings
         return AWT_MULTICLICK_SMUDGE;
@@ -716,11 +698,7 @@
             /*
                Check for popup trigger !!
             */
-            if (lbutton == getRightButtonNumber() || lbutton > 2) {
-                popupTrigger = true;
-            } else {
-                popupTrigger = false;
-            }
+            popupTrigger = (lbutton == 3);
         }
 
         button = XConstants.buttons[lbutton - 1];
--- a/jdk/src/java.desktop/unix/classes/sun/awt/datatransfer/flavormap.properties	Wed Jul 05 20:01:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-#
-# This properties file is used to initialize the default
-# java.awt.datatransfer.SystemFlavorMap. It contains the X11 platform-specific,
-# default mappings between common X11 selection atoms and platform-independent
-# MIME type strings, which will be converted into
-# java.awt.datatransfer.DataFlavors.
-#
-# The standard format is:
-#
-# <native>=<MIME type>,<MIME type>, ...
-#
-# <native> should be a string identifier that the native platform will
-# recognize as a valid data format. <MIME type> should specify both a MIME
-# primary type and a MIME subtype separated by a '/'. The MIME type may include
-# parameters, where each parameter is a key/value pair separated by '=', and
-# where each parameter to the MIME type is separated by a ';'.
-#
-# Because SystemFlavorMap implements FlavorTable, developers are free to
-# duplicate DataFlavor values and set multiple values for a single native by
-# separating them with ",". If a mapping contains a duplicate key or value,
-# earlier mappings which included this key or value will be preferred.
-#
-# Mappings whose values specify DataFlavors with primary MIME types of
-# "text", and which support the charset parameter, should specify the exact
-# format in which the native platform expects the data. The "charset"
-# parameter specifies the char to byte encoding, the "eoln" parameter
-# specifies the end-of-line marker, and the "terminators" parameter specifies
-# the number of terminating NUL bytes. Note that "eoln" and "terminators"
-# are not standardized MIME type parameters. They are specific to this file
-# format ONLY. They will not appear in any of the DataFlavors returned by the
-# SystemFlavorMap at the Java level.
-#
-# If the "charset" parameter is omitted, or has zero length, the platform
-# default encoding is assumed. If the "eoln" parameter is omitted, or has
-# zero length, "\n" is assumed. If the "terminators" parameter is omitted,
-# or has a value less than zero, zero is assumed.
-#
-# Upon initialization, the data transfer subsystem will record the specified
-# details of the native text format, but the default SystemFlavorMap will
-# present a large set of synthesized DataFlavors which map, in both
-# directions, to the native. After receiving data from the application in one
-# of the synthetic DataFlavors, the data transfer subsystem will transform
-# the data stream into the format specified in this file before passing the
-# transformed stream to the native system.
-#
-# Mappings whose values specify DataFlavors with primary MIME types of
-# "text", but which do not support the charset parameter, will be treated as
-# opaque, 8-bit data. They will not undergo any transformation process, and
-# any "charset", "eoln", or "terminators" parameters specified in this file
-# will be ignored.
-#
-# See java.awt.datatransfer.DataFlavor.selectBestTextFlavor for a list of
-# text flavors which support the charset parameter.
-
-UTF8_STRING=text/plain;charset=UTF-8;eoln="\n";terminators=0
-
-# The COMPOUND_TEXT support for inter-client text transfer is disabled by 
-# default. The reason is that many native applications prefer this format over 
-# other native text formats, but are unable to decode the textual data in this 
-# format properly. This results in java-to-native text transfer failures.
-# To enable the COMPOUND_TEXT support for this JRE installation uncomment 
-# the line below.
-
-# COMPOUND_TEXT=text/plain;charset=x-compound-text;eoln="\n";terminators=0
-
-TEXT=text/plain;eoln="\n";terminators=0
-STRING=text/plain;charset=iso8859-1;eoln="\n";terminators=0
-FILE_NAME=application/x-java-file-list;class=java.util.List
-text/uri-list=application/x-java-file-list;class=java.util.List
-PNG=image/x-java-image;class=java.awt.Image
-JFIF=image/x-java-image;class=java.awt.Image
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/unix/classes/sun/datatransfer/resources/flavormap.properties	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,71 @@
+#
+# This properties file is used to initialize the default
+# java.awt.datatransfer.SystemFlavorMap. It contains the X11 platform-specific,
+# default mappings between common X11 selection atoms and platform-independent
+# MIME type strings, which will be converted into
+# java.awt.datatransfer.DataFlavors.
+#
+# The standard format is:
+#
+# <native>=<MIME type>,<MIME type>, ...
+#
+# <native> should be a string identifier that the native platform will
+# recognize as a valid data format. <MIME type> should specify both a MIME
+# primary type and a MIME subtype separated by a '/'. The MIME type may include
+# parameters, where each parameter is a key/value pair separated by '=', and
+# where each parameter to the MIME type is separated by a ';'.
+#
+# Because SystemFlavorMap implements FlavorTable, developers are free to
+# duplicate DataFlavor values and set multiple values for a single native by
+# separating them with ",". If a mapping contains a duplicate key or value,
+# earlier mappings which included this key or value will be preferred.
+#
+# Mappings whose values specify DataFlavors with primary MIME types of
+# "text", and which support the charset parameter, should specify the exact
+# format in which the native platform expects the data. The "charset"
+# parameter specifies the char to byte encoding, the "eoln" parameter
+# specifies the end-of-line marker, and the "terminators" parameter specifies
+# the number of terminating NUL bytes. Note that "eoln" and "terminators"
+# are not standardized MIME type parameters. They are specific to this file
+# format ONLY. They will not appear in any of the DataFlavors returned by the
+# SystemFlavorMap at the Java level.
+#
+# If the "charset" parameter is omitted, or has zero length, the platform
+# default encoding is assumed. If the "eoln" parameter is omitted, or has
+# zero length, "\n" is assumed. If the "terminators" parameter is omitted,
+# or has a value less than zero, zero is assumed.
+#
+# Upon initialization, the data transfer subsystem will record the specified
+# details of the native text format, but the default SystemFlavorMap will
+# present a large set of synthesized DataFlavors which map, in both
+# directions, to the native. After receiving data from the application in one
+# of the synthetic DataFlavors, the data transfer subsystem will transform
+# the data stream into the format specified in this file before passing the
+# transformed stream to the native system.
+#
+# Mappings whose values specify DataFlavors with primary MIME types of
+# "text", but which do not support the charset parameter, will be treated as
+# opaque, 8-bit data. They will not undergo any transformation process, and
+# any "charset", "eoln", or "terminators" parameters specified in this file
+# will be ignored.
+#
+# See java.awt.datatransfer.DataFlavor.selectBestTextFlavor for a list of
+# text flavors which support the charset parameter.
+
+UTF8_STRING=text/plain;charset=UTF-8;eoln="\n";terminators=0
+
+# The COMPOUND_TEXT support for inter-client text transfer is disabled by 
+# default. The reason is that many native applications prefer this format over 
+# other native text formats, but are unable to decode the textual data in this 
+# format properly. This results in java-to-native text transfer failures.
+# To enable the COMPOUND_TEXT support for this JRE installation uncomment 
+# the line below.
+
+# COMPOUND_TEXT=text/plain;charset=x-compound-text;eoln="\n";terminators=0
+
+TEXT=text/plain;eoln="\n";terminators=0
+STRING=text/plain;charset=iso8859-1;eoln="\n";terminators=0
+FILE_NAME=application/x-java-file-list;class=java.util.List
+text/uri-list=application/x-java-file-list;class=java.util.List
+PNG=image/x-java-image;class=java.awt.Image
+JFIF=image/x-java-image;class=java.awt.Image
--- a/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRSolidSrcPict.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRSolidSrcPict.java	Wed Jul 05 20:01:50 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved.
 
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -31,12 +31,14 @@
 
     XRSurfaceData srcPict;
     XRColor xrCol;
-    int curPixVal = -1;
+    int curPixVal;
 
     public XRSolidSrcPict(XRBackend con, int parentXid) {
         this.con = con;
 
         xrCol = new XRColor();
+        curPixVal = 0xFF000000;
+
         int solidPixmap = con.createPixmap(parentXid, 32, 1, 1);
         int solidSrcPictXID = con.createPicture(solidPixmap, XRUtils.PictStandardARGB32);
         con.setPictureRepeat(solidSrcPictXID, XRUtils.RepeatNormal);
--- a/jdk/src/java.desktop/windows/classes/sun/awt/datatransfer/flavormap.properties	Wed Jul 05 20:01:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-#
-# This properties file is used to initialize the default
-# java.awt.datatransfer.SystemFlavorMap. It contains the Win32 platform-
-# specific, default mappings between common Win32 Clipboard atoms and platform-
-# independent MIME type strings, which will be converted into
-# java.awt.datatransfer.DataFlavors.
-#
-# The standard format is:
-#
-# <native>=<MIME type>,<MIME type>, ...
-#
-# <native> should be a string identifier that the native platform will
-# recognize as a valid data format. <MIME type> should specify both a MIME
-# primary type and a MIME subtype separated by a '/'. The MIME type may include
-# parameters, where each parameter is a key/value pair separated by '=', and
-# where each parameter to the MIME type is separated by a ';'.
-#
-# Because SystemFlavorMap implements FlavorTable, developers are free to
-# duplicate DataFlavor values and set multiple values for a single native by
-# separating them with ",". If a mapping contains a duplicate key or value,
-# earlier mappings which included this key or value will be preferred.#
-# Mappings whose values specify DataFlavors with primary MIME types of
-# "text", and which support the charset parameter, should specify the exact
-# format in which the native platform expects the data. The "charset"
-# parameter specifies the char to byte encoding, the "eoln" parameter
-# specifies the end-of-line marker, and the "terminators" parameter specifies
-# the number of terminating NUL bytes. Note that "eoln" and "terminators"
-# are not standardized MIME type parameters. They are specific to this file
-# format ONLY. They will not appear in any of the DataFlavors returned by the
-# SystemFlavorMap at the Java level.
-#
-# If the "charset" parameter is omitted, or has zero length, the platform
-# default encoding is assumed. If the "eoln" parameter is omitted, or has
-# zero length, "\n" is assumed. If the "terminators" parameter is omitted,
-# or has a value less than zero, zero is assumed.
-#
-# Upon initialization, the data transfer subsystem will record the specified
-# details of the native text format, but the default SystemFlavorMap will
-# present a large set of synthesized DataFlavors which map, in both
-# directions, to the native. After receiving data from the application in one
-# of the synthetic DataFlavors, the data transfer subsystem will transform
-# the data stream into the format specified in this file before passing the
-# transformed stream to the native system.
-#
-# Mappings whose values specify DataFlavors with primary MIME types of
-# "text", but which do not support the charset parameter, will be treated as
-# opaque, 8-bit data. They will not undergo any transformation process, and
-# any "charset", "eoln", or "terminators" parameters specified in this file
-# will be ignored.
-#
-# See java.awt.datatransfer.DataFlavor.selectBestTextFlavor for a list of
-# text flavors which support the charset parameter.
-
-UNICODE\ TEXT=text/plain;charset=utf-16le;eoln="\r\n";terminators=2
-TEXT=text/plain;eoln="\r\n";terminators=1
-HTML\ Format=text/html;charset=utf-8;eoln="\r\n";terminators=1
-Rich\ Text\ Format=text/rtf
-HDROP=application/x-java-file-list;class=java.util.List
-PNG=image/x-java-image;class=java.awt.Image
-JFIF=image/x-java-image;class=java.awt.Image
-DIB=image/x-java-image;class=java.awt.Image
-ENHMETAFILE=image/x-java-image;class=java.awt.Image
-METAFILEPICT=image/x-java-image;class=java.awt.Image
-LOCALE=application/x-java-text-encoding;class="[B"
-UniformResourceLocator=application/x-java-url;class=java.net.URL,\
-                       text/uri-list;eoln="\r\n";terminators=1,\
-                       text/plain;eoln="\r\n";terminators=1
-FileGroupDescriptorW=application/x-java-file-list;class=java.util.List
-FileGroupDescriptor=application/x-java-file-list;class=java.util.List
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WBufferStrategy.java	Wed Jul 05 20:01:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.awt.windows;
-
-import java.awt.Image;
-import java.awt.Component;
-
-/**
- * This sun-private class exists solely to get a handle to
- * the back buffer associated with a Component.  If that
- * Component has a BufferStrategy with >1 buffer, then the
- * Image subclass associated with that buffer will be returned.
- * Note: the class is used by the JAWT3d.
- */
-public final class WBufferStrategy {
-
-    private static native void initIDs(Class <?> componentClass);
-
-    static {
-        initIDs(Component.class);
-    }
-
-    public static native Image getDrawBuffer(Component comp);
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/windows/classes/sun/datatransfer/resources/flavormap.properties	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,69 @@
+#
+# This properties file is used to initialize the default
+# java.awt.datatransfer.SystemFlavorMap. It contains the Win32 platform-
+# specific, default mappings between common Win32 Clipboard atoms and platform-
+# independent MIME type strings, which will be converted into
+# java.awt.datatransfer.DataFlavors.
+#
+# The standard format is:
+#
+# <native>=<MIME type>,<MIME type>, ...
+#
+# <native> should be a string identifier that the native platform will
+# recognize as a valid data format. <MIME type> should specify both a MIME
+# primary type and a MIME subtype separated by a '/'. The MIME type may include
+# parameters, where each parameter is a key/value pair separated by '=', and
+# where each parameter to the MIME type is separated by a ';'.
+#
+# Because SystemFlavorMap implements FlavorTable, developers are free to
+# duplicate DataFlavor values and set multiple values for a single native by
+# separating them with ",". If a mapping contains a duplicate key or value,
+# earlier mappings which included this key or value will be preferred.#
+# Mappings whose values specify DataFlavors with primary MIME types of
+# "text", and which support the charset parameter, should specify the exact
+# format in which the native platform expects the data. The "charset"
+# parameter specifies the char to byte encoding, the "eoln" parameter
+# specifies the end-of-line marker, and the "terminators" parameter specifies
+# the number of terminating NUL bytes. Note that "eoln" and "terminators"
+# are not standardized MIME type parameters. They are specific to this file
+# format ONLY. They will not appear in any of the DataFlavors returned by the
+# SystemFlavorMap at the Java level.
+#
+# If the "charset" parameter is omitted, or has zero length, the platform
+# default encoding is assumed. If the "eoln" parameter is omitted, or has
+# zero length, "\n" is assumed. If the "terminators" parameter is omitted,
+# or has a value less than zero, zero is assumed.
+#
+# Upon initialization, the data transfer subsystem will record the specified
+# details of the native text format, but the default SystemFlavorMap will
+# present a large set of synthesized DataFlavors which map, in both
+# directions, to the native. After receiving data from the application in one
+# of the synthetic DataFlavors, the data transfer subsystem will transform
+# the data stream into the format specified in this file before passing the
+# transformed stream to the native system.
+#
+# Mappings whose values specify DataFlavors with primary MIME types of
+# "text", but which do not support the charset parameter, will be treated as
+# opaque, 8-bit data. They will not undergo any transformation process, and
+# any "charset", "eoln", or "terminators" parameters specified in this file
+# will be ignored.
+#
+# See java.awt.datatransfer.DataFlavor.selectBestTextFlavor for a list of
+# text flavors which support the charset parameter.
+
+UNICODE\ TEXT=text/plain;charset=utf-16le;eoln="\r\n";terminators=2
+TEXT=text/plain;eoln="\r\n";terminators=1
+HTML\ Format=text/html;charset=utf-8;eoln="\r\n";terminators=1
+Rich\ Text\ Format=text/rtf
+HDROP=application/x-java-file-list;class=java.util.List
+PNG=image/x-java-image;class=java.awt.Image
+JFIF=image/x-java-image;class=java.awt.Image
+DIB=image/x-java-image;class=java.awt.Image
+ENHMETAFILE=image/x-java-image;class=java.awt.Image
+METAFILEPICT=image/x-java-image;class=java.awt.Image
+LOCALE=application/x-java-text-encoding;class="[B"
+UniformResourceLocator=application/x-java-url;class=java.net.URL,\
+                       text/uri-list;eoln="\r\n";terminators=1,\
+                       text/plain;eoln="\r\n";terminators=1
+FileGroupDescriptorW=application/x-java-file-list;class=java.util.List
+FileGroupDescriptor=application/x-java-file-list;class=java.util.List
--- a/jdk/src/java.desktop/windows/native/libawt/sun/java2d/d3d/D3DPipeline.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include "D3DPipeline.h"
-
-BOOL APIENTRY DllMain( HANDLE hModule,
-                       DWORD  ul_reason_for_call,
-                       LPVOID lpReserved)
-{
-    switch (ul_reason_for_call) {
-    case DLL_PROCESS_ATTACH:
-    case DLL_THREAD_ATTACH:
-    case DLL_THREAD_DETACH:
-    case DLL_PROCESS_DETACH:
-        break;
-    }
-    return TRUE;
-}
--- a/jdk/src/java.desktop/windows/native/libawt/sun/windows/WBufferStrategy.cpp	Wed Jul 05 20:01:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include "sun_awt_windows_WBufferStrategy.h"
-#include "jni_util.h"
-
-
-static jmethodID getBackBufferID;
-
-/*
- * Class:     sun_awt_windows_WBufferStrategy
- * Method:    initIDs
- * Signature: (Ljava/lang/Class;)V
- */
-JNIEXPORT void JNICALL
-Java_sun_awt_windows_WBufferStrategy_initIDs(JNIEnv *env, jclass wbs,
-                                             jclass componentClass)
-{
-    getBackBufferID = env->GetMethodID(componentClass, "getBackBuffer",
-                                       "()Ljava/awt/Image;");
-}
-
-/**
- * Native method of WBufferStrategy.java.  Given a Component
- * object, this method will find the back buffer associated
- * with the Component's BufferStrategy and return a handle
- * to it.
- */
-extern "C" JNIEXPORT jobject JNICALL
-Java_sun_awt_windows_WBufferStrategy_getDrawBuffer(JNIEnv *env, jclass wbs,
-                                                   jobject component)
-{
-    if (!JNU_IsNull(env, getBackBufferID)) {
-        return env->CallObjectMethod(component, getBackBufferID);
-    } else {
-        return NULL;
-    }
-}
--- a/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIConnector.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIConnector.java	Wed Jul 05 20:01:50 2017 +0200
@@ -1335,66 +1335,94 @@
                 int maxNotifications,
                 long timeout)
                 throws IOException, ClassNotFoundException {
-            IOException org;
 
+            boolean retried = false;
             while (true) { // used for a successful re-connection
+                           // or a transient network problem
                 try {
                     return connection.fetchNotifications(clientSequenceNumber,
                             maxNotifications,
-                            timeout);
+                            timeout); // return normally
                 } catch (IOException ioe) {
-                    org = ioe;
+                    // Examine the chain of exceptions to determine whether this
+                    // is a deserialization issue. If so - we propagate the
+                    // appropriate exception to the caller, who will then
+                    // proceed with fetching notifications one by one
+                    rethrowDeserializationException(ioe);
 
-                    // inform of IOException
                     try {
                         communicatorAdmin.gotIOException(ioe);
-
-                        // The connection should be re-established.
-                        continue;
+                        // reconnection OK, back to "while" to do again
                     } catch (IOException ee) {
-                        // No more fetch, the Exception will be re-thrown.
-                        break;
-                    } // never reached
-                } // never reached
-            }
+                        boolean toClose = false;
 
-            // specially treating for an UnmarshalException
-            if (org instanceof UnmarshalException) {
-                UnmarshalException ume = (UnmarshalException)org;
-
-                if (ume.detail instanceof ClassNotFoundException)
-                    throw (ClassNotFoundException) ume.detail;
+                        synchronized (this) {
+                            if (terminated) {
+                                // the connection is closed.
+                                throw ioe;
+                            } else if (retried) {
+                                toClose = true;
+                            }
+                        }
 
-                /* In Sun's RMI implementation, if a method return
-                   contains an unserializable object, then we get
-                   UnmarshalException wrapping WriteAbortedException
-                   wrapping NotSerializableException.  In that case we
-                   extract the NotSerializableException so that our
-                   caller can realize it should try to skip past the
-                   notification that presumably caused it.  It's not
-                   certain that every other RMI implementation will
-                   generate this exact exception sequence.  If not, we
-                   will not detect that the problem is due to an
-                   unserializable object, and we will stop trying to
-                   receive notifications from the server.  It's not
-                   clear we can do much better.  */
-                if (ume.detail instanceof WriteAbortedException) {
-                    WriteAbortedException wae =
-                            (WriteAbortedException) ume.detail;
-                    if (wae.detail instanceof IOException)
-                        throw (IOException) wae.detail;
+                        if (toClose) {
+                            // JDK-8049303
+                            // We received an IOException - but the communicatorAdmin
+                            // did not close the connection - possibly because
+                            // the original exception was raised by a transient network
+                            // problem?
+                            // We already know that this exception is not due to a deserialization
+                            // issue as we already took care of that before involving the
+                            // communicatorAdmin. Moreover - we already made one retry attempt
+                            // at fetching the same batch of notifications - and the
+                            // problem persisted.
+                            // Since trying again doesn't seem to solve the issue, we will now
+                            // close the connection. Doing otherwise might cause the
+                            // NotifFetcher thread to die silently.
+                            final Notification failedNotif =
+                                    new JMXConnectionNotification(
+                                    JMXConnectionNotification.FAILED,
+                                    this,
+                                    connectionId,
+                                    clientNotifSeqNo++,
+                                    "Failed to communicate with the server: " + ioe.toString(),
+                                    ioe);
+
+                            sendNotification(failedNotif);
+
+                            try {
+                                close(true);
+                            } catch (Exception e) {
+                                // OK.
+                                // We are closing
+                            }
+                            throw ioe; // the connection is closed here.
+                        } else {
+                            // JDK-8049303 possible transient network problem,
+                            // let's try one more time
+                            retried = true;
+                        }
+                    }
                 }
-            } else if (org instanceof MarshalException) {
+            }
+        }
+
+        private void rethrowDeserializationException(IOException ioe)
+                throws ClassNotFoundException, IOException {
+            // specially treating for an UnmarshalException
+            if (ioe instanceof UnmarshalException) {
+                throw ioe; // the fix of 6937053 made ClientNotifForwarder.fetchNotifs
+                           // fetch one by one with UnmarshalException
+            } else if (ioe instanceof MarshalException) {
                 // IIOP will throw MarshalException wrapping a NotSerializableException
                 // when a server fails to serialize a response.
-                MarshalException me = (MarshalException)org;
+                MarshalException me = (MarshalException)ioe;
                 if (me.detail instanceof NotSerializableException) {
                     throw (NotSerializableException)me.detail;
                 }
             }
 
-            // Not serialization problem, simply re-throw the orginal exception
-            throw org;
+            // Not serialization problem, return.
         }
 
         protected Integer addListenerForMBeanRemovedNotif()
--- a/jdk/src/java.security.jgss/share/classes/com/sun/security/jgss/AuthorizationDataEntry.java	Wed Jul 05 20:01:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.security.jgss;
-
-/**
- * Kerberos 5 AuthorizationData entry.
- */
-@jdk.Exported
-public final class AuthorizationDataEntry {
-
-    private final int type;
-    private final byte[] data;
-
-    /**
-     * Create an AuthorizationDataEntry object.
-     * @param type the ad-type
-     * @param data the ad-data, a copy of the data will be saved
-     * inside the object.
-     */
-    public AuthorizationDataEntry(int type, byte[] data) {
-        this.type = type;
-        this.data = data.clone();
-    }
-
-    /**
-     * Get the ad-type field.
-     * @return ad-type
-     */
-    public int getType() {
-        return type;
-    }
-
-    /**
-     * Get a copy of the ad-data field.
-     * @return ad-data
-     */
-    public byte[] getData() {
-        return data.clone();
-    }
-
-    public String toString() {
-        return "AuthorizationDataEntry: type="+type+", data=" +
-                data.length + " bytes:\n" +
-                new sun.misc.HexDumpEncoder().encodeBuffer(data);
-    }
-}
--- a/jdk/src/java.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSContext.java	Wed Jul 05 20:01:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +0,0 @@
-/*
- * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.security.jgss;
-
-import org.ietf.jgss.*;
-
-/**
- * The extended GSSContext interface for supporting additional
- * functionalities not defined by {@code org.ietf.jgss.GSSContext},
- * such as querying context-specific attributes.
- */
-@jdk.Exported
-public interface ExtendedGSSContext extends GSSContext {
-    /**
-     * Return the mechanism-specific attribute associated with {@code type}.
-     * <p>
-     * If there is a security manager, an {@link InquireSecContextPermission}
-     * with the name {@code type.mech} must be granted. Otherwise, this could
-     * result in a {@link SecurityException}.<p>
-     *
-     * Example:
-     * <pre>
-     *      GSSContext ctxt = m.createContext(...)
-     *      // Establishing the context
-     *      if (ctxt instanceof ExtendedGSSContext) {
-     *          ExtendedGSSContext ex = (ExtendedGSSContext)ctxt;
-     *          try {
-     *              Key key = (key)ex.inquireSecContext(
-     *                      InquireType.KRB5_GET_SESSION_KEY);
-     *              // read key info
-     *          } catch (GSSException gsse) {
-     *              // deal with exception
-     *          }
-     *      }
-     * </pre>
-     * @param type the type of the attribute requested
-     * @return the attribute, see the method documentation for details.
-     * @throws GSSException containing  the following
-     * major error codes:
-     *   {@link GSSException#BAD_MECH GSSException.BAD_MECH} if the mechanism
-     *   does not support this method,
-     *   {@link GSSException#UNAVAILABLE GSSException.UNAVAILABLE} if the
-     *   type specified is not supported,
-     *   {@link GSSException#NO_CONTEXT GSSException.NO_CONTEXT} if the
-     *   security context is invalid,
-     *   {@link GSSException#FAILURE GSSException.FAILURE} for other
-     *   unspecified failures.
-     * @throws SecurityException if a security manager exists and a proper
-     *   {@link InquireSecContextPermission} is not granted.
-     * @see InquireSecContextPermission
-     * @see InquireType
-     */
-    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/java.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSCredential.java	Wed Jul 05 20:01:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.security.jgss;
-
-import org.ietf.jgss.*;
-
-/**
- * The extended GSSCredential interface for supporting additional
- * functionalities not defined by {@code org.ietf.jgss.GSSCredential}.
- * @since 1.8
- */
-@jdk.Exported
-public interface ExtendedGSSCredential extends GSSCredential {
-    /**
-     * Impersonates a principal. In Kerberos, this can be implemented
-     * using the Microsoft S4U2self extension.
-     * <p>
-     * A {@link GSSException#NO_CRED GSSException.NO_CRED} will be thrown if the
-     * impersonation fails. A {@link GSSException#FAILURE GSSException.FAILURE}
-     * will be  thrown if the impersonation method is not available to this
-     * credential object.
-     * @param name the name of the principal to impersonate
-     * @return a credential for that principal
-     * @throws GSSException  containing the following
-     * major error codes:
-     *   {@link GSSException#NO_CRED GSSException.NO_CRED}
-     *   {@link GSSException#FAILURE GSSException.FAILURE}
-     */
-    public GSSCredential impersonate(GSSName name) throws GSSException;
-}
--- a/jdk/src/java.security.jgss/share/classes/com/sun/security/jgss/GSSUtil.java	Wed Jul 05 20:01:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.security.jgss;
-
-import javax.security.auth.Subject;
-import org.ietf.jgss.GSSName;
-import org.ietf.jgss.GSSCredential;
-
-/**
- * GSS-API Utilities for using in conjunction with Sun Microsystem's
- * implementation of Java GSS-API.
- */
-@jdk.Exported
-public class GSSUtil {
-
-    /**
-     * Use this method to convert a GSSName and GSSCredential into a
-     * Subject. Typically this would be done by a server that wants to
-     * impersonate a client thread at the Java level by setting a client
-     * Subject in the current access control context. If the server is merely
-     * interested in using a principal based policy in its local JVM, then
-     * it only needs to provide the GSSName of the client.
-     *
-     * The elements from the GSSName are placed in the principals set of this
-     * Subject and those from the GSSCredential are placed in the private
-     * credentials set of the Subject. Any Kerberos specific elements that
-     * are added to the subject will be instances of the standard Kerberos
-     * implementation classes defined in javax.security.auth.kerberos.
-     *
-     * @return a Subject with the entries that contain elements from the
-     * given GSSName and GSSCredential.
-     *
-     * @param principals a GSSName containing one or more mechanism specific
-     * representations of the same entity. These mechanism specific
-     * representations will be populated in the returned Subject's principal
-     * set.
-     *
-     * @param credentials a GSSCredential containing one or more mechanism
-     * specific credentials for the same entity. These mechanism specific
-     * credentials will be populated in the returned Subject's private
-     * credential set. Passing in a value of null will imply that the private
-     * credential set should be left empty.
-     */
-    public static Subject createSubject(GSSName principals,
-                                     GSSCredential credentials) {
-
-        return  sun.security.jgss.GSSUtil.getSubject(principals,
-                                                     credentials);
-    }
-}
--- a/jdk/src/java.security.jgss/share/classes/com/sun/security/jgss/InquireSecContextPermission.java	Wed Jul 05 20:01:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.security.jgss;
-
-import java.security.BasicPermission;
-
-/**
- * This class is used to protect various attributes of an established
- * GSS security context that can be accessed using the
- * {@link com.sun.security.jgss.ExtendedGSSContext#inquireSecContext}
- * method.
- *
- * <p>The target name is the {@link InquireType} allowed.
- */
-@jdk.Exported
-public final class InquireSecContextPermission extends BasicPermission {
-    private static final long serialVersionUID = -7131173349668647297L;
-
-    /**
-     * Constructs a new {@code InquireSecContextPermission} object with
-     * the specified name. The name is the symbolic name of the
-     * {@link InquireType} allowed.
-     *
-     * @param name the {@link InquireType} allowed by this
-     * permission. "*" means all {@link InquireType}s are allowed.
-     *
-     * @throws NullPointerException if <code>name</code> is <code>null</code>.
-     * @throws IllegalArgumentException if <code>name</code> is empty.
-     */
-    public InquireSecContextPermission(String name) {
-        super(name);
-    }
-}
--- a/jdk/src/java.security.jgss/share/classes/com/sun/security/jgss/InquireType.java	Wed Jul 05 20:01:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.security.jgss;
-
-/**
- * Attribute types that can be specified as an argument of
- * {@link com.sun.security.jgss.ExtendedGSSContext#inquireSecContext}
- */
-@jdk.Exported
-public enum InquireType {
-    /**
-     * Attribute type for retrieving the session key of an established
-     * Kerberos 5 security context. The returned object is an instance of
-     * {@link java.security.Key}, which has the following properties:
-     *    <ul>
-     *    <li>Algorithm: enctype as a string, where
-     *        enctype is defined in RFC 3961, section 8.
-     *    <li>Format: "RAW"
-     *    <li>Encoded form: the raw key bytes, not in any ASN.1 encoding
-     *    </ul>
-     * @deprecated as of 1.9, replaced by {@link #KRB5_GET_SESSION_KEY_EX}
-     * which returns an instance of
-     * {@link javax.security.auth.kerberos.EncryptionKey}
-     * that implements the {@link javax.crypto.SecretKey} interface and
-     * has similar methods with {@link javax.security.auth.kerberos.KerberosKey}.
-     */
-    @Deprecated
-    KRB5_GET_SESSION_KEY,
-    /**
-     * Attribute type for retrieving the session key of an
-     * established Kerberos 5 security context. The return value is an
-     * instance of {@link javax.security.auth.kerberos.EncryptionKey}.
-     *
-     * @since 1.9
-     */
-    KRB5_GET_SESSION_KEY_EX,
-    /**
-     * Attribute type for retrieving the service ticket flags of an
-     * established Kerberos 5 security context. The returned object is
-     * a boolean array for the service ticket flags, which is long enough
-     * to contain all true bits. This means if the user wants to get the
-     * <em>n</em>'th bit but the length of the returned array is less than
-     * <em>n</em>, it is regarded as false.
-     */
-    KRB5_GET_TKT_FLAGS,
-    /**
-     * Attribute type for retrieving the authorization data in the
-     * service ticket of an established Kerberos 5 security context.
-     * Only supported on the acceptor side.
-     */
-    KRB5_GET_AUTHZ_DATA,
-    /**
-     * Attribute type for retrieving the authtime in the service ticket
-     * of an established Kerberos 5 security context. The returned object
-     * is a String object in the standard KerberosTime format defined in
-     * RFC 4120 Section 5.2.3.
-     */
-    KRB5_GET_AUTHTIME,
-    /**
-     * Attribute type for retrieving the KRB_CRED message that an initiator
-     * is about to send to an acceptor. The return type is an instance of
-     * {@link javax.security.auth.kerberos.KerberosCredMessage}.
-     *
-     * @since 1.9
-     */
-    KRB5_GET_KRB_CRED,
-}
--- a/jdk/src/java.security.jgss/share/classes/com/sun/security/jgss/package-info.java	Wed Jul 05 20:01:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-@jdk.Exported
-package com.sun.security.jgss;
--- a/jdk/src/java.security.jgss/share/classes/com/sun/security/sasl/gsskerb/FactoryImpl.java	Wed Jul 05 20:01:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.security.sasl.gsskerb;
-
-import javax.security.sasl.*;
-import com.sun.security.sasl.util.PolicyUtils;
-
-import java.util.Map;
-import javax.security.auth.callback.CallbackHandler;
-
-/**
-  * Client/server factory for GSSAPI (Kerberos V5) SASL client/server mechs.
-  * See GssKrb5Client/GssKrb5Server for input requirements.
-  *
-  * @author Rosanna Lee
-  */
-public final class FactoryImpl implements SaslClientFactory, SaslServerFactory {
-    private static final String myMechs[] = {
-        "GSSAPI"};
-
-    private static final int mechPolicies[] = {
-        PolicyUtils.NOPLAINTEXT|PolicyUtils.NOANONYMOUS|PolicyUtils.NOACTIVE
-    };
-
-    private static final int GSS_KERB_V5 = 0;
-
-    public FactoryImpl() {
-    }
-
-    public SaslClient createSaslClient(String[] mechs,
-        String authorizationId,
-        String protocol,
-        String serverName,
-        Map<String,?> props,
-        CallbackHandler cbh) throws SaslException {
-
-            for (int i = 0; i < mechs.length; i++) {
-                if (mechs[i].equals(myMechs[GSS_KERB_V5])
-                    && PolicyUtils.checkPolicy(mechPolicies[GSS_KERB_V5], props)) {
-                    return new GssKrb5Client(
-                        authorizationId,
-                        protocol,
-                        serverName,
-                        props,
-                        cbh);
-                }
-            }
-            return null;
-    };
-
-    public SaslServer createSaslServer(String mech,
-        String protocol,
-        String serverName,
-        Map<String,?> props,
-        CallbackHandler cbh) throws SaslException {
-            if (mech.equals(myMechs[GSS_KERB_V5])
-                && PolicyUtils.checkPolicy(mechPolicies[GSS_KERB_V5], props)) {
-                if (cbh == null) {
-                    throw new SaslException(
-                "Callback handler with support for AuthorizeCallback required");
-                }
-                return new GssKrb5Server(
-                    protocol,
-                    serverName,
-                    props,
-                    cbh);
-            }
-            return null;
-    };
-
-    public String[] getMechanismNames(Map<String,?> props) {
-        return PolicyUtils.filterMechs(myMechs, mechPolicies, props);
-    }
-}
--- a/jdk/src/java.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java	Wed Jul 05 20:01:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,164 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package com.sun.security.sasl.gsskerb;
-
-import java.util.Locale;
-import java.util.Map;
-import java.util.logging.Level;
-import javax.security.sasl.*;
-import com.sun.security.sasl.util.AbstractSaslImpl;
-import org.ietf.jgss.*;
-import com.sun.security.jgss.ExtendedGSSContext;
-import com.sun.security.jgss.InquireType;
-
-abstract class GssKrb5Base extends AbstractSaslImpl {
-
-    private static final String KRB5_OID_STR = "1.2.840.113554.1.2.2";
-    protected static Oid KRB5_OID;
-    protected static final byte[] EMPTY = new byte[0];
-
-    static {
-        try {
-            KRB5_OID = new Oid(KRB5_OID_STR);
-        } catch (GSSException ignore) {}
-    }
-
-    protected GSSContext secCtx = null;
-    protected static final int JGSS_QOP = 0;    // unrelated to SASL QOP mask
-
-    protected GssKrb5Base(Map<String, ?> props, String className)
-        throws SaslException {
-        super(props, className);
-    }
-
-    /**
-     * Retrieves this mechanism's name.
-     *
-     * @return  The string "GSSAPI".
-     */
-    public String getMechanismName() {
-        return "GSSAPI";
-    }
-
-    @Override
-    public Object getNegotiatedProperty(String propName) {
-        if (!completed) {
-            throw new IllegalStateException("Authentication incomplete");
-        }
-        String xprefix = "com.sun.security.jgss.inquiretype.";
-        if (propName.startsWith(xprefix)) {
-            String type = propName.substring(xprefix.length());
-            if (logger.isLoggable(Level.FINEST)) {
-                logger.logp(Level.FINE, "GssKrb5Base",
-                        "getNegotiatedProperty", propName);
-            }
-            for (InquireType t: InquireType.values()) {
-                if (t.name().toLowerCase(Locale.US).equals(type)) {
-                    try {
-                        return ((ExtendedGSSContext)secCtx).inquireSecContext(t);
-                    } catch (GSSException e) {
-                        if (logger.isLoggable(Level.FINEST)) {
-                            logger.log(Level.WARNING, "inquireSecContext error", e);
-                        }
-                        return null;
-                    }
-                }
-            }
-            // No such InquireType. Although not likely to be defined
-            // as a property in a parent class, still try it.
-        }
-        return super.getNegotiatedProperty(propName);
-    }
-
-    public byte[] unwrap(byte[] incoming, int start, int len)
-        throws SaslException {
-        if (!completed) {
-            throw new IllegalStateException("GSSAPI authentication not completed");
-        }
-
-        // integrity will be true if either privacy or integrity negotiated
-        if (!integrity) {
-            throw new IllegalStateException("No security layer negotiated");
-        }
-
-        try {
-            MessageProp msgProp = new MessageProp(JGSS_QOP, privacy);
-            byte[] answer = secCtx.unwrap(incoming, start, len, msgProp);
-            if (logger.isLoggable(Level.FINEST)) {
-                traceOutput(myClassName, "KRB501:Unwrap", "incoming: ",
-                    incoming, start, len);
-                traceOutput(myClassName, "KRB502:Unwrap", "unwrapped: ",
-                    answer, 0, answer.length);
-            }
-            return answer;
-        } catch (GSSException e) {
-            throw new SaslException("Problems unwrapping SASL buffer", e);
-        }
-    }
-
-    public byte[] wrap(byte[] outgoing, int start, int len) throws SaslException {
-        if (!completed) {
-            throw new IllegalStateException("GSSAPI authentication not completed");
-        }
-
-        // integrity will be true if either privacy or integrity negotiated
-        if (!integrity) {
-            throw new IllegalStateException("No security layer negotiated");
-        }
-
-        // Generate GSS token
-        try {
-            MessageProp msgProp = new MessageProp(JGSS_QOP, privacy);
-            byte[] answer = secCtx.wrap(outgoing, start, len, msgProp);
-            if (logger.isLoggable(Level.FINEST)) {
-                traceOutput(myClassName, "KRB503:Wrap", "outgoing: ",
-                    outgoing, start, len);
-                traceOutput(myClassName, "KRB504:Wrap", "wrapped: ",
-                    answer, 0, answer.length);
-            }
-            return answer;
-
-        } catch (GSSException e) {
-            throw new SaslException("Problem performing GSS wrap", e);
-        }
-    }
-
-    public void dispose() throws SaslException {
-        if (secCtx != null) {
-            try {
-                secCtx.dispose();
-            } catch (GSSException e) {
-                throw new SaslException("Problem disposing GSS context", e);
-            }
-            secCtx = null;
-        }
-    }
-
-    protected void finalize() throws Throwable {
-        dispose();
-    }
-}
--- a/jdk/src/java.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java	Wed Jul 05 20:01:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,329 +0,0 @@
-/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.security.sasl.gsskerb;
-
-import java.io.IOException;
-import java.util.Map;
-import java.util.logging.Level;
-import javax.security.sasl.*;
-
-// JAAS
-import javax.security.auth.callback.CallbackHandler;
-
-// JGSS
-import org.ietf.jgss.*;
-
-/**
-  * Implements the GSSAPI SASL client mechanism for Kerberos V5.
-  * (<A HREF="http://www.ietf.org/rfc/rfc2222.txt">RFC 2222</A>,
-  * <a HREF="http://www.ietf.org/internet-drafts/draft-ietf-cat-sasl-gssapi-04.txt">draft-ietf-cat-sasl-gssapi-04.txt</a>).
-  * It uses the Java Bindings for GSSAPI
-  * (<A HREF="http://www.ietf.org/rfc/rfc2853.txt">RFC 2853</A>)
-  * for getting GSSAPI/Kerberos V5 support.
-  *
-  * The client/server interactions are:
-  * C0: bind (GSSAPI, initial response)
-  * S0: sasl-bind-in-progress, challenge 1 (output of accept_sec_context or [])
-  * C1: bind (GSSAPI, response 1 (output of init_sec_context or []))
-  * S1: sasl-bind-in-progress challenge 2 (security layer, server max recv size)
-  * C2: bind (GSSAPI, response 2 (security layer, client max recv size, authzid))
-  * S2: bind success response
-  *
-  * Expects the client's credentials to be supplied from the
-  * javax.security.sasl.credentials property or from the thread's Subject.
-  * Otherwise the underlying KRB5 mech will attempt to acquire Kerberos creds
-  * by logging into Kerberos (via default TextCallbackHandler).
-  * These creds will be used for exchange with server.
-  *
-  * Required callbacks: none.
-  *
-  * Environment properties that affect behavior of implementation:
-  *
-  * javax.security.sasl.qop
-  * - quality of protection; list of auth, auth-int, auth-conf; default is "auth"
-  * javax.security.sasl.maxbuf
-  * - max receive buffer size; default is 65536
-  * javax.security.sasl.sendmaxbuffer
-  * - max send buffer size; default is 65536; (min with server max recv size)
-  *
-  * javax.security.sasl.server.authentication
-  * - "true" means require mutual authentication; default is "false"
-  *
-  * javax.security.sasl.credentials
-  * - an {@link org.ietf.jgss.GSSCredential} used for delegated authentication.
-  *
-  * @author Rosanna Lee
-  */
-
-final class GssKrb5Client extends GssKrb5Base implements SaslClient {
-    // ---------------- Constants -----------------
-    private static final String MY_CLASS_NAME = GssKrb5Client.class.getName();
-
-    private boolean finalHandshake = false;
-    private boolean mutual = false;       // default false
-    private byte[] authzID;
-
-    /**
-     * Creates a SASL mechanism with client credentials that it needs
-     * to participate in GSS-API/Kerberos v5 authentication exchange
-     * with the server.
-     */
-    GssKrb5Client(String authzID, String protocol, String serverName,
-        Map<String, ?> props, CallbackHandler cbh) throws SaslException {
-
-        super(props, MY_CLASS_NAME);
-
-        String service = protocol + "@" + serverName;
-        logger.log(Level.FINE, "KRB5CLNT01:Requesting service name: {0}",
-            service);
-
-        try {
-            GSSManager mgr = GSSManager.getInstance();
-
-            // Create the name for the requested service entity for Krb5 mech
-            GSSName acceptorName = mgr.createName(service,
-                GSSName.NT_HOSTBASED_SERVICE, KRB5_OID);
-
-            // Parse properties to check for supplied credentials
-            GSSCredential credentials = null;
-            if (props != null) {
-                Object prop = props.get(Sasl.CREDENTIALS);
-                if (prop != null && prop instanceof GSSCredential) {
-                    credentials = (GSSCredential) prop;
-                    logger.log(Level.FINE,
-                        "KRB5CLNT01:Using the credentials supplied in " +
-                        "javax.security.sasl.credentials");
-                }
-            }
-
-            // Create a context using credentials for Krb5 mech
-            secCtx = mgr.createContext(acceptorName,
-                KRB5_OID,   /* mechanism */
-                credentials, /* credentials */
-                GSSContext.INDEFINITE_LIFETIME);
-
-            // Request credential delegation when credentials have been supplied
-            if (credentials != null) {
-                secCtx.requestCredDeleg(true);
-            }
-
-            // Parse properties  to set desired context options
-            if (props != null) {
-                // Mutual authentication
-                String prop = (String)props.get(Sasl.SERVER_AUTH);
-                if (prop != null) {
-                    mutual = "true".equalsIgnoreCase(prop);
-                }
-            }
-            secCtx.requestMutualAuth(mutual);
-
-            // Always specify potential need for integrity and confidentiality
-            // Decision will be made during final handshake
-            secCtx.requestConf(true);
-            secCtx.requestInteg(true);
-
-        } catch (GSSException e) {
-            throw new SaslException("Failure to initialize security context", e);
-        }
-
-        if (authzID != null && authzID.length() > 0) {
-            try {
-                this.authzID = authzID.getBytes("UTF8");
-            } catch (IOException e) {
-                throw new SaslException("Cannot encode authorization ID", e);
-            }
-        }
-    }
-
-    public boolean hasInitialResponse() {
-        return true;
-    }
-
-    /**
-     * Processes the challenge data.
-     *
-     * The server sends a challenge data using which the client must
-     * process using GSS_Init_sec_context.
-     * As per RFC 2222, when GSS_S_COMPLETE is returned, we do
-     * an extra handshake to determine the negotiated security protection
-     * and buffer sizes.
-     *
-     * @param challengeData A non-null byte array containing the
-     * challenge data from the server.
-     * @return A non-null byte array containing the response to be
-     * sent to the server.
-     */
-    public byte[] evaluateChallenge(byte[] challengeData) throws SaslException {
-        if (completed) {
-            throw new IllegalStateException(
-                "GSSAPI authentication already complete");
-        }
-
-        if (finalHandshake) {
-            return doFinalHandshake(challengeData);
-        } else {
-
-            // Security context not established yet; continue with init
-
-            try {
-                byte[] gssOutToken = secCtx.initSecContext(challengeData,
-                    0, challengeData.length);
-                if (logger.isLoggable(Level.FINER)) {
-                    traceOutput(MY_CLASS_NAME, "evaluteChallenge",
-                        "KRB5CLNT02:Challenge: [raw]", challengeData);
-                    traceOutput(MY_CLASS_NAME, "evaluateChallenge",
-                        "KRB5CLNT03:Response: [after initSecCtx]", gssOutToken);
-                }
-
-                if (secCtx.isEstablished()) {
-                    finalHandshake = true;
-                    if (gssOutToken == null) {
-                        // RFC 2222 7.2.1:  Client responds with no data
-                        return EMPTY;
-                    }
-                }
-
-                return gssOutToken;
-            } catch (GSSException e) {
-                throw new SaslException("GSS initiate failed", e);
-            }
-        }
-    }
-
-    private byte[] doFinalHandshake(byte[] challengeData) throws SaslException {
-        try {
-            // Security context already established. challengeData
-            // should contain security layers and server's maximum buffer size
-
-            if (logger.isLoggable(Level.FINER)) {
-                traceOutput(MY_CLASS_NAME, "doFinalHandshake",
-                    "KRB5CLNT04:Challenge [raw]:", challengeData);
-            }
-
-            if (challengeData.length == 0) {
-                // Received S0, should return []
-                return EMPTY;
-            }
-
-            // Received S1 (security layer, server max recv size)
-
-            byte[] gssOutToken = secCtx.unwrap(challengeData, 0,
-                challengeData.length, new MessageProp(0, false));
-
-            // First octet is a bit-mask specifying the protections
-            // supported by the server
-            if (logger.isLoggable(Level.FINE)) {
-                if (logger.isLoggable(Level.FINER)) {
-                    traceOutput(MY_CLASS_NAME, "doFinalHandshake",
-                        "KRB5CLNT05:Challenge [unwrapped]:", gssOutToken);
-                }
-                logger.log(Level.FINE, "KRB5CLNT06:Server protections: {0}",
-                    gssOutToken[0]);
-            }
-
-            // Client selects preferred protection
-            // qop is ordered list of qop values
-            byte selectedQop = findPreferredMask(gssOutToken[0], qop);
-            if (selectedQop == 0) {
-                throw new SaslException(
-                    "No common protection layer between client and server");
-            }
-
-            if ((selectedQop&PRIVACY_PROTECTION) != 0) {
-                privacy = true;
-                integrity = true;
-            } else if ((selectedQop&INTEGRITY_ONLY_PROTECTION) != 0) {
-                integrity = true;
-            }
-
-            // 2nd-4th octets specifies maximum buffer size expected by
-            // server (in network byte order)
-            int srvMaxBufSize = networkByteOrderToInt(gssOutToken, 1, 3);
-
-            // Determine the max send buffer size based on what the
-            // server is able to receive and our specified max
-            sendMaxBufSize = (sendMaxBufSize == 0) ? srvMaxBufSize :
-                Math.min(sendMaxBufSize, srvMaxBufSize);
-
-            // Update context to limit size of returned buffer
-            rawSendSize = secCtx.getWrapSizeLimit(JGSS_QOP, privacy,
-                sendMaxBufSize);
-
-            if (logger.isLoggable(Level.FINE)) {
-                logger.log(Level.FINE,
-"KRB5CLNT07:Client max recv size: {0}; server max recv size: {1}; rawSendSize: {2}",
-                    new Object[] {recvMaxBufSize,
-                                  srvMaxBufSize,
-                                  rawSendSize});
-            }
-
-            // Construct negotiated security layers and client's max
-            // receive buffer size and authzID
-            int len = 4;
-            if (authzID != null) {
-                len += authzID.length;
-            }
-
-            byte[] gssInToken = new byte[len];
-            gssInToken[0] = selectedQop;
-
-            if (logger.isLoggable(Level.FINE)) {
-                logger.log(Level.FINE,
-            "KRB5CLNT08:Selected protection: {0}; privacy: {1}; integrity: {2}",
-                    new Object[]{selectedQop,
-                                 Boolean.valueOf(privacy),
-                                 Boolean.valueOf(integrity)});
-            }
-
-            intToNetworkByteOrder(recvMaxBufSize, gssInToken, 1, 3);
-            if (authzID != null) {
-                // copy authorization id
-                System.arraycopy(authzID, 0, gssInToken, 4, authzID.length);
-                logger.log(Level.FINE, "KRB5CLNT09:Authzid: {0}", authzID);
-            }
-
-            if (logger.isLoggable(Level.FINER)) {
-                traceOutput(MY_CLASS_NAME, "doFinalHandshake",
-                    "KRB5CLNT10:Response [raw]", gssInToken);
-            }
-
-            gssOutToken = secCtx.wrap(gssInToken,
-                0, gssInToken.length,
-                new MessageProp(0 /* qop */, false /* privacy */));
-
-            if (logger.isLoggable(Level.FINER)) {
-                traceOutput(MY_CLASS_NAME, "doFinalHandshake",
-                    "KRB5CLNT11:Response [after wrap]", gssOutToken);
-            }
-
-            completed = true;  // server authenticated
-
-            return gssOutToken;
-        } catch (GSSException e) {
-            throw new SaslException("Final handshake failed", e);
-        }
-    }
-}
--- a/jdk/src/java.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java	Wed Jul 05 20:01:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,365 +0,0 @@
-/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.security.sasl.gsskerb;
-
-import javax.security.sasl.*;
-import java.io.*;
-import java.util.Map;
-import java.util.logging.Level;
-
-// JAAS
-import javax.security.auth.callback.*;
-
-// JGSS
-import org.ietf.jgss.*;
-
-/**
-  * Implements the GSSAPI SASL server mechanism for Kerberos V5.
-  * (<A HREF="http://www.ietf.org/rfc/rfc2222.txt">RFC 2222</A>,
-  * <a HREF="http://www.ietf.org/internet-drafts/draft-ietf-cat-sasl-gssapi-00.txt">draft-ietf-cat-sasl-gssapi-00.txt</a>).
-  *
-  * Expects thread's Subject to contain server's Kerberos credentials
-  * - If not, underlying KRB5 mech will attempt to acquire Kerberos creds
-  *   by logging into Kerberos (via default TextCallbackHandler).
-  * - These creds will be used for exchange with client.
-  *
-  * Required callbacks:
-  * - AuthorizeCallback
-  *      handler must verify that authid/authzids are allowed and set
-  *      authorized ID to be the canonicalized authzid (if applicable).
-  *
-  * Environment properties that affect behavior of implementation:
-  *
-  * javax.security.sasl.qop
-  * - quality of protection; list of auth, auth-int, auth-conf; default is "auth"
-  * javax.security.sasl.maxbuf
-  * - max receive buffer size; default is 65536
-  * javax.security.sasl.sendmaxbuffer
-  * - max send buffer size; default is 65536; (min with client max recv size)
-  *
-  * @author Rosanna Lee
-  */
-final class GssKrb5Server extends GssKrb5Base implements SaslServer {
-    private static final String MY_CLASS_NAME = GssKrb5Server.class.getName();
-
-    private int handshakeStage = 0;
-    private String peer;
-    private String me;
-    private String authzid;
-    private CallbackHandler cbh;
-
-    // When serverName is null, the server will be unbound. We need to save and
-    // check the protocol name after the context is established. This value
-    // will be null if serverName is not null.
-    private final String protocolSaved;
-    /**
-     * Creates a SASL mechanism with server credentials that it needs
-     * to participate in GSS-API/Kerberos v5 authentication exchange
-     * with the client.
-     */
-    GssKrb5Server(String protocol, String serverName,
-        Map<String, ?> props, CallbackHandler cbh) throws SaslException {
-
-        super(props, MY_CLASS_NAME);
-
-        this.cbh = cbh;
-
-        String service;
-        if (serverName == null) {
-            protocolSaved = protocol;
-            service = null;
-        } else {
-            protocolSaved = null;
-            service = protocol + "@" + serverName;
-        }
-
-        logger.log(Level.FINE, "KRB5SRV01:Using service name: {0}", service);
-
-        try {
-            GSSManager mgr = GSSManager.getInstance();
-
-            // Create the name for the requested service entity for Krb5 mech
-            GSSName serviceName = service == null ? null:
-                    mgr.createName(service, GSSName.NT_HOSTBASED_SERVICE, KRB5_OID);
-
-            GSSCredential cred = mgr.createCredential(serviceName,
-                GSSCredential.INDEFINITE_LIFETIME,
-                KRB5_OID, GSSCredential.ACCEPT_ONLY);
-
-            // Create a context using the server's credentials
-            secCtx = mgr.createContext(cred);
-
-            if ((allQop&INTEGRITY_ONLY_PROTECTION) != 0) {
-                // Might need integrity
-                secCtx.requestInteg(true);
-            }
-
-            if ((allQop&PRIVACY_PROTECTION) != 0) {
-                // Might need privacy
-                secCtx.requestConf(true);
-            }
-        } catch (GSSException e) {
-            throw new SaslException("Failure to initialize security context", e);
-        }
-        logger.log(Level.FINE, "KRB5SRV02:Initialization complete");
-    }
-
-
-    /**
-     * Processes the response data.
-     *
-     * The client sends response data to which the server must
-     * process using GSS_accept_sec_context.
-     * As per RFC 2222, the GSS authenication completes (GSS_S_COMPLETE)
-     * we do an extra hand shake to determine the negotiated security protection
-     * and buffer sizes.
-     *
-     * @param responseData A non-null but possible empty byte array containing the
-     * response data from the client.
-     * @return A non-null byte array containing the challenge to be
-     * sent to the client, or null when no more data is to be sent.
-     */
-    public byte[] evaluateResponse(byte[] responseData) throws SaslException {
-        if (completed) {
-            throw new SaslException(
-                "SASL authentication already complete");
-        }
-
-        if (logger.isLoggable(Level.FINER)) {
-            traceOutput(MY_CLASS_NAME, "evaluateResponse",
-                "KRB5SRV03:Response [raw]:", responseData);
-        }
-
-        switch (handshakeStage) {
-        case 1:
-            return doHandshake1(responseData);
-
-        case 2:
-            return doHandshake2(responseData);
-
-        default:
-            // Security context not established yet; continue with accept
-
-            try {
-                byte[] gssOutToken = secCtx.acceptSecContext(responseData,
-                    0, responseData.length);
-
-                if (logger.isLoggable(Level.FINER)) {
-                    traceOutput(MY_CLASS_NAME, "evaluateResponse",
-                        "KRB5SRV04:Challenge: [after acceptSecCtx]", gssOutToken);
-                }
-
-                if (secCtx.isEstablished()) {
-                    handshakeStage = 1;
-
-                    peer = secCtx.getSrcName().toString();
-                    me = secCtx.getTargName().toString();
-
-                    logger.log(Level.FINE,
-                            "KRB5SRV05:Peer name is : {0}, my name is : {1}",
-                            new Object[]{peer, me});
-
-                    // me might take the form of proto@host or proto/host
-                    if (protocolSaved != null &&
-                            !protocolSaved.equalsIgnoreCase(me.split("[/@]")[0])) {
-                        throw new SaslException(
-                                "GSS context targ name protocol error: " + me);
-                    }
-
-                    if (gssOutToken == null) {
-                        return doHandshake1(EMPTY);
-                    }
-                }
-
-                return gssOutToken;
-            } catch (GSSException e) {
-                throw new SaslException("GSS initiate failed", e);
-            }
-        }
-    }
-
-    private byte[] doHandshake1(byte[] responseData) throws SaslException {
-        try {
-            // Security context already established. responseData
-            // should contain no data
-            if (responseData != null && responseData.length > 0) {
-                throw new SaslException(
-                    "Handshake expecting no response data from server");
-            }
-
-            // Construct 4 octets of data:
-            // First octet contains bitmask specifying protections supported
-            // 2nd-4th octets contains max receive buffer of server
-
-            byte[] gssInToken = new byte[4];
-            gssInToken[0] = allQop;
-            intToNetworkByteOrder(recvMaxBufSize, gssInToken, 1, 3);
-
-            if (logger.isLoggable(Level.FINE)) {
-                logger.log(Level.FINE,
-                    "KRB5SRV06:Supported protections: {0}; recv max buf size: {1}",
-                    new Object[]{allQop,
-                                 recvMaxBufSize});
-            }
-
-            handshakeStage = 2;  // progress to next stage
-
-            if (logger.isLoggable(Level.FINER)) {
-                traceOutput(MY_CLASS_NAME, "doHandshake1",
-                    "KRB5SRV07:Challenge [raw]", gssInToken);
-            }
-
-            byte[] gssOutToken = secCtx.wrap(gssInToken, 0, gssInToken.length,
-                new MessageProp(0 /* gop */, false /* privacy */));
-
-            if (logger.isLoggable(Level.FINER)) {
-                traceOutput(MY_CLASS_NAME, "doHandshake1",
-                    "KRB5SRV08:Challenge [after wrap]", gssOutToken);
-            }
-            return gssOutToken;
-
-        } catch (GSSException e) {
-            throw new SaslException("Problem wrapping handshake1", e);
-        }
-    }
-
-    private byte[] doHandshake2(byte[] responseData) throws SaslException {
-        try {
-            // Expecting 4 octets from client selected protection
-            // and client's receive buffer size
-            byte[] gssOutToken = secCtx.unwrap(responseData, 0,
-                responseData.length, new MessageProp(0, false));
-
-            if (logger.isLoggable(Level.FINER)) {
-                traceOutput(MY_CLASS_NAME, "doHandshake2",
-                    "KRB5SRV09:Response [after unwrap]", gssOutToken);
-            }
-
-            // First octet is a bit-mask specifying the selected protection
-            byte selectedQop = gssOutToken[0];
-            if ((selectedQop&allQop) == 0) {
-                throw new SaslException("Client selected unsupported protection: "
-                    + selectedQop);
-            }
-            if ((selectedQop&PRIVACY_PROTECTION) != 0) {
-                privacy = true;
-                integrity = true;
-            } else if ((selectedQop&INTEGRITY_ONLY_PROTECTION) != 0) {
-                integrity = true;
-            }
-
-            // 2nd-4th octets specifies maximum buffer size expected by
-            // client (in network byte order). This is the server's send
-            // buffer maximum.
-            int clntMaxBufSize = networkByteOrderToInt(gssOutToken, 1, 3);
-
-            // Determine the max send buffer size based on what the
-            // client is able to receive and our specified max
-            sendMaxBufSize = (sendMaxBufSize == 0) ? clntMaxBufSize :
-                Math.min(sendMaxBufSize, clntMaxBufSize);
-
-            // Update context to limit size of returned buffer
-            rawSendSize = secCtx.getWrapSizeLimit(JGSS_QOP, privacy,
-                sendMaxBufSize);
-
-            if (logger.isLoggable(Level.FINE)) {
-                logger.log(Level.FINE,
-            "KRB5SRV10:Selected protection: {0}; privacy: {1}; integrity: {2}",
-                    new Object[]{selectedQop,
-                                 Boolean.valueOf(privacy),
-                                 Boolean.valueOf(integrity)});
-                logger.log(Level.FINE,
-"KRB5SRV11:Client max recv size: {0}; server max send size: {1}; rawSendSize: {2}",
-                    new Object[] {clntMaxBufSize,
-                                  sendMaxBufSize,
-                                  rawSendSize});
-            }
-
-            // Get authorization identity, if any
-            if (gssOutToken.length > 4) {
-                try {
-                    authzid = new String(gssOutToken, 4,
-                        gssOutToken.length - 4, "UTF-8");
-                } catch (UnsupportedEncodingException uee) {
-                    throw new SaslException ("Cannot decode authzid", uee);
-                }
-            } else {
-                authzid = peer;
-            }
-            logger.log(Level.FINE, "KRB5SRV12:Authzid: {0}", authzid);
-
-            AuthorizeCallback acb = new AuthorizeCallback(peer, authzid);
-
-            // In Kerberos, realm is embedded in peer name
-            cbh.handle(new Callback[] {acb});
-            if (acb.isAuthorized()) {
-                authzid = acb.getAuthorizedID();
-                completed = true;
-            } else {
-                // Authorization failed
-                throw new SaslException(peer +
-                    " is not authorized to connect as " + authzid);
-            }
-
-            return null;
-        } catch (GSSException e) {
-            throw new SaslException("Final handshake step failed", e);
-        } catch (IOException e) {
-            throw new SaslException("Problem with callback handler", e);
-        } catch (UnsupportedCallbackException e) {
-            throw new SaslException("Problem with callback handler", e);
-        }
-    }
-
-    public String getAuthorizationID() {
-        if (completed) {
-            return authzid;
-        } else {
-            throw new IllegalStateException("Authentication incomplete");
-        }
-    }
-
-    public Object getNegotiatedProperty(String propName) {
-        if (!completed) {
-            throw new IllegalStateException("Authentication incomplete");
-        }
-
-        Object result;
-        switch (propName) {
-            case Sasl.BOUND_SERVER_NAME:
-                try {
-                    // me might take the form of proto@host or proto/host
-                    result = me.split("[/@]")[1];
-                } catch (Exception e) {
-                    result = null;
-                }
-                break;
-            default:
-                result = super.getNegotiatedProperty(propName);
-        }
-        return result;
-    }
-}
--- a/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/GSSContext.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/GSSContext.java	Wed Jul 05 20:01:50 2017 +0200
@@ -25,7 +25,6 @@
 
 package org.ietf.jgss;
 
-import sun.security.jgss.spi.*;
 import java.io.InputStream;
 import java.io.OutputStream;
 
--- a/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/GSSName.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/GSSName.java	Wed Jul 05 20:01:50 2017 +0200
@@ -25,10 +25,6 @@
 
 package org.ietf.jgss;
 
-import sun.security.jgss.spi.*;
-import java.util.Vector;
-import java.util.Enumeration;
-
 /**
  * This interface encapsulates a single GSS-API principal entity. The
  * application obtains an implementation of this interface
--- a/jdk/src/java.security.jgss/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.security.jgss/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java	Wed Jul 05 20:01:50 2017 +0200
@@ -25,7 +25,6 @@
 
 package sun.net.www.protocol.http.spnego;
 
-import com.sun.security.jgss.ExtendedGSSContext;
 import java.io.IOException;
 
 import org.ietf.jgss.GSSContext;
@@ -36,6 +35,7 @@
 import sun.net.www.protocol.http.HttpCallerInfo;
 import sun.net.www.protocol.http.Negotiator;
 import sun.security.jgss.GSSManagerImpl;
+import sun.security.jgss.GSSContextImpl;
 import sun.security.jgss.GSSUtil;
 import sun.security.jgss.HttpCaller;
 
@@ -102,8 +102,8 @@
                                         GSSContext.DEFAULT_LIFETIME);
 
         // Always respect delegation policy in HTTP/SPNEGO.
-        if (context instanceof ExtendedGSSContext) {
-            ((ExtendedGSSContext)context).requestDelegPolicy(true);
+        if (context instanceof GSSContextImpl) {
+            ((GSSContextImpl)context).requestDelegPolicy(true);
         }
         oneToken = context.initSecContext(new byte[0], 0, 0);
     }
--- a/jdk/src/java.security.jgss/share/classes/sun/security/jgss/GSSContextImpl.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/GSSContextImpl.java	Wed Jul 05 20:01:50 2017 +0200
@@ -33,7 +33,8 @@
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import com.sun.security.jgss.*;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
 
 /**
  * This class represents the JGSS security context and its associated
@@ -87,10 +88,10 @@
  * per-message operations are returned in an instance of the MessageProp
  * class, which is used as an argument in these calls.</dl>
  */
-class GSSContextImpl implements ExtendedGSSContext {
+public class GSSContextImpl implements GSSContext {
 
-    private final GSSManagerImpl gssManager;
-    private final boolean initiator;
+    private GSSManagerImpl gssManager;
+    private boolean initiator;
 
     // private flags for the context state
     private static final int PRE_INIT = 1;
@@ -122,6 +123,22 @@
     private boolean reqAnonState = false;
     private boolean reqDelegPolicyState = false;
 
+    public GSSContextImpl() {
+        // Useless
+    }
+
+    // Used by new ExtendedGSSContext.ExtendedGSSContextImpl(ctxt)
+    protected GSSContextImpl(GSSContextImpl src) {
+        for (Field f: GSSContextImpl.class.getDeclaredFields()) {
+            if (!Modifier.isStatic(f.getModifiers())) {
+                try {
+                    f.set(this, f.get(src));
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+    }
     /**
      * Creates a GSSContextImp on the context initiator's side.
      */
@@ -613,7 +630,7 @@
                                    "No mechanism context yet!");
         GSSCredentialSpi delCredElement = mechCtxt.getDelegCred();
         return (delCredElement == null ?
-            null : new GSSCredentialImpl(gssManager, delCredElement));
+            null : GSSManagerImpl.wrap(new GSSCredentialImpl(gssManager, delCredElement)));
     }
 
     public boolean isInitiator() throws GSSException {
@@ -633,25 +650,18 @@
 
     // ExtendedGSSContext methods:
 
-    @Override
-    public Object inquireSecContext(InquireType type) throws GSSException {
-        SecurityManager security = System.getSecurityManager();
-        if (security != null) {
-            security.checkPermission(new InquireSecContextPermission(type.toString()));
-        }
+    public Object inquireSecContext(String type) throws GSSException {
         if (mechCtxt == null) {
             throw new GSSException(GSSException.NO_CONTEXT);
         }
         return mechCtxt.inquireSecContext(type);
     }
 
-    @Override
     public void requestDelegPolicy(boolean state) throws GSSException {
         if (mechCtxt == null && initiator)
             reqDelegPolicyState = state;
     }
 
-    @Override
     public boolean getDelegPolicyState() {
         if (mechCtxt != null)
             return mechCtxt.getDelegPolicyState();
--- a/jdk/src/java.security.jgss/share/classes/sun/security/jgss/GSSCredentialImpl.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/GSSCredentialImpl.java	Wed Jul 05 20:01:50 2017 +0200
@@ -27,11 +27,11 @@
 
 import org.ietf.jgss.*;
 import sun.security.jgss.spi.*;
+
 import java.util.*;
-import com.sun.security.jgss.*;
 import sun.security.jgss.spnego.SpNegoCredElement;
 
-public class GSSCredentialImpl implements ExtendedGSSCredential {
+public class GSSCredentialImpl implements GSSCredential {
 
     private GSSManagerImpl gssManager = null;
     private boolean destroyed = false;
@@ -47,6 +47,18 @@
     // XXX Optimization for single mech usage
     private GSSCredentialSpi tempCred = null;
 
+    public GSSCredentialImpl() {
+        // Useless
+    }
+
+    // Used by new ExtendedGSSCredential.ExtendedGSSCredentialImpl(cred)
+    protected GSSCredentialImpl(GSSCredentialImpl src) {
+        this.gssManager = src.gssManager;
+        this.destroyed = src.destroyed;
+        this.hashtable = src.hashtable;
+        this.tempCred = src.tempCred;
+    }
+
     GSSCredentialImpl(GSSManagerImpl gssManager, int usage)
         throws GSSException {
         this(gssManager, null, GSSCredential.DEFAULT_LIFETIME,
@@ -140,7 +152,7 @@
                                   ((GSSNameImpl)name).getElement(mech));
         GSSCredentialSpi cred = tempCred.impersonate(nameElement);
         return (cred == null ?
-            null : new GSSCredentialImpl(gssManager, cred));
+            null : GSSManagerImpl.wrap(new GSSCredentialImpl(gssManager, cred)));
     }
 
     public GSSName getName() throws GSSException {
--- a/jdk/src/java.security.jgss/share/classes/sun/security/jgss/GSSManagerImpl.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/GSSManagerImpl.java	Wed Jul 05 20:01:50 2017 +0200
@@ -145,35 +145,35 @@
 
     public GSSCredential createCredential(int usage)
         throws GSSException {
-        return new GSSCredentialImpl(this, usage);
+        return wrap(new GSSCredentialImpl(this, usage));
     }
 
     public GSSCredential createCredential(GSSName aName,
                                           int lifetime, Oid mech, int usage)
         throws GSSException {
-        return new GSSCredentialImpl(this, aName, lifetime, mech, usage);
+        return wrap(new GSSCredentialImpl(this, aName, lifetime, mech, usage));
     }
 
     public GSSCredential createCredential(GSSName aName,
                                           int lifetime, Oid mechs[], int usage)
         throws GSSException {
-        return new GSSCredentialImpl(this, aName, lifetime, mechs, usage);
+        return wrap(new GSSCredentialImpl(this, aName, lifetime, mechs, usage));
     }
 
     public GSSContext createContext(GSSName peer, Oid mech,
                                     GSSCredential myCred, int lifetime)
         throws GSSException {
-        return new GSSContextImpl(this, peer, mech, myCred, lifetime);
+        return wrap(new GSSContextImpl(this, peer, mech, myCred, lifetime));
     }
 
     public GSSContext createContext(GSSCredential myCred)
         throws GSSException {
-        return new GSSContextImpl(this, myCred);
+        return wrap(new GSSContextImpl(this, myCred));
     }
 
     public GSSContext createContext(byte[] interProcessToken)
         throws GSSException {
-        return new GSSContextImpl(this, interProcessToken);
+        return wrap(new GSSContextImpl(this, interProcessToken));
     }
 
     public void addProviderAtFront(Provider p, Oid mech)
@@ -257,4 +257,20 @@
         }
         return result;
     }
+
+    static {
+        // Load the extended JGSS interfaces if exist
+        try {
+            Class.forName("com.sun.security.jgss.Extender");
+        } catch (Exception e) {
+        }
+    }
+
+    static GSSCredential wrap(GSSCredentialImpl cred) {
+        return sun.security.jgss.JgssExtender.getExtender().wrap(cred);
+    }
+
+    static GSSContext wrap(GSSContextImpl ctxt) {
+        return sun.security.jgss.JgssExtender.getExtender().wrap(ctxt);
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/JgssExtender.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.jgss;
+
+import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSCredential;
+
+/**
+ * The extending point of basic JGSS-API.
+ * <p>
+ * If a module wants to extend basic JGSS-API classes, it should extends this
+ * class and register itself as "the extender" using the setExtender method.
+ * When various GSSManager.createXXX methods are called, they will call
+ * "the extender"'s wrap methods to create objects of extended types
+ * instead of basic types.
+ * <p>
+ * We have only one extension now defined in com.sun.security.jgss, and the
+ * registering process is triggered in {@link GSSManagerImpl} by calling
+ * Class.forName("com.sun.security.jgss.Extender"). Only GSSContext
+ * and GSSCredential are extended now.
+ * <p>
+ * The setExtender method should be called before any JGSS call.
+ */
+public class JgssExtender {
+
+    // "The extender"
+    private static volatile JgssExtender theOne = new JgssExtender();
+
+    /**
+     * Gets "the extender". GSSManager calls this method so that it can
+     * wrap basic objects into extended objects.
+     * @return the extender
+     */
+    public static JgssExtender getExtender() {
+        return theOne;
+    }
+
+    /**
+     * Set "the extender" so that GSSManager can create extended objects.
+     */
+    protected static void setExtender(JgssExtender theOne) {
+        JgssExtender.theOne = theOne;
+    }
+
+    /**
+     * Wraps a plain GSSCredential object into an extended type.
+     */
+    public GSSCredential wrap(GSSCredential cred) {
+        return cred;
+    }
+
+    /**
+     * Wraps a plain GSSContext object into an extended type.
+     */
+    public GSSContext wrap(GSSContext ctxt) {
+        return ctxt;
+    }
+}
--- a/jdk/src/java.security.jgss/share/classes/sun/security/jgss/krb5/InitSecContextToken.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/krb5/InitSecContextToken.java	Wed Jul 05 20:01:50 2017 +0200
@@ -25,7 +25,6 @@
 
 package sun.security.jgss.krb5;
 
-import com.sun.security.jgss.AuthorizationDataEntry;
 import org.ietf.jgss.*;
 import java.io.InputStream;
 import java.io.IOException;
@@ -152,17 +151,7 @@
                 new KerberosTime(apReq.getCreds().getAuthTime()).toString());
         context.setTktFlags(apReq.getCreds().getFlags());
         AuthorizationData ad = apReq.getCreds().getAuthzData();
-        if (ad == null) {
-            context.setAuthzData(null);
-        } else {
-            AuthorizationDataEntry[] authzData =
-                    new AuthorizationDataEntry[ad.count()];
-            for (int i=0; i<ad.count(); i++) {
-                authzData[i] = new AuthorizationDataEntry(
-                        ad.item(i).adType, ad.item(i).adData);
-            }
-            context.setAuthzData(authzData);
-        }
+        context.setAuthzData(ad);
     }
 
     public final KrbApReq getKrbApReq() {
--- a/jdk/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Context.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Context.java	Wed Jul 05 20:01:50 2017 +0200
@@ -25,7 +25,6 @@
 
 package sun.security.jgss.krb5;
 
-import com.sun.security.jgss.InquireType;
 import org.ietf.jgss.*;
 import sun.misc.HexDumpEncoder;
 import sun.security.jgss.GSSUtil;
@@ -48,6 +47,7 @@
 import javax.security.auth.kerberos.KerberosPrincipal;
 import javax.security.auth.kerberos.KerberosTicket;
 import sun.security.krb5.internal.Ticket;
+import sun.security.krb5.internal.AuthorizationData;
 
 /**
  * Implements the mechanism specific context class for the Kerberos v5
@@ -1419,30 +1419,30 @@
     /**
      * Return the mechanism-specific attribute associated with {@code type}.
      */
-    public Object inquireSecContext(InquireType type)
+    public Object inquireSecContext(String type)
             throws GSSException {
         if (!isEstablished()) {
              throw new GSSException(GSSException.NO_CONTEXT, -1,
                      "Security context not established.");
         }
         switch (type) {
-            case KRB5_GET_SESSION_KEY:
+            case "KRB5_GET_SESSION_KEY":
                 return new KerberosSessionKey(key);
-            case KRB5_GET_SESSION_KEY_EX:
+            case "KRB5_GET_SESSION_KEY_EX":
                 return new javax.security.auth.kerberos.EncryptionKey(
                         key.getBytes(), key.getEType());
-            case KRB5_GET_TKT_FLAGS:
+            case "KRB5_GET_TKT_FLAGS":
                 return tktFlags.clone();
-            case KRB5_GET_AUTHZ_DATA:
+            case "KRB5_GET_AUTHZ_DATA":
                 if (isInitiator()) {
                     throw new GSSException(GSSException.UNAVAILABLE, -1,
                             "AuthzData not available on initiator side.");
                 } else {
-                    return (authzData==null)?null:authzData.clone();
+                    return authzData;
                 }
-            case KRB5_GET_AUTHTIME:
+            case "KRB5_GET_AUTHTIME":
                 return authTime;
-            case KRB5_GET_KRB_CRED:
+            case "KRB5_GET_KRB_CRED":
                 if (!isInitiator()) {
                     throw new GSSException(GSSException.UNAVAILABLE, -1,
                             "KRB_CRED not available on acceptor side.");
@@ -1470,7 +1470,7 @@
     // Helpers for inquireSecContext
     private boolean[] tktFlags;
     private String authTime;
-    private com.sun.security.jgss.AuthorizationDataEntry[] authzData;
+    private AuthorizationData authzData;
 
     public void setTktFlags(boolean[] tktFlags) {
         this.tktFlags = tktFlags;
@@ -1480,7 +1480,7 @@
         this.authTime = authTime;
     }
 
-    public void setAuthzData(com.sun.security.jgss.AuthorizationDataEntry[] authzData) {
+    public void setAuthzData(AuthorizationData authzData) {
         this.authzData = authzData;
     }
 
--- a/jdk/src/java.security.jgss/share/classes/sun/security/jgss/spi/GSSContextSpi.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/spi/GSSContextSpi.java	Wed Jul 05 20:01:50 2017 +0200
@@ -34,7 +34,6 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.security.Provider;
-import com.sun.security.jgss.*;
 
 /**
  * This interface is implemented by a mechanism specific instance of a GSS
@@ -403,6 +402,6 @@
      * @throws GSSException see {@link ExtendedGSSContext#inquireSecContext}
      * for details
      */
-    public Object inquireSecContext(InquireType type)
+    public Object inquireSecContext(String type)
             throws GSSException;
 }
--- a/jdk/src/java.security.jgss/share/classes/sun/security/jgss/spnego/SpNegoContext.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/spnego/SpNegoContext.java	Wed Jul 05 20:01:50 2017 +0200
@@ -25,8 +25,6 @@
 
 package sun.security.jgss.spnego;
 
-import com.sun.security.jgss.ExtendedGSSContext;
-import com.sun.security.jgss.InquireType;
 import java.io.*;
 import java.security.Provider;
 import org.ietf.jgss.*;
@@ -174,9 +172,9 @@
      */
     public final boolean getDelegPolicyState() {
         if (isInitiator() && mechContext != null &&
-                mechContext instanceof ExtendedGSSContext &&
+                mechContext instanceof GSSContextImpl &&
                 (state == STATE_IN_PROCESS || state == STATE_DONE)) {
-            return ((ExtendedGSSContext)mechContext).getDelegPolicyState();
+            return ((GSSContextImpl)mechContext).getDelegPolicyState();
         } else {
             return delegPolicyState;
         }
@@ -850,7 +848,7 @@
                     myCred.getInternalCred());
             }
             mechContext =
-                factory.manager.createContext(serverName,
+                    factory.manager.createContext(serverName,
                     internal_mech, cred, GSSContext.DEFAULT_LIFETIME);
             mechContext.requestConf(confState);
             mechContext.requestInteg(integState);
@@ -858,8 +856,8 @@
             mechContext.requestMutualAuth(mutualAuthState);
             mechContext.requestReplayDet(replayDetState);
             mechContext.requestSequenceDet(sequenceDetState);
-            if (mechContext instanceof ExtendedGSSContext) {
-                ((ExtendedGSSContext)mechContext).requestDelegPolicy(
+            if (mechContext instanceof GSSContextImpl) {
+                ((GSSContextImpl)mechContext).requestDelegPolicy(
                         delegPolicyState);
             }
         }
@@ -890,8 +888,7 @@
                 cred = new GSSCredentialImpl(factory.manager,
                 myCred.getInternalCred());
             }
-            mechContext =
-                factory.manager.createContext(cred);
+            mechContext = factory.manager.createContext(cred);
         }
 
         // pass token to mechanism acceptSecContext
@@ -1217,14 +1214,14 @@
     /**
      * Retrieve attribute of the context for {@code type}.
      */
-    public Object inquireSecContext(InquireType type)
+    public Object inquireSecContext(String type)
             throws GSSException {
         if (mechContext == null) {
             throw new GSSException(GSSException.NO_CONTEXT, -1,
                     "Underlying mech not established.");
         }
-        if (mechContext instanceof ExtendedGSSContext) {
-            return ((ExtendedGSSContext)mechContext).inquireSecContext(type);
+        if (mechContext instanceof GSSContextImpl) {
+            return ((GSSContextImpl)mechContext).inquireSecContext(type);
         } else {
             throw new GSSException(GSSException.BAD_MECH, -1,
                     "inquireSecContext not supported by underlying mech.");
--- a/jdk/src/java.security.jgss/share/classes/sun/security/jgss/spnego/SpNegoCredElement.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/spnego/SpNegoCredElement.java	Wed Jul 05 20:01:50 2017 +0200
@@ -27,8 +27,6 @@
 import org.ietf.jgss.*;
 import java.security.Provider;
 import sun.security.jgss.GSSUtil;
-import sun.security.jgss.ProviderList;
-import sun.security.jgss.GSSCredentialImpl;
 import sun.security.jgss.spi.GSSNameSpi;
 import sun.security.jgss.spi.GSSCredentialSpi;
 
--- a/jdk/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java	Wed Jul 05 20:01:50 2017 +0200
@@ -36,7 +36,6 @@
 import sun.security.jgss.spnego.NegTokenInit;
 import sun.security.jgss.spnego.NegTokenTarg;
 import javax.security.auth.kerberos.DelegationPermission;
-import com.sun.security.jgss.InquireType;
 import java.io.*;
 
 
@@ -623,7 +622,7 @@
         dispose();
     }
 
-    public Object inquireSecContext(InquireType type)
+    public Object inquireSecContext(String type)
             throws GSSException {
         throw new GSSException(GSSException.UNAVAILABLE, -1,
                 "Inquire type not supported.");
--- a/jdk/src/java.sql/share/classes/java/sql/Date.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.sql/share/classes/java/sql/Date.java	Wed Jul 05 20:01:50 2017 +0200
@@ -27,6 +27,8 @@
 
 import java.time.Instant;
 import java.time.LocalDate;
+import sun.misc.SharedSecrets;
+import sun.misc.JavaLangAccess;
 
 /**
  * <P>A thin wrapper around a millisecond value that allows
@@ -42,6 +44,8 @@
  */
 public class Date extends java.util.Date {
 
+    private static final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
+
     /**
      * Constructs a <code>Date</code> object initialized with the given
      * year, month, and day.
@@ -108,31 +112,27 @@
      *         JDBC date escape format (yyyy-[m]m-[d]d)
      */
     public static Date valueOf(String s) {
+        if (s == null) {
+            throw new java.lang.IllegalArgumentException();
+        }
         final int YEAR_LENGTH = 4;
         final int MONTH_LENGTH = 2;
         final int DAY_LENGTH = 2;
         final int MAX_MONTH = 12;
         final int MAX_DAY = 31;
-        int firstDash;
-        int secondDash;
         Date d = null;
-        if (s == null) {
-            throw new java.lang.IllegalArgumentException();
-        }
 
-        firstDash = s.indexOf('-');
-        secondDash = s.indexOf('-', firstDash + 1);
+        int firstDash = s.indexOf('-');
+        int secondDash = s.indexOf('-', firstDash + 1);
+        int len = s.length();
 
-        if ((firstDash > 0) && (secondDash > 0) && (secondDash < s.length() - 1)) {
-            String yyyy = s.substring(0, firstDash);
-            String mm = s.substring(firstDash + 1, secondDash);
-            String dd = s.substring(secondDash + 1);
-            if (yyyy.length() == YEAR_LENGTH &&
-                    (mm.length() >= 1 && mm.length() <= MONTH_LENGTH) &&
-                    (dd.length() >= 1 && dd.length() <= DAY_LENGTH)) {
-                int year = Integer.parseInt(yyyy);
-                int month = Integer.parseInt(mm);
-                int day = Integer.parseInt(dd);
+        if ((firstDash > 0) && (secondDash > 0) && (secondDash < len - 1)) {
+            if (firstDash == YEAR_LENGTH &&
+                    (secondDash - firstDash > 1 && secondDash - firstDash <= MONTH_LENGTH + 1) &&
+                    (len - secondDash > 1 && len - secondDash <= DAY_LENGTH + 1)) {
+                int year = Integer.parseInt(s, 0, firstDash, 10);
+                int month = Integer.parseInt(s, firstDash + 1, secondDash, 10);
+                int day = Integer.parseInt(s, secondDash + 1, len, 10);
 
                 if ((month >= 1 && month <= MAX_MONTH) && (day >= 1 && day <= MAX_DAY)) {
                     d = new Date(year - 1900, month - 1, day);
@@ -159,17 +159,34 @@
         int month = super.getMonth() + 1;
         int day = super.getDate();
 
-        char buf[] = "2000-00-00".toCharArray();
-        buf[0] = Character.forDigit(year/1000,10);
-        buf[1] = Character.forDigit((year/100)%10,10);
-        buf[2] = Character.forDigit((year/10)%10,10);
-        buf[3] = Character.forDigit(year%10,10);
-        buf[5] = Character.forDigit(month/10,10);
-        buf[6] = Character.forDigit(month%10,10);
-        buf[8] = Character.forDigit(day/10,10);
-        buf[9] = Character.forDigit(day%10,10);
+        char buf[] = new char[10];
+        formatDecimalInt(year, buf, 0, 4);
+        buf[4] = '-';
+        Date.formatDecimalInt(month, buf, 5, 2);
+        buf[7] = '-';
+        Date.formatDecimalInt(day, buf, 8, 2);
+
+        return jla.newStringUnsafe(buf);
+    }
 
-        return new String(buf);
+    /**
+     * Formats an unsigned integer into a char array in decimal output format.
+     * Numbers will be zero-padded or truncated if the string representation
+     * of the integer is smaller than or exceeds len, respectively.
+     *
+     * Should consider moving this to Integer and expose it through
+     * JavaLangAccess similar to Integer::formatUnsignedInt
+     * @param val  Value to convert
+     * @param buf  Array containing converted value
+     * @param offset Starting pos in buf
+     * @param len  length of output value
+     */
+    static void formatDecimalInt(int val, char[] buf, int offset, int len) {
+        int charPos = offset + len;
+        do {
+            buf[--charPos] = (char)('0' + (val % 10));
+            val /= 10;
+        } while (charPos > offset);
     }
 
     // Override all the time operations inherited from java.util.Date;
--- a/jdk/src/java.sql/share/classes/java/sql/Time.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.sql/share/classes/java/sql/Time.java	Wed Jul 05 20:01:50 2017 +0200
@@ -27,6 +27,8 @@
 
 import java.time.Instant;
 import java.time.LocalTime;
+import sun.misc.SharedSecrets;
+import sun.misc.JavaLangAccess;
 
 /**
  * <P>A thin wrapper around the <code>java.util.Date</code> class that allows the JDBC
@@ -39,6 +41,8 @@
  */
 public class Time extends java.util.Date {
 
+    private static final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
+
     /**
      * Constructs a <code>Time</code> object initialized with the
      * given values for the hour, minute, and second.
@@ -90,22 +94,19 @@
      * @return a corresponding <code>Time</code> object
      */
     public static Time valueOf(String s) {
+        if (s == null) throw new java.lang.IllegalArgumentException();
+
         int hour;
         int minute;
         int second;
-        int firstColon;
-        int secondColon;
-
-        if (s == null) throw new java.lang.IllegalArgumentException();
-
-        firstColon = s.indexOf(':');
-        secondColon = s.indexOf(':', firstColon+1);
-        if ((firstColon > 0) & (secondColon > 0) &
-            (secondColon < s.length()-1)) {
-            hour = Integer.parseInt(s.substring(0, firstColon));
-            minute =
-                Integer.parseInt(s.substring(firstColon+1, secondColon));
-            second = Integer.parseInt(s.substring(secondColon+1));
+        int firstColon = s.indexOf(':');
+        int secondColon = s.indexOf(':', firstColon + 1);
+        int len = s.length();
+        if (firstColon > 0 && secondColon > 0 &&
+                secondColon < len - 1) {
+            hour = Integer.parseInt(s, 0, firstColon, 10);
+            minute = Integer.parseInt(s, firstColon + 1, secondColon, 10);
+            second = Integer.parseInt(s, secondColon + 1, len, 10);
         } else {
             throw new java.lang.IllegalArgumentException();
         }
@@ -123,26 +124,15 @@
         int hour = super.getHours();
         int minute = super.getMinutes();
         int second = super.getSeconds();
-        String hourString;
-        String minuteString;
-        String secondString;
 
-        if (hour < 10) {
-            hourString = "0" + hour;
-        } else {
-            hourString = Integer.toString(hour);
-        }
-        if (minute < 10) {
-            minuteString = "0" + minute;
-        } else {
-            minuteString = Integer.toString(minute);
-        }
-        if (second < 10) {
-            secondString = "0" + second;
-        } else {
-            secondString = Integer.toString(second);
-        }
-        return (hourString + ":" + minuteString + ":" + secondString);
+        char[] buf = new char[8];
+        Date.formatDecimalInt(hour, buf, 0, 2);
+        buf[2] = ':';
+        Date.formatDecimalInt(minute, buf, 3, 2);
+        buf[5] = ':';
+        Date.formatDecimalInt(second, buf, 6, 2);
+
+        return jla.newStringUnsafe(buf);
     }
 
     // Override all the date operations inherited from java.util.Date;
--- a/jdk/src/java.sql/share/classes/java/sql/Timestamp.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/java.sql/share/classes/java/sql/Timestamp.java	Wed Jul 05 20:01:50 2017 +0200
@@ -27,7 +27,8 @@
 
 import java.time.Instant;
 import java.time.LocalDateTime;
-import java.util.StringTokenizer;
+import sun.misc.SharedSecrets;
+import sun.misc.JavaLangAccess;
 
 /**
  * <P>A thin wrapper around <code>java.util.Date</code> that allows
@@ -71,6 +72,8 @@
  */
 public class Timestamp extends java.util.Date {
 
+    private static final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
+
     /**
      * Constructs a <code>Timestamp</code> object initialized
      * with the given values.
@@ -171,9 +174,6 @@
         final int DAY_LENGTH = 2;
         final int MAX_MONTH = 12;
         final int MAX_DAY = 31;
-        String date_s;
-        String time_s;
-        String nanos_s;
         int year = 0;
         int month = 0;
         int day = 0;
@@ -184,49 +184,38 @@
         int firstDash;
         int secondDash;
         int dividingSpace;
-        int firstColon = 0;
-        int secondColon = 0;
-        int period = 0;
+        int firstColon;
+        int secondColon;
+        int period;
         String formatError = "Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]";
-        String zeros = "000000000";
-        String delimiterDate = "-";
-        String delimiterTime = ":";
 
         if (s == null) throw new java.lang.IllegalArgumentException("null string");
 
         // Split the string into date and time components
         s = s.trim();
         dividingSpace = s.indexOf(' ');
-        if (dividingSpace > 0) {
-            date_s = s.substring(0,dividingSpace);
-            time_s = s.substring(dividingSpace+1);
-        } else {
+        if (dividingSpace < 0) {
             throw new java.lang.IllegalArgumentException(formatError);
         }
 
         // Parse the date
-        firstDash = date_s.indexOf('-');
-        secondDash = date_s.indexOf('-', firstDash+1);
+        firstDash = s.indexOf('-');
+        secondDash = s.indexOf('-', firstDash+1);
 
         // Parse the time
-        if (time_s == null)
-            throw new java.lang.IllegalArgumentException(formatError);
-        firstColon = time_s.indexOf(':');
-        secondColon = time_s.indexOf(':', firstColon+1);
-        period = time_s.indexOf('.', secondColon+1);
+        firstColon = s.indexOf(':', dividingSpace + 1);
+        secondColon = s.indexOf(':', firstColon + 1);
+        period = s.indexOf('.', secondColon + 1);
 
         // Convert the date
         boolean parsedDate = false;
-        if ((firstDash > 0) && (secondDash > 0) && (secondDash < date_s.length() - 1)) {
-            String yyyy = date_s.substring(0, firstDash);
-            String mm = date_s.substring(firstDash + 1, secondDash);
-            String dd = date_s.substring(secondDash + 1);
-            if (yyyy.length() == YEAR_LENGTH &&
-                    (mm.length() >= 1 && mm.length() <= MONTH_LENGTH) &&
-                    (dd.length() >= 1 && dd.length() <= DAY_LENGTH)) {
-                 year = Integer.parseInt(yyyy);
-                 month = Integer.parseInt(mm);
-                 day = Integer.parseInt(dd);
+        if (firstDash > 0 && secondDash > 0 && secondDash < dividingSpace - 1) {
+            if (firstDash == YEAR_LENGTH &&
+                    (secondDash - firstDash > 1 && secondDash - firstDash <= MONTH_LENGTH + 1) &&
+                    (dividingSpace - secondDash > 1 && dividingSpace - secondDash <= DAY_LENGTH + 1)) {
+                 year = Integer.parseInt(s, 0, firstDash, 10);
+                 month = Integer.parseInt(s, firstDash + 1, secondDash, 10);
+                 day = Integer.parseInt(s, secondDash + 1, dividingSpace, 10);
 
                 if ((month >= 1 && month <= MAX_MONTH) && (day >= 1 && day <= MAX_DAY)) {
                     parsedDate = true;
@@ -238,25 +227,27 @@
         }
 
         // Convert the time; default missing nanos
-        if ((firstColon > 0) & (secondColon > 0) &
-            (secondColon < time_s.length()-1)) {
-            hour = Integer.parseInt(time_s.substring(0, firstColon));
-            minute =
-                Integer.parseInt(time_s.substring(firstColon+1, secondColon));
-            if ((period > 0) & (period < time_s.length()-1)) {
-                second =
-                    Integer.parseInt(time_s.substring(secondColon+1, period));
-                nanos_s = time_s.substring(period+1);
-                if (nanos_s.length() > 9)
+        int len = s.length();
+        if (firstColon > 0 && secondColon > 0 && secondColon < len - 1) {
+            hour = Integer.parseInt(s, dividingSpace + 1, firstColon, 10);
+            minute = Integer.parseInt(s, firstColon + 1, secondColon, 10);
+            if (period > 0 && period < len - 1) {
+                second = Integer.parseInt(s, secondColon + 1, period, 10);
+                int nanoPrecision = len - (period + 1);
+                if (nanoPrecision > 9)
                     throw new java.lang.IllegalArgumentException(formatError);
-                if (!Character.isDigit(nanos_s.charAt(0)))
+                if (!Character.isDigit(s.charAt(period + 1)))
                     throw new java.lang.IllegalArgumentException(formatError);
-                nanos_s = nanos_s + zeros.substring(0,9-nanos_s.length());
-                a_nanos = Integer.parseInt(nanos_s);
+                int tmpNanos = Integer.parseInt(s, period + 1, len, 10);
+                while (nanoPrecision < 9) {
+                    tmpNanos *= 10;
+                    nanoPrecision++;
+                }
+                a_nanos = tmpNanos;
             } else if (period > 0) {
                 throw new java.lang.IllegalArgumentException(formatError);
             } else {
-                second = Integer.parseInt(time_s.substring(secondColon+1));
+                second = Integer.parseInt(s, secondColon + 1, len, 10);
             }
         } else {
             throw new java.lang.IllegalArgumentException(formatError);
@@ -274,95 +265,53 @@
      *           <code>yyyy-mm-dd hh:mm:ss.fffffffff</code> format
      */
     @SuppressWarnings("deprecation")
-    public String toString () {
-
+    public String toString() {
         int year = super.getYear() + 1900;
         int month = super.getMonth() + 1;
         int day = super.getDate();
         int hour = super.getHours();
         int minute = super.getMinutes();
         int second = super.getSeconds();
-        String yearString;
-        String monthString;
-        String dayString;
-        String hourString;
-        String minuteString;
-        String secondString;
-        String nanosString;
-        String zeros = "000000000";
-        String yearZeros = "0000";
-        StringBuffer timestampBuf;
 
-        if (year < 1000) {
-            // Add leading zeros
-            yearString = "" + year;
-            yearString = yearZeros.substring(0, (4-yearString.length())) +
-                yearString;
-        } else {
-            yearString = "" + year;
-        }
-        if (month < 10) {
-            monthString = "0" + month;
-        } else {
-            monthString = Integer.toString(month);
-        }
-        if (day < 10) {
-            dayString = "0" + day;
+        int trailingZeros = 0;
+        int tmpNanos = nanos;
+        if (tmpNanos == 0) {
+            trailingZeros = 8;
         } else {
-            dayString = Integer.toString(day);
-        }
-        if (hour < 10) {
-            hourString = "0" + hour;
-        } else {
-            hourString = Integer.toString(hour);
-        }
-        if (minute < 10) {
-            minuteString = "0" + minute;
-        } else {
-            minuteString = Integer.toString(minute);
-        }
-        if (second < 10) {
-            secondString = "0" + second;
-        } else {
-            secondString = Integer.toString(second);
-        }
-        if (nanos == 0) {
-            nanosString = "0";
-        } else {
-            nanosString = Integer.toString(nanos);
-
-            // Add leading zeros
-            nanosString = zeros.substring(0, (9-nanosString.length())) +
-                nanosString;
-
-            // Truncate trailing zeros
-            char[] nanosChar = new char[nanosString.length()];
-            nanosString.getChars(0, nanosString.length(), nanosChar, 0);
-            int truncIndex = 8;
-            while (nanosChar[truncIndex] == '0') {
-                truncIndex--;
+            while (tmpNanos % 10 == 0) {
+                tmpNanos /= 10;
+                trailingZeros++;
             }
-
-            nanosString = new String(nanosChar, 0, truncIndex + 1);
         }
 
-        // do a string buffer here instead.
-        timestampBuf = new StringBuffer(20+nanosString.length());
-        timestampBuf.append(yearString);
-        timestampBuf.append("-");
-        timestampBuf.append(monthString);
-        timestampBuf.append("-");
-        timestampBuf.append(dayString);
-        timestampBuf.append(" ");
-        timestampBuf.append(hourString);
-        timestampBuf.append(":");
-        timestampBuf.append(minuteString);
-        timestampBuf.append(":");
-        timestampBuf.append(secondString);
-        timestampBuf.append(".");
-        timestampBuf.append(nanosString);
+        // 8058429: To comply with current JCK tests, we need to deal with year
+        // being any number between 0 and 292278995
+        int count = 10000;
+        int yearSize = 4;
+        do {
+            if (year < count) {
+                break;
+            }
+            yearSize++;
+            count *= 10;
+        } while (count < 1000000000);
 
-        return (timestampBuf.toString());
+        char[] buf = new char[25 + yearSize - trailingZeros];
+        Date.formatDecimalInt(year, buf, 0, yearSize);
+        buf[yearSize] = '-';
+        Date.formatDecimalInt(month, buf, yearSize + 1, 2);
+        buf[yearSize + 3] = '-';
+        Date.formatDecimalInt(day, buf, yearSize + 4, 2);
+        buf[yearSize + 6] = ' ';
+        Date.formatDecimalInt(hour, buf, yearSize + 7, 2);
+        buf[yearSize + 9] = ':';
+        Date.formatDecimalInt(minute, buf, yearSize + 10, 2);
+        buf[yearSize + 12] = ':';
+        Date.formatDecimalInt(second, buf, yearSize + 13, 2);
+        buf[yearSize + 15] = '.';
+        Date.formatDecimalInt(tmpNanos, buf, yearSize + 16, 9 - trailingZeros);
+
+        return jla.newStringUnsafe(buf);
     }
 
     /**
--- a/jdk/src/jdk.localedata/META-INF/cldrdata-services/sun.util.locale.provider.LocaleDataMetaInfo	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/src/jdk.localedata/META-INF/cldrdata-services/sun.util.locale.provider.LocaleDataMetaInfo	Wed Jul 05 20:01:50 2017 +0200
@@ -1,1 +1,1 @@
-sun.util.cldr.CLDRLocaleDataMetaInfo
+sun.util.resources.cldr.provider.CLDRLocaleDataMetaInfo
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/AuthorizationDataEntry.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.security.jgss;
+
+/**
+ * Kerberos 5 AuthorizationData entry.
+ */
+@jdk.Exported
+public final class AuthorizationDataEntry {
+
+    private final int type;
+    private final byte[] data;
+
+    /**
+     * Create an AuthorizationDataEntry object.
+     * @param type the ad-type
+     * @param data the ad-data, a copy of the data will be saved
+     * inside the object.
+     */
+    public AuthorizationDataEntry(int type, byte[] data) {
+        this.type = type;
+        this.data = data.clone();
+    }
+
+    /**
+     * Get the ad-type field.
+     * @return ad-type
+     */
+    public int getType() {
+        return type;
+    }
+
+    /**
+     * Get a copy of the ad-data field.
+     * @return ad-data
+     */
+    public byte[] getData() {
+        return data.clone();
+    }
+
+    public String toString() {
+        return "AuthorizationDataEntry: type="+type+", data=" +
+                data.length + " bytes:\n" +
+                new sun.misc.HexDumpEncoder().encodeBuffer(data);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSContext.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.security.jgss;
+
+import org.ietf.jgss.*;
+import sun.security.jgss.GSSContextImpl;
+import sun.security.krb5.internal.AuthorizationData;
+
+/**
+ * The extended GSSContext interface for supporting additional
+ * functionalities not defined by {@code org.ietf.jgss.GSSContext},
+ * such as querying context-specific attributes.
+ */
+@jdk.Exported
+public interface ExtendedGSSContext extends GSSContext {
+
+    // The impl is almost identical to GSSContextImpl with only 2 differences:
+    // 1. It implements the extended interface
+    // 2. It translates result to data types here in inquireSecContext
+    static class ExtendedGSSContextImpl extends GSSContextImpl
+            implements ExtendedGSSContext {
+
+        public ExtendedGSSContextImpl(GSSContextImpl old) {
+            super(old);
+        }
+
+        @Override
+        public Object inquireSecContext(InquireType type) throws GSSException {
+            SecurityManager security = System.getSecurityManager();
+            if (security != null) {
+                security.checkPermission(
+                        new InquireSecContextPermission(type.toString()));
+            }
+            Object output = super.inquireSecContext(type.name());
+            if (output != null) {
+                if (type == InquireType.KRB5_GET_AUTHZ_DATA) {
+                    AuthorizationData ad = (AuthorizationData) output;
+                    AuthorizationDataEntry[] authzData =
+                            new AuthorizationDataEntry[ad.count()];
+                    for (int i = 0; i < ad.count(); i++) {
+                        authzData[i] = new AuthorizationDataEntry(
+                                ad.item(i).adType, ad.item(i).adData);
+                    }
+                    output = authzData;
+                }
+            }
+            return output;
+        }
+    }
+
+    /**
+     * Return the mechanism-specific attribute associated with {@code type}.
+     * <p>
+     * If there is a security manager, an {@link InquireSecContextPermission}
+     * with the name {@code type.mech} must be granted. Otherwise, this could
+     * result in a {@link SecurityException}.
+     * <p>
+     * Example:
+     * <pre>
+     *      GSSContext ctxt = m.createContext(...)
+     *      // Establishing the context
+     *      if (ctxt instanceof ExtendedGSSContext) {
+     *          ExtendedGSSContext ex = (ExtendedGSSContext)ctxt;
+     *          try {
+     *              Key key = (key)ex.inquireSecContext(
+     *                      InquireType.KRB5_GET_SESSION_KEY);
+     *              // read key info
+     *          } catch (GSSException gsse) {
+     *              // deal with exception
+     *          }
+     *      }
+     * </pre>
+     * @param type the type of the attribute requested
+     * @return the attribute, see the method documentation for details.
+     * @throws GSSException containing  the following
+     * major error codes:
+     *   {@link GSSException#BAD_MECH GSSException.BAD_MECH} if the mechanism
+     *   does not support this method,
+     *   {@link GSSException#UNAVAILABLE GSSException.UNAVAILABLE} if the
+     *   type specified is not supported,
+     *   {@link GSSException#NO_CONTEXT GSSException.NO_CONTEXT} if the
+     *   security context is invalid,
+     *   {@link GSSException#FAILURE GSSException.FAILURE} for other
+     *   unspecified failures.
+     * @throws SecurityException if a security manager exists and a proper
+     *   {@link InquireSecContextPermission} is not granted.
+     * @see InquireSecContextPermission
+     * @see InquireType
+     */
+    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();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSCredential.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.security.jgss;
+
+import org.ietf.jgss.*;
+import sun.security.jgss.GSSCredentialImpl;
+
+/**
+ * The extended GSSCredential interface for supporting additional
+ * functionalities not defined by {@code org.ietf.jgss.GSSCredential}.
+ * @since 1.8
+ */
+@jdk.Exported
+public interface ExtendedGSSCredential extends GSSCredential {
+
+    static class ExtendedGSSCredentialImpl extends GSSCredentialImpl
+            implements ExtendedGSSCredential {
+
+        public ExtendedGSSCredentialImpl(GSSCredentialImpl old) {
+            super(old);
+        }
+    }
+
+    /**
+     * Impersonates a principal. In Kerberos, this can be implemented
+     * using the Microsoft S4U2self extension.
+     * <p>
+     * A {@link GSSException#NO_CRED GSSException.NO_CRED} will be thrown if the
+     * impersonation fails. A {@link GSSException#FAILURE GSSException.FAILURE}
+     * will be  thrown if the impersonation method is not available to this
+     * credential object.
+     * @param name the name of the principal to impersonate
+     * @return a credential for that principal
+     * @throws GSSException  containing the following
+     * major error codes:
+     *   {@link GSSException#NO_CRED GSSException.NO_CRED}
+     *   {@link GSSException#FAILURE GSSException.FAILURE}
+     */
+    public GSSCredential impersonate(GSSName name) throws GSSException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/Extender.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.security.jgss;
+
+import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSCredential;
+import sun.security.jgss.GSSContextImpl;
+import sun.security.jgss.GSSCredentialImpl;
+import sun.security.jgss.JgssExtender;
+
+// The com.sun.security.jgss extension to JGSS-API
+class Extender extends JgssExtender {
+
+    static {
+        JgssExtender.setExtender(new Extender());
+    }
+
+    public GSSCredential wrap(GSSCredential cred) {
+        if (cred instanceof ExtendedGSSCredential.ExtendedGSSCredentialImpl) {
+            return cred;
+        } else {
+            return new ExtendedGSSCredential.ExtendedGSSCredentialImpl((GSSCredentialImpl)cred);
+        }
+    }
+
+    public GSSContext wrap(GSSContext ctxt) {
+        if (ctxt instanceof ExtendedGSSContext.ExtendedGSSContextImpl) {
+            return ctxt;
+        } else {
+            return new ExtendedGSSContext.ExtendedGSSContextImpl((GSSContextImpl)ctxt);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/GSSUtil.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.security.jgss;
+
+import javax.security.auth.Subject;
+import org.ietf.jgss.GSSName;
+import org.ietf.jgss.GSSCredential;
+
+/**
+ * GSS-API Utilities for using in conjunction with Sun Microsystem's
+ * implementation of Java GSS-API.
+ */
+@jdk.Exported
+public class GSSUtil {
+
+    /**
+     * Use this method to convert a GSSName and GSSCredential into a
+     * Subject. Typically this would be done by a server that wants to
+     * impersonate a client thread at the Java level by setting a client
+     * Subject in the current access control context. If the server is merely
+     * interested in using a principal based policy in its local JVM, then
+     * it only needs to provide the GSSName of the client.
+     *
+     * The elements from the GSSName are placed in the principals set of this
+     * Subject and those from the GSSCredential are placed in the private
+     * credentials set of the Subject. Any Kerberos specific elements that
+     * are added to the subject will be instances of the standard Kerberos
+     * implementation classes defined in javax.security.auth.kerberos.
+     *
+     * @return a Subject with the entries that contain elements from the
+     * given GSSName and GSSCredential.
+     *
+     * @param principals a GSSName containing one or more mechanism specific
+     * representations of the same entity. These mechanism specific
+     * representations will be populated in the returned Subject's principal
+     * set.
+     *
+     * @param credentials a GSSCredential containing one or more mechanism
+     * specific credentials for the same entity. These mechanism specific
+     * credentials will be populated in the returned Subject's private
+     * credential set. Passing in a value of null will imply that the private
+     * credential set should be left empty.
+     */
+    public static Subject createSubject(GSSName principals,
+                                     GSSCredential credentials) {
+
+        return  sun.security.jgss.GSSUtil.getSubject(principals,
+                                                     credentials);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/InquireSecContextPermission.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.security.jgss;
+
+import java.security.BasicPermission;
+
+/**
+ * This class is used to protect various attributes of an established
+ * GSS security context that can be accessed using the
+ * {@link com.sun.security.jgss.ExtendedGSSContext#inquireSecContext}
+ * method.
+ *
+ * <p>The target name is the {@link InquireType} allowed.
+ */
+@jdk.Exported
+public final class InquireSecContextPermission extends BasicPermission {
+    private static final long serialVersionUID = -7131173349668647297L;
+
+    /**
+     * Constructs a new {@code InquireSecContextPermission} object with
+     * the specified name. The name is the symbolic name of the
+     * {@link InquireType} allowed.
+     *
+     * @param name the {@link InquireType} allowed by this
+     * permission. "*" means all {@link InquireType}s are allowed.
+     *
+     * @throws NullPointerException if <code>name</code> is <code>null</code>.
+     * @throws IllegalArgumentException if <code>name</code> is empty.
+     */
+    public InquireSecContextPermission(String name) {
+        super(name);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/InquireType.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.security.jgss;
+
+/**
+ * Attribute types that can be specified as an argument of
+ * {@link com.sun.security.jgss.ExtendedGSSContext#inquireSecContext}
+ */
+@jdk.Exported
+public enum InquireType {
+    /**
+     * Attribute type for retrieving the session key of an established
+     * Kerberos 5 security context. The returned object is an instance of
+     * {@link java.security.Key}, which has the following properties:
+     *    <ul>
+     *    <li>Algorithm: enctype as a string, where
+     *        enctype is defined in RFC 3961, section 8.
+     *    <li>Format: "RAW"
+     *    <li>Encoded form: the raw key bytes, not in any ASN.1 encoding
+     *    </ul>
+     * @deprecated as of 1.9, replaced by {@link #KRB5_GET_SESSION_KEY_EX}
+     * which returns an instance of
+     * {@link javax.security.auth.kerberos.EncryptionKey}
+     * that implements the {@link javax.crypto.SecretKey} interface and
+     * has similar methods with {@link javax.security.auth.kerberos.KerberosKey}.
+     */
+    @Deprecated
+    KRB5_GET_SESSION_KEY,
+    /**
+     * Attribute type for retrieving the session key of an
+     * established Kerberos 5 security context. The return value is an
+     * instance of {@link javax.security.auth.kerberos.EncryptionKey}.
+     *
+     * @since 1.9
+     */
+    KRB5_GET_SESSION_KEY_EX,
+    /**
+     * Attribute type for retrieving the service ticket flags of an
+     * established Kerberos 5 security context. The returned object is
+     * a boolean array for the service ticket flags, which is long enough
+     * to contain all true bits. This means if the user wants to get the
+     * <em>n</em>'th bit but the length of the returned array is less than
+     * <em>n</em>, it is regarded as false.
+     */
+    KRB5_GET_TKT_FLAGS,
+    /**
+     * Attribute type for retrieving the authorization data in the
+     * service ticket of an established Kerberos 5 security context.
+     * Only supported on the acceptor side.
+     */
+    KRB5_GET_AUTHZ_DATA,
+    /**
+     * Attribute type for retrieving the authtime in the service ticket
+     * of an established Kerberos 5 security context. The returned object
+     * is a String object in the standard KerberosTime format defined in
+     * RFC 4120 Section 5.2.3.
+     */
+    KRB5_GET_AUTHTIME,
+    /**
+     * Attribute type for retrieving the KRB_CRED message that an initiator
+     * is about to send to an acceptor. The return type is an instance of
+     * {@link javax.security.auth.kerberos.KerberosCredMessage}.
+     *
+     * @since 1.9
+     */
+    KRB5_GET_KRB_CRED,
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/jgss/package-info.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+@jdk.Exported
+package com.sun.security.jgss;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/FactoryImpl.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.security.sasl.gsskerb;
+
+import javax.security.sasl.*;
+import com.sun.security.sasl.util.PolicyUtils;
+
+import java.util.Map;
+import javax.security.auth.callback.CallbackHandler;
+
+/**
+  * Client/server factory for GSSAPI (Kerberos V5) SASL client/server mechs.
+  * See GssKrb5Client/GssKrb5Server for input requirements.
+  *
+  * @author Rosanna Lee
+  */
+public final class FactoryImpl implements SaslClientFactory, SaslServerFactory {
+    private static final String myMechs[] = {
+        "GSSAPI"};
+
+    private static final int mechPolicies[] = {
+        PolicyUtils.NOPLAINTEXT|PolicyUtils.NOANONYMOUS|PolicyUtils.NOACTIVE
+    };
+
+    private static final int GSS_KERB_V5 = 0;
+
+    public FactoryImpl() {
+    }
+
+    public SaslClient createSaslClient(String[] mechs,
+        String authorizationId,
+        String protocol,
+        String serverName,
+        Map<String,?> props,
+        CallbackHandler cbh) throws SaslException {
+
+            for (int i = 0; i < mechs.length; i++) {
+                if (mechs[i].equals(myMechs[GSS_KERB_V5])
+                    && PolicyUtils.checkPolicy(mechPolicies[GSS_KERB_V5], props)) {
+                    return new GssKrb5Client(
+                        authorizationId,
+                        protocol,
+                        serverName,
+                        props,
+                        cbh);
+                }
+            }
+            return null;
+    };
+
+    public SaslServer createSaslServer(String mech,
+        String protocol,
+        String serverName,
+        Map<String,?> props,
+        CallbackHandler cbh) throws SaslException {
+            if (mech.equals(myMechs[GSS_KERB_V5])
+                && PolicyUtils.checkPolicy(mechPolicies[GSS_KERB_V5], props)) {
+                if (cbh == null) {
+                    throw new SaslException(
+                "Callback handler with support for AuthorizeCallback required");
+                }
+                return new GssKrb5Server(
+                    protocol,
+                    serverName,
+                    props,
+                    cbh);
+            }
+            return null;
+    };
+
+    public String[] getMechanismNames(Map<String,?> props) {
+        return PolicyUtils.filterMechs(myMechs, mechPolicies, props);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package com.sun.security.sasl.gsskerb;
+
+import java.util.Locale;
+import java.util.Map;
+import java.util.logging.Level;
+import javax.security.sasl.*;
+import com.sun.security.sasl.util.AbstractSaslImpl;
+import org.ietf.jgss.*;
+import com.sun.security.jgss.ExtendedGSSContext;
+import com.sun.security.jgss.InquireType;
+
+abstract class GssKrb5Base extends AbstractSaslImpl {
+
+    private static final String KRB5_OID_STR = "1.2.840.113554.1.2.2";
+    protected static Oid KRB5_OID;
+    protected static final byte[] EMPTY = new byte[0];
+
+    static {
+        try {
+            KRB5_OID = new Oid(KRB5_OID_STR);
+        } catch (GSSException ignore) {}
+    }
+
+    protected GSSContext secCtx = null;
+    protected static final int JGSS_QOP = 0;    // unrelated to SASL QOP mask
+
+    protected GssKrb5Base(Map<String, ?> props, String className)
+        throws SaslException {
+        super(props, className);
+    }
+
+    /**
+     * Retrieves this mechanism's name.
+     *
+     * @return  The string "GSSAPI".
+     */
+    public String getMechanismName() {
+        return "GSSAPI";
+    }
+
+    @Override
+    public Object getNegotiatedProperty(String propName) {
+        if (!completed) {
+            throw new IllegalStateException("Authentication incomplete");
+        }
+        String xprefix = "com.sun.security.jgss.inquiretype.";
+        if (propName.startsWith(xprefix)) {
+            String type = propName.substring(xprefix.length());
+            if (logger.isLoggable(Level.FINEST)) {
+                logger.logp(Level.FINE, "GssKrb5Base",
+                        "getNegotiatedProperty", propName);
+            }
+            for (InquireType t: InquireType.values()) {
+                if (t.name().toLowerCase(Locale.US).equals(type)) {
+                    try {
+                        return ((ExtendedGSSContext)secCtx).inquireSecContext(t);
+                    } catch (GSSException e) {
+                        if (logger.isLoggable(Level.FINEST)) {
+                            logger.log(Level.WARNING, "inquireSecContext error", e);
+                        }
+                        return null;
+                    }
+                }
+            }
+            // No such InquireType. Although not likely to be defined
+            // as a property in a parent class, still try it.
+        }
+        return super.getNegotiatedProperty(propName);
+    }
+
+    public byte[] unwrap(byte[] incoming, int start, int len)
+        throws SaslException {
+        if (!completed) {
+            throw new IllegalStateException("GSSAPI authentication not completed");
+        }
+
+        // integrity will be true if either privacy or integrity negotiated
+        if (!integrity) {
+            throw new IllegalStateException("No security layer negotiated");
+        }
+
+        try {
+            MessageProp msgProp = new MessageProp(JGSS_QOP, privacy);
+            byte[] answer = secCtx.unwrap(incoming, start, len, msgProp);
+            if (logger.isLoggable(Level.FINEST)) {
+                traceOutput(myClassName, "KRB501:Unwrap", "incoming: ",
+                    incoming, start, len);
+                traceOutput(myClassName, "KRB502:Unwrap", "unwrapped: ",
+                    answer, 0, answer.length);
+            }
+            return answer;
+        } catch (GSSException e) {
+            throw new SaslException("Problems unwrapping SASL buffer", e);
+        }
+    }
+
+    public byte[] wrap(byte[] outgoing, int start, int len) throws SaslException {
+        if (!completed) {
+            throw new IllegalStateException("GSSAPI authentication not completed");
+        }
+
+        // integrity will be true if either privacy or integrity negotiated
+        if (!integrity) {
+            throw new IllegalStateException("No security layer negotiated");
+        }
+
+        // Generate GSS token
+        try {
+            MessageProp msgProp = new MessageProp(JGSS_QOP, privacy);
+            byte[] answer = secCtx.wrap(outgoing, start, len, msgProp);
+            if (logger.isLoggable(Level.FINEST)) {
+                traceOutput(myClassName, "KRB503:Wrap", "outgoing: ",
+                    outgoing, start, len);
+                traceOutput(myClassName, "KRB504:Wrap", "wrapped: ",
+                    answer, 0, answer.length);
+            }
+            return answer;
+
+        } catch (GSSException e) {
+            throw new SaslException("Problem performing GSS wrap", e);
+        }
+    }
+
+    public void dispose() throws SaslException {
+        if (secCtx != null) {
+            try {
+                secCtx.dispose();
+            } catch (GSSException e) {
+                throw new SaslException("Problem disposing GSS context", e);
+            }
+            secCtx = null;
+        }
+    }
+
+    protected void finalize() throws Throwable {
+        dispose();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.security.sasl.gsskerb;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.logging.Level;
+import javax.security.sasl.*;
+
+// JAAS
+import javax.security.auth.callback.CallbackHandler;
+
+// JGSS
+import org.ietf.jgss.*;
+
+/**
+  * Implements the GSSAPI SASL client mechanism for Kerberos V5.
+  * (<A HREF="http://www.ietf.org/rfc/rfc2222.txt">RFC 2222</A>,
+  * <a HREF="http://www.ietf.org/internet-drafts/draft-ietf-cat-sasl-gssapi-04.txt">draft-ietf-cat-sasl-gssapi-04.txt</a>).
+  * It uses the Java Bindings for GSSAPI
+  * (<A HREF="http://www.ietf.org/rfc/rfc2853.txt">RFC 2853</A>)
+  * for getting GSSAPI/Kerberos V5 support.
+  *
+  * The client/server interactions are:
+  * C0: bind (GSSAPI, initial response)
+  * S0: sasl-bind-in-progress, challenge 1 (output of accept_sec_context or [])
+  * C1: bind (GSSAPI, response 1 (output of init_sec_context or []))
+  * S1: sasl-bind-in-progress challenge 2 (security layer, server max recv size)
+  * C2: bind (GSSAPI, response 2 (security layer, client max recv size, authzid))
+  * S2: bind success response
+  *
+  * Expects the client's credentials to be supplied from the
+  * javax.security.sasl.credentials property or from the thread's Subject.
+  * Otherwise the underlying KRB5 mech will attempt to acquire Kerberos creds
+  * by logging into Kerberos (via default TextCallbackHandler).
+  * These creds will be used for exchange with server.
+  *
+  * Required callbacks: none.
+  *
+  * Environment properties that affect behavior of implementation:
+  *
+  * javax.security.sasl.qop
+  * - quality of protection; list of auth, auth-int, auth-conf; default is "auth"
+  * javax.security.sasl.maxbuf
+  * - max receive buffer size; default is 65536
+  * javax.security.sasl.sendmaxbuffer
+  * - max send buffer size; default is 65536; (min with server max recv size)
+  *
+  * javax.security.sasl.server.authentication
+  * - "true" means require mutual authentication; default is "false"
+  *
+  * javax.security.sasl.credentials
+  * - an {@link org.ietf.jgss.GSSCredential} used for delegated authentication.
+  *
+  * @author Rosanna Lee
+  */
+
+final class GssKrb5Client extends GssKrb5Base implements SaslClient {
+    // ---------------- Constants -----------------
+    private static final String MY_CLASS_NAME = GssKrb5Client.class.getName();
+
+    private boolean finalHandshake = false;
+    private boolean mutual = false;       // default false
+    private byte[] authzID;
+
+    /**
+     * Creates a SASL mechanism with client credentials that it needs
+     * to participate in GSS-API/Kerberos v5 authentication exchange
+     * with the server.
+     */
+    GssKrb5Client(String authzID, String protocol, String serverName,
+        Map<String, ?> props, CallbackHandler cbh) throws SaslException {
+
+        super(props, MY_CLASS_NAME);
+
+        String service = protocol + "@" + serverName;
+        logger.log(Level.FINE, "KRB5CLNT01:Requesting service name: {0}",
+            service);
+
+        try {
+            GSSManager mgr = GSSManager.getInstance();
+
+            // Create the name for the requested service entity for Krb5 mech
+            GSSName acceptorName = mgr.createName(service,
+                GSSName.NT_HOSTBASED_SERVICE, KRB5_OID);
+
+            // Parse properties to check for supplied credentials
+            GSSCredential credentials = null;
+            if (props != null) {
+                Object prop = props.get(Sasl.CREDENTIALS);
+                if (prop != null && prop instanceof GSSCredential) {
+                    credentials = (GSSCredential) prop;
+                    logger.log(Level.FINE,
+                        "KRB5CLNT01:Using the credentials supplied in " +
+                        "javax.security.sasl.credentials");
+                }
+            }
+
+            // Create a context using credentials for Krb5 mech
+            secCtx = mgr.createContext(acceptorName,
+                KRB5_OID,   /* mechanism */
+                credentials, /* credentials */
+                GSSContext.INDEFINITE_LIFETIME);
+
+            // Request credential delegation when credentials have been supplied
+            if (credentials != null) {
+                secCtx.requestCredDeleg(true);
+            }
+
+            // Parse properties  to set desired context options
+            if (props != null) {
+                // Mutual authentication
+                String prop = (String)props.get(Sasl.SERVER_AUTH);
+                if (prop != null) {
+                    mutual = "true".equalsIgnoreCase(prop);
+                }
+            }
+            secCtx.requestMutualAuth(mutual);
+
+            // Always specify potential need for integrity and confidentiality
+            // Decision will be made during final handshake
+            secCtx.requestConf(true);
+            secCtx.requestInteg(true);
+
+        } catch (GSSException e) {
+            throw new SaslException("Failure to initialize security context", e);
+        }
+
+        if (authzID != null && authzID.length() > 0) {
+            try {
+                this.authzID = authzID.getBytes("UTF8");
+            } catch (IOException e) {
+                throw new SaslException("Cannot encode authorization ID", e);
+            }
+        }
+    }
+
+    public boolean hasInitialResponse() {
+        return true;
+    }
+
+    /**
+     * Processes the challenge data.
+     *
+     * The server sends a challenge data using which the client must
+     * process using GSS_Init_sec_context.
+     * As per RFC 2222, when GSS_S_COMPLETE is returned, we do
+     * an extra handshake to determine the negotiated security protection
+     * and buffer sizes.
+     *
+     * @param challengeData A non-null byte array containing the
+     * challenge data from the server.
+     * @return A non-null byte array containing the response to be
+     * sent to the server.
+     */
+    public byte[] evaluateChallenge(byte[] challengeData) throws SaslException {
+        if (completed) {
+            throw new IllegalStateException(
+                "GSSAPI authentication already complete");
+        }
+
+        if (finalHandshake) {
+            return doFinalHandshake(challengeData);
+        } else {
+
+            // Security context not established yet; continue with init
+
+            try {
+                byte[] gssOutToken = secCtx.initSecContext(challengeData,
+                    0, challengeData.length);
+                if (logger.isLoggable(Level.FINER)) {
+                    traceOutput(MY_CLASS_NAME, "evaluteChallenge",
+                        "KRB5CLNT02:Challenge: [raw]", challengeData);
+                    traceOutput(MY_CLASS_NAME, "evaluateChallenge",
+                        "KRB5CLNT03:Response: [after initSecCtx]", gssOutToken);
+                }
+
+                if (secCtx.isEstablished()) {
+                    finalHandshake = true;
+                    if (gssOutToken == null) {
+                        // RFC 2222 7.2.1:  Client responds with no data
+                        return EMPTY;
+                    }
+                }
+
+                return gssOutToken;
+            } catch (GSSException e) {
+                throw new SaslException("GSS initiate failed", e);
+            }
+        }
+    }
+
+    private byte[] doFinalHandshake(byte[] challengeData) throws SaslException {
+        try {
+            // Security context already established. challengeData
+            // should contain security layers and server's maximum buffer size
+
+            if (logger.isLoggable(Level.FINER)) {
+                traceOutput(MY_CLASS_NAME, "doFinalHandshake",
+                    "KRB5CLNT04:Challenge [raw]:", challengeData);
+            }
+
+            if (challengeData.length == 0) {
+                // Received S0, should return []
+                return EMPTY;
+            }
+
+            // Received S1 (security layer, server max recv size)
+
+            byte[] gssOutToken = secCtx.unwrap(challengeData, 0,
+                challengeData.length, new MessageProp(0, false));
+
+            // First octet is a bit-mask specifying the protections
+            // supported by the server
+            if (logger.isLoggable(Level.FINE)) {
+                if (logger.isLoggable(Level.FINER)) {
+                    traceOutput(MY_CLASS_NAME, "doFinalHandshake",
+                        "KRB5CLNT05:Challenge [unwrapped]:", gssOutToken);
+                }
+                logger.log(Level.FINE, "KRB5CLNT06:Server protections: {0}",
+                    gssOutToken[0]);
+            }
+
+            // Client selects preferred protection
+            // qop is ordered list of qop values
+            byte selectedQop = findPreferredMask(gssOutToken[0], qop);
+            if (selectedQop == 0) {
+                throw new SaslException(
+                    "No common protection layer between client and server");
+            }
+
+            if ((selectedQop&PRIVACY_PROTECTION) != 0) {
+                privacy = true;
+                integrity = true;
+            } else if ((selectedQop&INTEGRITY_ONLY_PROTECTION) != 0) {
+                integrity = true;
+            }
+
+            // 2nd-4th octets specifies maximum buffer size expected by
+            // server (in network byte order)
+            int srvMaxBufSize = networkByteOrderToInt(gssOutToken, 1, 3);
+
+            // Determine the max send buffer size based on what the
+            // server is able to receive and our specified max
+            sendMaxBufSize = (sendMaxBufSize == 0) ? srvMaxBufSize :
+                Math.min(sendMaxBufSize, srvMaxBufSize);
+
+            // Update context to limit size of returned buffer
+            rawSendSize = secCtx.getWrapSizeLimit(JGSS_QOP, privacy,
+                sendMaxBufSize);
+
+            if (logger.isLoggable(Level.FINE)) {
+                logger.log(Level.FINE,
+"KRB5CLNT07:Client max recv size: {0}; server max recv size: {1}; rawSendSize: {2}",
+                    new Object[] {recvMaxBufSize,
+                                  srvMaxBufSize,
+                                  rawSendSize});
+            }
+
+            // Construct negotiated security layers and client's max
+            // receive buffer size and authzID
+            int len = 4;
+            if (authzID != null) {
+                len += authzID.length;
+            }
+
+            byte[] gssInToken = new byte[len];
+            gssInToken[0] = selectedQop;
+
+            if (logger.isLoggable(Level.FINE)) {
+                logger.log(Level.FINE,
+            "KRB5CLNT08:Selected protection: {0}; privacy: {1}; integrity: {2}",
+                    new Object[]{selectedQop,
+                                 Boolean.valueOf(privacy),
+                                 Boolean.valueOf(integrity)});
+            }
+
+            intToNetworkByteOrder(recvMaxBufSize, gssInToken, 1, 3);
+            if (authzID != null) {
+                // copy authorization id
+                System.arraycopy(authzID, 0, gssInToken, 4, authzID.length);
+                logger.log(Level.FINE, "KRB5CLNT09:Authzid: {0}", authzID);
+            }
+
+            if (logger.isLoggable(Level.FINER)) {
+                traceOutput(MY_CLASS_NAME, "doFinalHandshake",
+                    "KRB5CLNT10:Response [raw]", gssInToken);
+            }
+
+            gssOutToken = secCtx.wrap(gssInToken,
+                0, gssInToken.length,
+                new MessageProp(0 /* qop */, false /* privacy */));
+
+            if (logger.isLoggable(Level.FINER)) {
+                traceOutput(MY_CLASS_NAME, "doFinalHandshake",
+                    "KRB5CLNT11:Response [after wrap]", gssOutToken);
+            }
+
+            completed = true;  // server authenticated
+
+            return gssOutToken;
+        } catch (GSSException e) {
+            throw new SaslException("Final handshake failed", e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.security.sasl.gsskerb;
+
+import javax.security.sasl.*;
+import java.io.*;
+import java.util.Map;
+import java.util.logging.Level;
+
+// JAAS
+import javax.security.auth.callback.*;
+
+// JGSS
+import org.ietf.jgss.*;
+
+/**
+  * Implements the GSSAPI SASL server mechanism for Kerberos V5.
+  * (<A HREF="http://www.ietf.org/rfc/rfc2222.txt">RFC 2222</A>,
+  * <a HREF="http://www.ietf.org/internet-drafts/draft-ietf-cat-sasl-gssapi-00.txt">draft-ietf-cat-sasl-gssapi-00.txt</a>).
+  *
+  * Expects thread's Subject to contain server's Kerberos credentials
+  * - If not, underlying KRB5 mech will attempt to acquire Kerberos creds
+  *   by logging into Kerberos (via default TextCallbackHandler).
+  * - These creds will be used for exchange with client.
+  *
+  * Required callbacks:
+  * - AuthorizeCallback
+  *      handler must verify that authid/authzids are allowed and set
+  *      authorized ID to be the canonicalized authzid (if applicable).
+  *
+  * Environment properties that affect behavior of implementation:
+  *
+  * javax.security.sasl.qop
+  * - quality of protection; list of auth, auth-int, auth-conf; default is "auth"
+  * javax.security.sasl.maxbuf
+  * - max receive buffer size; default is 65536
+  * javax.security.sasl.sendmaxbuffer
+  * - max send buffer size; default is 65536; (min with client max recv size)
+  *
+  * @author Rosanna Lee
+  */
+final class GssKrb5Server extends GssKrb5Base implements SaslServer {
+    private static final String MY_CLASS_NAME = GssKrb5Server.class.getName();
+
+    private int handshakeStage = 0;
+    private String peer;
+    private String me;
+    private String authzid;
+    private CallbackHandler cbh;
+
+    // When serverName is null, the server will be unbound. We need to save and
+    // check the protocol name after the context is established. This value
+    // will be null if serverName is not null.
+    private final String protocolSaved;
+    /**
+     * Creates a SASL mechanism with server credentials that it needs
+     * to participate in GSS-API/Kerberos v5 authentication exchange
+     * with the client.
+     */
+    GssKrb5Server(String protocol, String serverName,
+        Map<String, ?> props, CallbackHandler cbh) throws SaslException {
+
+        super(props, MY_CLASS_NAME);
+
+        this.cbh = cbh;
+
+        String service;
+        if (serverName == null) {
+            protocolSaved = protocol;
+            service = null;
+        } else {
+            protocolSaved = null;
+            service = protocol + "@" + serverName;
+        }
+
+        logger.log(Level.FINE, "KRB5SRV01:Using service name: {0}", service);
+
+        try {
+            GSSManager mgr = GSSManager.getInstance();
+
+            // Create the name for the requested service entity for Krb5 mech
+            GSSName serviceName = service == null ? null:
+                    mgr.createName(service, GSSName.NT_HOSTBASED_SERVICE, KRB5_OID);
+
+            GSSCredential cred = mgr.createCredential(serviceName,
+                GSSCredential.INDEFINITE_LIFETIME,
+                KRB5_OID, GSSCredential.ACCEPT_ONLY);
+
+            // Create a context using the server's credentials
+            secCtx = mgr.createContext(cred);
+
+            if ((allQop&INTEGRITY_ONLY_PROTECTION) != 0) {
+                // Might need integrity
+                secCtx.requestInteg(true);
+            }
+
+            if ((allQop&PRIVACY_PROTECTION) != 0) {
+                // Might need privacy
+                secCtx.requestConf(true);
+            }
+        } catch (GSSException e) {
+            throw new SaslException("Failure to initialize security context", e);
+        }
+        logger.log(Level.FINE, "KRB5SRV02:Initialization complete");
+    }
+
+
+    /**
+     * Processes the response data.
+     *
+     * The client sends response data to which the server must
+     * process using GSS_accept_sec_context.
+     * As per RFC 2222, the GSS authenication completes (GSS_S_COMPLETE)
+     * we do an extra hand shake to determine the negotiated security protection
+     * and buffer sizes.
+     *
+     * @param responseData A non-null but possible empty byte array containing the
+     * response data from the client.
+     * @return A non-null byte array containing the challenge to be
+     * sent to the client, or null when no more data is to be sent.
+     */
+    public byte[] evaluateResponse(byte[] responseData) throws SaslException {
+        if (completed) {
+            throw new SaslException(
+                "SASL authentication already complete");
+        }
+
+        if (logger.isLoggable(Level.FINER)) {
+            traceOutput(MY_CLASS_NAME, "evaluateResponse",
+                "KRB5SRV03:Response [raw]:", responseData);
+        }
+
+        switch (handshakeStage) {
+        case 1:
+            return doHandshake1(responseData);
+
+        case 2:
+            return doHandshake2(responseData);
+
+        default:
+            // Security context not established yet; continue with accept
+
+            try {
+                byte[] gssOutToken = secCtx.acceptSecContext(responseData,
+                    0, responseData.length);
+
+                if (logger.isLoggable(Level.FINER)) {
+                    traceOutput(MY_CLASS_NAME, "evaluateResponse",
+                        "KRB5SRV04:Challenge: [after acceptSecCtx]", gssOutToken);
+                }
+
+                if (secCtx.isEstablished()) {
+                    handshakeStage = 1;
+
+                    peer = secCtx.getSrcName().toString();
+                    me = secCtx.getTargName().toString();
+
+                    logger.log(Level.FINE,
+                            "KRB5SRV05:Peer name is : {0}, my name is : {1}",
+                            new Object[]{peer, me});
+
+                    // me might take the form of proto@host or proto/host
+                    if (protocolSaved != null &&
+                            !protocolSaved.equalsIgnoreCase(me.split("[/@]")[0])) {
+                        throw new SaslException(
+                                "GSS context targ name protocol error: " + me);
+                    }
+
+                    if (gssOutToken == null) {
+                        return doHandshake1(EMPTY);
+                    }
+                }
+
+                return gssOutToken;
+            } catch (GSSException e) {
+                throw new SaslException("GSS initiate failed", e);
+            }
+        }
+    }
+
+    private byte[] doHandshake1(byte[] responseData) throws SaslException {
+        try {
+            // Security context already established. responseData
+            // should contain no data
+            if (responseData != null && responseData.length > 0) {
+                throw new SaslException(
+                    "Handshake expecting no response data from server");
+            }
+
+            // Construct 4 octets of data:
+            // First octet contains bitmask specifying protections supported
+            // 2nd-4th octets contains max receive buffer of server
+
+            byte[] gssInToken = new byte[4];
+            gssInToken[0] = allQop;
+            intToNetworkByteOrder(recvMaxBufSize, gssInToken, 1, 3);
+
+            if (logger.isLoggable(Level.FINE)) {
+                logger.log(Level.FINE,
+                    "KRB5SRV06:Supported protections: {0}; recv max buf size: {1}",
+                    new Object[]{allQop,
+                                 recvMaxBufSize});
+            }
+
+            handshakeStage = 2;  // progress to next stage
+
+            if (logger.isLoggable(Level.FINER)) {
+                traceOutput(MY_CLASS_NAME, "doHandshake1",
+                    "KRB5SRV07:Challenge [raw]", gssInToken);
+            }
+
+            byte[] gssOutToken = secCtx.wrap(gssInToken, 0, gssInToken.length,
+                new MessageProp(0 /* gop */, false /* privacy */));
+
+            if (logger.isLoggable(Level.FINER)) {
+                traceOutput(MY_CLASS_NAME, "doHandshake1",
+                    "KRB5SRV08:Challenge [after wrap]", gssOutToken);
+            }
+            return gssOutToken;
+
+        } catch (GSSException e) {
+            throw new SaslException("Problem wrapping handshake1", e);
+        }
+    }
+
+    private byte[] doHandshake2(byte[] responseData) throws SaslException {
+        try {
+            // Expecting 4 octets from client selected protection
+            // and client's receive buffer size
+            byte[] gssOutToken = secCtx.unwrap(responseData, 0,
+                responseData.length, new MessageProp(0, false));
+
+            if (logger.isLoggable(Level.FINER)) {
+                traceOutput(MY_CLASS_NAME, "doHandshake2",
+                    "KRB5SRV09:Response [after unwrap]", gssOutToken);
+            }
+
+            // First octet is a bit-mask specifying the selected protection
+            byte selectedQop = gssOutToken[0];
+            if ((selectedQop&allQop) == 0) {
+                throw new SaslException("Client selected unsupported protection: "
+                    + selectedQop);
+            }
+            if ((selectedQop&PRIVACY_PROTECTION) != 0) {
+                privacy = true;
+                integrity = true;
+            } else if ((selectedQop&INTEGRITY_ONLY_PROTECTION) != 0) {
+                integrity = true;
+            }
+
+            // 2nd-4th octets specifies maximum buffer size expected by
+            // client (in network byte order). This is the server's send
+            // buffer maximum.
+            int clntMaxBufSize = networkByteOrderToInt(gssOutToken, 1, 3);
+
+            // Determine the max send buffer size based on what the
+            // client is able to receive and our specified max
+            sendMaxBufSize = (sendMaxBufSize == 0) ? clntMaxBufSize :
+                Math.min(sendMaxBufSize, clntMaxBufSize);
+
+            // Update context to limit size of returned buffer
+            rawSendSize = secCtx.getWrapSizeLimit(JGSS_QOP, privacy,
+                sendMaxBufSize);
+
+            if (logger.isLoggable(Level.FINE)) {
+                logger.log(Level.FINE,
+            "KRB5SRV10:Selected protection: {0}; privacy: {1}; integrity: {2}",
+                    new Object[]{selectedQop,
+                                 Boolean.valueOf(privacy),
+                                 Boolean.valueOf(integrity)});
+                logger.log(Level.FINE,
+"KRB5SRV11:Client max recv size: {0}; server max send size: {1}; rawSendSize: {2}",
+                    new Object[] {clntMaxBufSize,
+                                  sendMaxBufSize,
+                                  rawSendSize});
+            }
+
+            // Get authorization identity, if any
+            if (gssOutToken.length > 4) {
+                try {
+                    authzid = new String(gssOutToken, 4,
+                        gssOutToken.length - 4, "UTF-8");
+                } catch (UnsupportedEncodingException uee) {
+                    throw new SaslException ("Cannot decode authzid", uee);
+                }
+            } else {
+                authzid = peer;
+            }
+            logger.log(Level.FINE, "KRB5SRV12:Authzid: {0}", authzid);
+
+            AuthorizeCallback acb = new AuthorizeCallback(peer, authzid);
+
+            // In Kerberos, realm is embedded in peer name
+            cbh.handle(new Callback[] {acb});
+            if (acb.isAuthorized()) {
+                authzid = acb.getAuthorizedID();
+                completed = true;
+            } else {
+                // Authorization failed
+                throw new SaslException(peer +
+                    " is not authorized to connect as " + authzid);
+            }
+
+            return null;
+        } catch (GSSException e) {
+            throw new SaslException("Final handshake step failed", e);
+        } catch (IOException e) {
+            throw new SaslException("Problem with callback handler", e);
+        } catch (UnsupportedCallbackException e) {
+            throw new SaslException("Problem with callback handler", e);
+        }
+    }
+
+    public String getAuthorizationID() {
+        if (completed) {
+            return authzid;
+        } else {
+            throw new IllegalStateException("Authentication incomplete");
+        }
+    }
+
+    public Object getNegotiatedProperty(String propName) {
+        if (!completed) {
+            throw new IllegalStateException("Authentication incomplete");
+        }
+
+        Object result;
+        switch (propName) {
+            case Sasl.BOUND_SERVER_NAME:
+                try {
+                    // me might take the form of proto@host or proto/host
+                    result = me.split("[/@]")[1];
+                } catch (Exception e) {
+                    result = null;
+                }
+                break;
+            default:
+                result = super.getNegotiatedProperty(propName);
+        }
+        return result;
+    }
+}
--- a/jdk/test/ProblemList.txt	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/test/ProblemList.txt	Wed Jul 05 20:01:50 2017 +0200
@@ -139,9 +139,6 @@
 com/sun/management/OperatingSystemMXBean/GetSystemCpuLoad.java  aix-all
 javax/management/MBeanServer/OldMBeanServerTest.java            aix-all
 
-# 8050115
-javax/management/monitor/GaugeMonitorDeadlockTest.java          generic-all
-
 ############################################################################
 
 # jdk_math
--- a/jdk/test/TEST.ROOT	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/test/TEST.ROOT	Wed Jul 05 20:01:50 2017 +0200
@@ -8,7 +8,7 @@
 othervm.dirs=java/awt java/beans javax/accessibility javax/imageio javax/sound javax/print javax/management com/sun/awt sun/awt sun/java2d sun/pisces
 
 # Tests that cannot run concurrently
-exclusiveAccess.dirs=java/rmi/Naming java/util/prefs sun/management/jmxremote sun/tools/jstatd sun/security/mscapi
+exclusiveAccess.dirs=java/rmi/Naming java/util/prefs sun/management/jmxremote sun/tools/jstatd sun/security/mscapi java/util/stream
 
 # Group definitions
 groups=TEST.groups [closed/TEST.groups]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Graphics2D/WhiteTextColorTest.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.*;
+import java.awt.image.*;
+import javax.swing.*;
+
+/**
+ * @test
+ * @bug 8056009
+ * @summary tests whether Graphics.setColor-calls with Color.white are ignored directly
+ *          after pipeline initialization for a certain set of operations.
+ * @author ceisserer
+ */
+public class WhiteTextColorTest extends Frame {
+    public static volatile boolean success = false;
+
+    public WhiteTextColorTest() {
+        Image dstImg = getGraphicsConfiguration()
+                .createCompatibleVolatileImage(30, 20);
+        Graphics g = dstImg.getGraphics();
+
+        g.setColor(Color.BLACK);
+        g.fillRect(0, 0, dstImg.getWidth(null), dstImg.getHeight(null));
+        g.setColor(Color.WHITE);
+        g.drawString("Test", 0, 15);
+
+        BufferedImage readBackImg = new BufferedImage(dstImg.getWidth(null),
+                dstImg.getHeight(null), BufferedImage.TYPE_INT_RGB);
+        readBackImg.getGraphics().drawImage(dstImg, 0, 0, null);
+
+        for (int x = 0; x < readBackImg.getWidth(); x++) {
+            for (int y = 0; y < readBackImg.getHeight(); y++) {
+                int pixel = readBackImg.getRGB(x, y);
+
+                // In case a single white pixel is found, the
+                // setColor(Color.WHITE)
+                // call before was not ignored and the bug is not present
+                if (pixel == 0xFFFFFFFF) {
+                    return;
+                }
+            }
+        }
+
+        throw new RuntimeException("Test Failed");
+    }
+
+    public static void main(String[] args) throws Exception {
+        SwingUtilities.invokeLater(new Runnable() {
+            public void run() {
+                new WhiteTextColorTest();
+            }
+        });
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Window/setLocRelativeTo/SetLocationRelativeToTest.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.*;
+import java.util.ArrayList;
+import javax.swing.*;
+
+/*
+@test
+@summary Toplevel should be correctly positioned as relative to a component:
+       so that their centers coincide
+       or, if the component is hidden, centered on the screen.
+@bug 8036915
+@library ../../../../lib/testlibrary
+@build ExtendedRobot
+@run main/timeout=1200 SetLocationRelativeToTest
+*/
+
+public class SetLocationRelativeToTest {
+    private static int delay = 500;
+    private static boolean testEverything = false;// NB: change this to true to test everything
+    java.util.List<Window> awtToplevels = new ArrayList<Window>();
+    java.util.List<Window> swingToplevels = new ArrayList<Window>();
+    java.util.List<Window> allToplevels = new ArrayList<Window>();
+    java.util.List<Component> awtComponents = new ArrayList<Component>();
+    java.util.List<Component> swingComponents = new ArrayList<Component>();
+    java.util.List<Component> allComponents = new ArrayList<Component>();
+    Label placeholder = new Label();
+    JLabel jplaceholder = new JLabel();
+    JFrame jcontainer;
+    public SetLocationRelativeToTest() {
+        Frame frame = new Frame("Frame");
+        frame.setSize(200,100);
+        Frame uframe = new Frame("U.Frame");
+        uframe.setUndecorated(true);
+        uframe.setSize(200,100);
+        Window window = new Window(frame);
+        window.setSize(200,100);
+        Dialog dialog = new Dialog(frame, "Dialog");
+        dialog.setSize(200,100);
+        awtToplevels.add(frame);
+        awtToplevels.add(uframe);
+        awtToplevels.add(window);
+        awtToplevels.add(dialog);
+
+        awtComponents.add(new TextArea("Am a TextArea"));
+        awtComponents.add(new TextField("Am a TextField"));
+        awtComponents.add(new Button("Press"));
+        awtComponents.add(new Label("Label"));
+        Choice aChoice = new Choice();
+        aChoice.add("One");
+        aChoice.add("Two");
+        awtComponents.add(aChoice);
+        awtComponents.add(new Canvas());
+        awtComponents.add(new List(4));
+        awtComponents.add(new Checkbox("Me CheckBox"));
+        awtComponents.add(new Scrollbar());
+
+        swingComponents.add(new JTextArea("Am a JTextArea"));
+        swingComponents.add(new JTextField("Am a JTextField"));
+        swingComponents.add(new JButton("Press"));
+        swingComponents.add(new JLabel("JLabel"));
+        JComboBox jcombo = new JComboBox();
+        swingComponents.add(jcombo);
+        swingComponents.add(new JPanel());
+        swingComponents.add(new JList());
+        swingComponents.add(new JCheckBox("Me JCheckBox"));
+        swingComponents.add(new JScrollBar());
+    }
+
+    public static void main(String args[]) {
+        SetLocationRelativeToTest test = new SetLocationRelativeToTest();
+        test.doAWTTest(true);
+        test.doAWTTest(false);
+        try {
+            test.doSwingTest(true);
+            test.doSwingTest(false);
+        }catch(InterruptedException ie) {
+            ie.printStackTrace();
+        }catch(java.lang.reflect.InvocationTargetException ite) {
+            ite.printStackTrace();
+            throw new RuntimeException("InvocationTarget?");
+        }
+        return;
+    }
+
+    // In regular testing, we select just few components to test
+    // randomly. If full testing required, select many ("all").
+    void selectObjectsToTest(boolean doSwing) {
+        allToplevels.clear();
+        allComponents.clear();
+        if(testEverything) {
+            allToplevels.addAll(0, awtToplevels);
+            allComponents.addAll(0, awtComponents);
+            if(doSwing) {
+                allToplevels.addAll(allToplevels.size(), swingToplevels);
+                allComponents.addAll(allComponents.size(), swingComponents);
+            }
+        }else{
+            //select a random of each
+            int i = (int)(java.lang.Math.random()*awtToplevels.size());
+            allToplevels.add(awtToplevels.get(i));
+            i = (int)(java.lang.Math.random()*awtComponents.size());
+            allComponents.add(awtComponents.get(i));
+            if(doSwing) {
+                i = (int)(java.lang.Math.random()*swingToplevels.size());
+                allToplevels.add(swingToplevels.get(i));
+                i = (int)(java.lang.Math.random()*swingComponents.size());
+                allComponents.add(swingComponents.get(i));
+            }
+        }
+    }
+
+    // create Frame, add an AWT component to it,
+    // hide it (or not) and position a new toplevel
+    // relativeTo
+    void doAWTTest(boolean isHidden) {
+        boolean res;
+        ExtendedRobot robot;
+        try {
+            robot = new ExtendedRobot();
+        }catch(Exception ex) {
+            ex.printStackTrace();
+            throw new RuntimeException("Failed: "+ex.getMessage());
+        }
+        Frame container = new Frame("Frame");
+        container.setBounds(100,100,300,300);
+        container.setLayout(new GridLayout(3,1));
+        container.add(placeholder);
+        container.setVisible(true);
+        selectObjectsToTest(false);
+        for(Component c: allComponents) {
+            placeholder.setText((isHidden ? "Hidden: " : "Below is ")+ c.getClass().getName());
+            c.setVisible(true);
+            container.add(c);
+            container.doLayout();
+            if(isHidden) {
+                c.setVisible(false);
+            }
+            robot.waitForIdle(delay);
+            for(Window w: allToplevels) {
+                w.setLocationRelativeTo(c);
+                w.setVisible(true);
+                robot.waitForIdle(delay);
+                res = compareLocations(w, c, robot);
+                System.out.println(c.getClass().getName()+"   \t: "+w.getClass().getName()+
+                    ((w instanceof Frame) && (((Frame)w).isUndecorated()) ? " undec\t\t:" : "\t\t:")+" "+
+                    (res ? "" : "Failed"));
+                if(!res) {
+                    throw new RuntimeException("Test failed.");
+                }
+                w.dispose();
+            }
+            container.remove(c);
+            robot.waitForIdle(delay);
+        }
+        container.dispose();
+    }
+
+    // Create JFrame, add an AWT or Swing component to it,
+    // hide it (or not) and position a new toplevel
+    // relativeTo
+    void doSwingTest(boolean isHidden) throws InterruptedException,
+                       java.lang.reflect.InvocationTargetException {
+        boolean res;
+        ExtendedRobot robot;
+        try {
+            robot = new ExtendedRobot();
+        }catch(Exception ex) {
+            ex.printStackTrace();
+            throw new RuntimeException("Failed: "+ex.getMessage());
+        }
+
+        EventQueue.invokeAndWait( () -> {
+            JFrame jframe = new JFrame("jframe");
+            jframe.setSize(200,100);
+            swingToplevels.add(jframe);
+            JFrame ujframe = new JFrame("ujframe");
+            ujframe.setSize(200,100);
+            ujframe.setUndecorated(true);
+            swingToplevels.add(ujframe);
+            JWindow jwin = new JWindow();
+            jwin.setSize(200,100);
+            swingToplevels.add(jwin);
+            JDialog jdia = new JDialog((Frame)null, "JDialog");
+            jdia.setSize(200,100);
+            swingToplevels.add(jdia);
+            jcontainer = new JFrame("JFrame");
+            jcontainer.setBounds(100,100,300,300);
+            jcontainer.setLayout(new GridLayout(3,1));
+            jcontainer.add(jplaceholder);
+            jcontainer.setVisible(true);
+            selectObjectsToTest(true);
+        });
+        robot.waitForIdle(delay);
+
+        for(Component c: allComponents) {
+            EventQueue.invokeAndWait( () -> {
+                jplaceholder.setText((isHidden ? "Hidden: " : "Below is: ")+ c.getClass().getName());
+                c.setVisible(true);
+                jcontainer.add(c);
+                jcontainer.doLayout();
+                if(isHidden) {
+                    c.setVisible(false);
+                }
+            });
+            robot.waitForIdle(delay);
+            for(Window w: allToplevels) {
+                EventQueue.invokeAndWait( () -> {
+                    w.setLocationRelativeTo(c);
+                    w.setVisible(true);
+                });
+                robot.waitForIdle(delay);
+                res = compareLocations(w, c, robot);
+                System.out.println(c.getClass().getName()+"   \t: "+w.getClass().getName()+
+                    ((w instanceof Frame) && (((Frame)w).isUndecorated()) ? " undec\t\t:" : "\t\t:")+" "+
+                    (res ? "" : "Failed"));
+                EventQueue.invokeAndWait( () -> {
+                    w.dispose();
+                });
+                robot.waitForIdle();
+                if(!res) {
+                    throw new RuntimeException("Test failed.");
+                }
+            }
+            EventQueue.invokeAndWait( () -> {
+                jcontainer.remove(c);
+            });
+            robot.waitForIdle(delay);
+        }
+        EventQueue.invokeAndWait( () -> {
+            jcontainer.dispose();
+        });
+    }
+
+    // Check, finally, if w  either is concentric with c
+    // or sits in the center of the screen (if c is hidden)
+    boolean compareLocations(final Window w, final Component c, ExtendedRobot robot) {
+        final Point pc = new Point();
+        final Point pw = new Point();
+        try {
+            EventQueue.invokeAndWait( () -> {
+                pw.setLocation(w.getLocationOnScreen());
+                pw.translate(w.getWidth()/2, w.getHeight()/2);
+                if(!c.isVisible()) {
+                    Rectangle screenRect = w.getGraphicsConfiguration().getBounds();
+                    pc.setLocation(screenRect.x+screenRect.width/2,
+                                   screenRect.y+screenRect.height/2);
+                }else{
+                    pc.setLocation(c.getLocationOnScreen());
+                    pc.translate(c.getWidth()/2, c.getHeight()/2);
+                }
+            });
+        } catch(InterruptedException ie) {
+            throw new RuntimeException("Interrupted");
+        } catch(java.lang.reflect.InvocationTargetException ite) {
+            ite.printStackTrace();
+            throw new RuntimeException("InvocationTarget?");
+        }
+        robot.waitForIdle(delay);
+        // Compare with 1 tolerance to forgive possible rounding errors
+        if(pc.x - pw.x > 1 ||
+           pc.x - pw.x < -1 ||
+           pc.y - pw.y > 1 ||
+           pc.y - pw.y < -1 ) {
+            System.out.println("Center of "+(c.isVisible() ? "Component:" : "screen:")+pc);
+            System.out.println("Center of Window:"+pw);
+            System.out.println("Centers of "+w+" and "+c+" do not coincide");
+            return false;
+        }
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/font/GlyphVector/GlyphVectorOutline.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2014 Google Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.font.LineBreakMeasurer;
+import java.awt.font.TextAttribute;
+import java.awt.font.TextLayout;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.text.AttributedString;
+
+import javax.imageio.ImageIO;
+
+/**
+ * Manual test for:
+ * JDK-8057986: freetype code to get glyph outline does not handle initial control point properly
+ *
+ * Manual repro recipe:
+ * (cd test/java/awt/font/GlyphVector/ && javac GlyphVectorOutline.java && wget -q -O/tmp/msgothic.ttc https://browserlinux-jp.googlecode.com/files/msgothic.ttc && java GlyphVectorOutline /tmp/msgothic.ttc /tmp/katakana.png)
+ *
+ * Then examine the two rendered Japanese characters in the png file.
+ *
+ * Renders text to a PNG by
+ * 1. using the native Graphics2D#drawGlyphVector implementation
+ * 2. filling in the result of GlyphVector#getOutline
+ *
+ * Should be the same but is different for some CJK characters
+ * (e.g. Katakana character \u30AF).
+ *
+ * @author ikopylov@google.com (Igor Kopylov)
+ */
+public class GlyphVectorOutline {
+    public static void main(String[] args) throws Exception {
+        if (args.length != 2) {
+            throw new Error("Usage: java GlyphVectorOutline fontfile outputfile");
+        }
+        writeImage(new File(args[0]),
+                   new File(args[1]),
+                   "\u30AF");
+    }
+
+    public static void writeImage(File fontFile, File outputFile, String value) throws Exception {
+        BufferedImage image = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB);
+        Graphics2D g = image.createGraphics();
+        g.setColor(Color.WHITE);
+        g.fillRect(0, 0, image.getWidth(), image.getHeight());
+        g.setColor(Color.BLACK);
+
+        Font font = Font.createFont(Font.TRUETYPE_FONT, fontFile);
+        font = font.deriveFont(Font.PLAIN, 72f);
+        FontRenderContext frc = new FontRenderContext(null, false, false);
+        GlyphVector gv = font.createGlyphVector(frc, value);
+        g.drawGlyphVector(gv, 10, 80);
+        g.fill(gv.getOutline(10, 180));
+        ImageIO.write(image, "png", outputFile);
+    }
+
+    private static void drawString(Graphics2D g, Font font, String value, float x, float y) {
+        AttributedString str = new AttributedString(value);
+        str.addAttribute(TextAttribute.FOREGROUND, Color.BLACK);
+        str.addAttribute(TextAttribute.FONT, font);
+        FontRenderContext frc = new FontRenderContext(null, true, true);
+        TextLayout layout = new LineBreakMeasurer(str.getIterator(), frc).nextLayout(Integer.MAX_VALUE);
+        layout.draw(g, x, y);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/LFCaching/LFCachingTestCase.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.invoke.MethodHandle;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Abstract class for lambda forms caching testing.
+ *
+ * @author kshefov
+ */
+public abstract class LFCachingTestCase extends LambdaFormTestCase {
+
+    /**
+     * Constructor for lambda forms caching test case.
+     *
+     * @param testMethod A method from {@code j.l.i.MethodHandles} class that
+     * returns a {@code j.l.i.MethodHandle} instance.
+     */
+    protected LFCachingTestCase(TestMethods testMethod) {
+        super(testMethod);
+    }
+
+    /**
+     * Checks that the lambda forms of the two adapter method handles adapter1
+     * and adapter2 are the same.
+     *
+     * @param adapter1 First method handle.
+     * @param adapter2 Second method handle.
+     */
+    public void checkLFCaching(MethodHandle adapter1, MethodHandle adapter2) {
+        try {
+
+            if (!adapter1.type().equals(adapter2.type())) {
+                throw new Error("TESTBUG: Types of the two method handles are not the same");
+            }
+
+            Object lambdaForm0 = LambdaFormTestCase.INTERNAL_FORM.invoke(adapter1);
+            Object lambdaForm1 = LambdaFormTestCase.INTERNAL_FORM.invoke(adapter2);
+
+            if (lambdaForm0 == null || lambdaForm1 == null) {
+                throw new Error("Unexpected error: One or both lambda forms of the method handles are null");
+            }
+
+            if (lambdaForm0 != lambdaForm1) {
+                System.err.println("Lambda form 0 toString is:");
+                System.err.println(lambdaForm0);
+                System.err.println("Lambda form 1 toString is:");
+                System.err.println(lambdaForm1);
+                throw new AssertionError("Error: Lambda forms of the two method handles"
+                        + " are not the same. LF cahing does not work");
+            }
+        } catch (IllegalAccessException | IllegalArgumentException |
+                SecurityException | InvocationTargetException ex) {
+            throw new Error("Unexpected exception: ", ex);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/LFCaching/LFGarbageCollectedTest.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test LFGarbageCollectedTest
+ * @bug 8046703
+ * @summary Test verifies that lambda forms are garbage collected
+ * @author kshefov
+ * @ignore 8057020
+ * @library /lib/testlibrary/jsr292 /lib/testlibrary
+ * @build TestMethods
+ * @build LambdaFormTestCase
+ * @build LFGarbageCollectedTest
+ * @run main/othervm/timeout=600 -Djava.lang.invoke.MethodHandle.USE_LF_EDITOR=true -DtestLimit=150 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI LFGarbageCollectedTest
+ */
+
+import java.lang.invoke.MethodHandle;
+import java.lang.ref.PhantomReference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.Map;
+
+/**
+ * Lambda forms garbage collection test class.
+ */
+public final class LFGarbageCollectedTest extends LambdaFormTestCase {
+
+    /**
+     * Constructor for a lambda forms garbage collection test case.
+     *
+     * @param testMethod A method from {@code j.l.i.MethodHandles} class that
+     * returns a {@code j.l.i.MethodHandle} instance.
+     */
+    public LFGarbageCollectedTest(TestMethods testMethod) {
+        super(testMethod);
+    }
+
+    @Override
+    public void doTest() {
+        try {
+            Map<String, Object> data = getTestMethod().getTestCaseData();
+            MethodHandle adapter;
+            try {
+                adapter = getTestMethod().getTestCaseMH(data, TestMethods.Kind.ONE);
+            } catch (NoSuchMethodException ex) {
+                throw new Error("Unexpected exception: ", ex);
+            }
+            Object lambdaForm = LambdaFormTestCase.INTERNAL_FORM.invoke(adapter);
+            if (lambdaForm == null) {
+                throw new Error("Unexpected error: Lambda form of the method handle is null");
+            }
+            ReferenceQueue rq = new ReferenceQueue();
+            PhantomReference ph = new PhantomReference(lambdaForm, rq);
+            lambdaForm = null;
+            data = null;
+            adapter = null;
+            for (int i = 0; i < 1000 && !ph.isEnqueued(); i++) {
+                System.gc();
+            }
+            if (!ph.isEnqueued()) {
+                throw new AssertionError("Error: Lambda form is not garbage collected");
+            }
+        } catch (IllegalAccessException | IllegalArgumentException |
+                InvocationTargetException ex) {
+            throw new Error("Unexpected exception: ", ex);
+        }
+    }
+
+    /**
+     * Main routine for lambda forms garbage collection test.
+     *
+     * @param args Accepts no arguments.
+     */
+    public static void main(String[] args) {
+        // The "identity" and "constant" methods should be removed from this test,
+        // because their lambda forms are stored in a static filed and are not GC'ed.
+        // There can be only 5 such LFs for each method, so no memory leak happens.
+        EnumSet<TestMethods> testMethods = EnumSet.complementOf(EnumSet.of(TestMethods.IDENTITY, TestMethods.CONSTANT));
+        LambdaFormTestCase.runTests(LFGarbageCollectedTest::new, testMethods);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test LFMultiThreadCachingTest
+ * @bug 8046703
+ * @summary Test verifies that lambda forms are cached when run with multiple threads
+ * @author kshefov
+ * @library /lib/testlibrary/jsr292 /lib/testlibrary
+ * @build TestMethods
+ * @build LambdaFormTestCase
+ * @build LFCachingTestCase
+ * @build LFMultiThreadCachingTest
+ * @run main/othervm/timeout=300 -Djava.lang.invoke.MethodHandle.USE_LF_EDITOR=true LFMultiThreadCachingTest
+ */
+
+import java.lang.invoke.MethodHandle;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.CyclicBarrier;
+
+/**
+ * Multiple threaded lambda forms caching test class.
+ */
+public final class LFMultiThreadCachingTest extends LFCachingTestCase {
+    private static final TestMethods.Kind[] KINDS;
+    static {
+        EnumSet<TestMethods.Kind> set = EnumSet.complementOf(EnumSet.of(TestMethods.Kind.EXCEPT));
+        KINDS = set.toArray(new TestMethods.Kind[set.size()]);
+        if (KINDS.length < 2) {
+            throw new Error("TESTBUG: KINDS.length[" + KINDS.length + "] should be at least 2");
+        }
+    }
+    private static final int CORES = Math.max(KINDS.length, Runtime.getRuntime().availableProcessors());
+
+    /**
+     * Constructor a for multiple threaded lambda forms caching test case.
+     *
+     * @param testMethod A method from {@code j.l.i.MethodHandles} class that
+     * returns a {@code j.l.i.MethodHandle} instance.
+     */
+    public LFMultiThreadCachingTest(TestMethods testMethod) {
+        super(testMethod);
+    }
+
+    @Override
+    public void doTest() {
+        Map<String, Object> data = getTestMethod().getTestCaseData();
+        ConcurrentLinkedQueue<MethodHandle> adapters = new ConcurrentLinkedQueue<>();
+        CyclicBarrier begin = new CyclicBarrier(CORES);
+        CountDownLatch end = new CountDownLatch(CORES);
+        for (int i = 0; i < CORES; ++i) {
+            TestMethods.Kind kind = KINDS[i % KINDS.length];
+            new Thread(() -> {
+                try {
+                    begin.await();
+                    adapters.add(getTestMethod().getTestCaseMH(data, kind));
+                } catch (InterruptedException | BrokenBarrierException | IllegalAccessException | NoSuchMethodException ex) {
+                    throw new Error("Unexpected exception: ", ex);
+                } finally {
+                    end.countDown();
+                }
+            }).start();
+        }
+        try {
+            end.await();
+        } catch (InterruptedException ex) {
+            throw new Error("Unexpected exception: ", ex);
+        }
+        if (adapters.size() < CORES) {
+            throw new Error("adapters size[" + adapters.size() + "] is less than " + CORES);
+        }
+        MethodHandle prev = adapters.poll();
+        for (MethodHandle current : adapters) {
+            checkLFCaching(prev, current);
+            prev = current;
+        }
+    }
+
+    /**
+     * Main routine for multiple threaded lambda forms caching test.
+     *
+     * @param args Accepts no arguments.
+     */
+    public static void main(String[] args) {
+        LambdaFormTestCase.runTests(LFMultiThreadCachingTest::new, EnumSet.allOf(TestMethods.class));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test LFSingleThreadCachingTest
+ * @bug 8046703
+ * @summary Test verifies that lambda forms are cached when run with single thread
+ * @author kshefov
+ * @library /lib/testlibrary/jsr292 /lib/testlibrary
+ * @build TestMethods
+ * @build LambdaFormTestCase
+ * @build LFCachingTestCase
+ * @build LFSingleThreadCachingTest
+ * @run main/othervm/timeout=300 -Djava.lang.invoke.MethodHandle.USE_LF_EDITOR=true LFSingleThreadCachingTest
+ */
+
+import java.lang.invoke.MethodHandle;
+import java.util.EnumSet;
+import java.util.Map;
+
+/**
+ * Single threaded lambda forms caching test class.
+ */
+public final class LFSingleThreadCachingTest extends LFCachingTestCase {
+
+    /**
+     * Constructor for a single threaded lambda forms caching test case.
+     *
+     * @param testMethod A method from {@code j.l.i.MethodHandles} class that
+     * returns a {@code j.l.i.MethodHandle} instance.
+     */
+    public LFSingleThreadCachingTest(TestMethods testMethod) {
+        super(testMethod);
+    }
+
+    @Override
+    public void doTest() {
+        MethodHandle adapter1;
+        MethodHandle adapter2;
+        Map<String, Object> data = getTestMethod().getTestCaseData();
+        try {
+            adapter1 = getTestMethod().getTestCaseMH(data, TestMethods.Kind.ONE);
+            adapter2 = getTestMethod().getTestCaseMH(data, TestMethods.Kind.TWO);
+        } catch (NoSuchMethodException | IllegalAccessException ex) {
+            throw new Error("Unexpected exception: ", ex);
+        }
+        checkLFCaching(adapter1, adapter2);
+    }
+
+    /**
+     * Main routine for single threaded lambda forms caching test.
+     *
+     * @param args Accepts no arguments.
+     */
+    public static void main(String[] args) {
+        LambdaFormTestCase.runTests(LFSingleThreadCachingTest::new, EnumSet.allOf(TestMethods.class));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/LFCaching/LambdaFormTestCase.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.oracle.testlibrary.jsr292.Helper;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.function.Function;
+
+/**
+ * Lambda forms caching test case class. Contains all necessary test routines to
+ * test lambda forms caching in method handles returned by methods of
+ * MethodHandles class.
+ *
+ * @author kshefov
+ */
+public abstract class LambdaFormTestCase {
+
+    private final static String METHOD_HANDLE_CLASS_NAME = "java.lang.invoke.MethodHandle";
+    private final static String INTERNAL_FORM_METHOD_NAME = "internalForm";
+
+    /**
+     * Reflection link to {@code j.l.i.MethodHandle.internalForm} method. It is
+     * used to get a lambda form from a method handle.
+     */
+    protected final static Method INTERNAL_FORM;
+
+    static {
+        try {
+            Class mhClass = Class.forName(METHOD_HANDLE_CLASS_NAME);
+            INTERNAL_FORM = mhClass.getDeclaredMethod(INTERNAL_FORM_METHOD_NAME);
+            INTERNAL_FORM.setAccessible(true);
+        } catch (Exception ex) {
+            throw new Error("Unexpected exception: ", ex);
+        }
+    }
+
+    private final TestMethods testMethod;
+
+    /**
+     * Test case constructor. Generates test cases with random method types for
+     * given methods form {@code j.l.i.MethodHandles} class.
+     *
+     * @param testMethod A method from {@code j.l.i.MethodHandles} class which
+     * returns a {@code j.l.i.MethodHandle}.
+     */
+    protected LambdaFormTestCase(TestMethods testMethod) {
+        this.testMethod = testMethod;
+    }
+
+    public TestMethods getTestMethod() {
+        return testMethod;
+    }
+
+    /**
+     * Routine that executes a test case.
+     */
+    public abstract void doTest();
+
+    /**
+     * Runs a number of test cases defined by the size of testCases list.
+     *
+     * @param ctor constructor of LambdaFormCachingTest or its child classes
+     * object.
+     * @param testMethods list of test methods
+     */
+    public static void runTests(Function<TestMethods, LambdaFormTestCase> ctor, Collection<TestMethods> testMethods) {
+        boolean passed = true;
+        int testCounter = 0;
+        int failCounter = 0;
+        long iterations = Math.max(1, Helper.TEST_LIMIT / testMethods.size());
+        for (long i = 0; i < iterations; i++) {
+            System.err.println(String.format("Iteration %d:", i));
+            for (TestMethods testMethod : testMethods) {
+                LambdaFormTestCase testCase = ctor.apply(testMethod);
+                try {
+                    System.err.printf("Tested LF caching feature with MethodHandles.%s method.%n",
+                            testCase.getTestMethod().name);
+                    testCase.doTest();
+                    System.err.println("PASSED");
+                } catch (Throwable t) {
+                    t.printStackTrace();
+                    System.err.println("FAILED");
+                    passed = false;
+                    failCounter++;
+                }
+                testCounter++;
+            }
+        }
+        if (!passed) {
+            throw new Error(String.format("%d of %d test cases FAILED! %n"
+                    + "Rerun the test with the same \"-Dseed=\" option as in the log file!",
+                    failCounter, testCounter));
+        } else {
+            System.err.println(String.format("All %d test cases PASSED!", testCounter));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/LFCaching/TestMethods.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,698 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.oracle.testlibrary.jsr292.Helper;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Enumeration containing information about methods from
+ * {@code j.l.i.MethodHandles} class that are used for testing lambda forms
+ * caching.
+ *
+ * @author kshefov
+ */
+public enum TestMethods {
+
+    FOLD_ARGUMENTS("foldArguments") {
+                @Override
+                public Map<String, Object> getTestCaseData() {
+                    Map<String, Object> data = new HashMap<>();
+                    int desiredArity = Helper.RNG.nextInt(Helper.MAX_ARITY);
+                    MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
+                    data.put("mtTarget", mtTarget);
+                    // Arity after reducing because of long and double take 2 slots.
+                    int realArity = mtTarget.parameterCount();
+                    int modifierMHArgNum = Helper.RNG.nextInt(realArity + 1);
+                    data.put("modifierMHArgNum", modifierMHArgNum);
+                    Class<?> combinerReturnType;
+                    if (realArity == 0) {
+                        combinerReturnType = void.class;
+                    } else {
+                        combinerReturnType = Helper.RNG.nextBoolean() ? void.class : mtTarget.parameterType(0);
+                    }
+                    data.put("combinerReturnType", combinerReturnType);
+                    return data;
+                }
+
+                @Override
+                protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {
+                    MethodType mtTarget = (MethodType) data.get("mtTarget");
+                    Class<?> combinerReturnType = (Class) data.get("combinerReturnType");
+                    int modifierMHArgNum = (int) data.get("modifierMHArgNum");
+                    MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),
+                            mtTarget.parameterList(), kind);
+                    Class<?> rType = mtTarget.returnType();
+                    int combListStart = (combinerReturnType == void.class) ? 0 : 1;
+                    if (modifierMHArgNum < combListStart) {
+                        modifierMHArgNum = combListStart;
+                    }
+                    MethodHandle combiner = TestMethods.methodHandleGenerator(combinerReturnType,
+                            mtTarget.parameterList().subList(combListStart,
+                                    modifierMHArgNum), kind);
+                    return MethodHandles.foldArguments(target, combiner);
+                }
+            },
+    DROP_ARGUMENTS("dropArguments") {
+                @Override
+                public Map<String, Object> getTestCaseData() {
+                    Map<String, Object> data = new HashMap<>();
+                    int desiredArity = Helper.RNG.nextInt(Helper.MAX_ARITY);
+                    MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
+                    data.put("mtTarget", mtTarget);
+                    // Arity after reducing because of long and double take 2 slots.
+                    int realArity = mtTarget.parameterCount();
+                    int dropArgsPos = Helper.RNG.nextInt(realArity + 1);
+                    data.put("dropArgsPos", dropArgsPos);
+                    MethodType mtDropArgs = TestMethods.randomMethodTypeGenerator(
+                            Helper.RNG.nextInt(Helper.MAX_ARITY - realArity));
+                    data.put("mtDropArgs", mtDropArgs);
+                    return data;
+                }
+
+                @Override
+                protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {
+                    MethodType mtTarget = (MethodType) data.get("mtTarget");
+                    MethodType mtDropArgs = (MethodType) data.get("mtDropArgs");
+                    int dropArgsPos = (int) data.get("dropArgsPos");
+                    MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),
+                            mtTarget.parameterList(), kind);
+                    int mtTgtSlotsCount = TestMethods.argSlotsCount(mtTarget);
+                    int mtDASlotsCount = TestMethods.argSlotsCount(mtDropArgs);
+                    List<Class<?>> fakeParList;
+                    if (mtTgtSlotsCount + mtDASlotsCount > Helper.MAX_ARITY - 1) {
+                        fakeParList = TestMethods.reduceArgListToSlotsCount(mtDropArgs.parameterList(),
+                                Helper.MAX_ARITY - mtTgtSlotsCount - 1);
+                    } else {
+                        fakeParList = mtDropArgs.parameterList();
+                    }
+                    return MethodHandles.dropArguments(target, dropArgsPos, fakeParList);
+                }
+            },
+    EXPLICIT_CAST_ARGUMENTS("explicitCastArguments") {
+                @Override
+                public Map<String, Object> getTestCaseData() {
+                    Map<String, Object> data = new HashMap<>();
+                    int desiredArity = Helper.RNG.nextInt(Helper.MAX_ARITY / 2);
+                    MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
+                    data.put("mtTarget", mtTarget);
+                    // Arity after reducing because of long and double take 2 slots.
+                    int realArity = mtTarget.parameterCount();
+                    MethodType mtExcplCastArgs = TestMethods.randomMethodTypeGenerator(realArity);
+                    if (mtTarget.returnType() == void.class) {
+                        mtExcplCastArgs = MethodType.methodType(void.class,
+                                mtExcplCastArgs.parameterArray());
+                    }
+                    if (mtExcplCastArgs.returnType() == void.class) {
+                        mtExcplCastArgs = MethodType.methodType(mtTarget.returnType(),
+                                mtExcplCastArgs.parameterArray());
+                    }
+                    data.put("mtExcplCastArgs", mtExcplCastArgs);
+                    return data;
+                }
+
+                @Override
+                protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {
+                    MethodType mtTarget = (MethodType) data.get("mtTarget");
+                    MethodType mtExcplCastArgs = (MethodType) data.get("mtExcplCastArgs");
+                    MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),
+                            mtTarget.parameterList(), kind);
+                    return MethodHandles.explicitCastArguments(target, mtExcplCastArgs);
+                }
+            },
+    FILTER_ARGUMENTS("filterArguments") {
+                @Override
+                public Map<String, Object> getTestCaseData() {
+                    Map<String, Object> data = new HashMap<>();
+                    int desiredArity = Helper.RNG.nextInt(Helper.MAX_ARITY / 2);
+                    MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
+                    data.put("mtTarget", mtTarget);
+                    // Arity after reducing because of long and double take 2 slots.
+                    int realArity = mtTarget.parameterCount();
+                    int filterArgsPos = Helper.RNG.nextInt(realArity + 1);
+                    data.put("filterArgsPos", filterArgsPos);
+                    int filtersArgsArrayLength = Helper.RNG.nextInt(realArity + 1 - filterArgsPos);
+                    data.put("filtersArgsArrayLength", filtersArgsArrayLength);
+                    MethodType mtFilter = TestMethods.randomMethodTypeGenerator(filtersArgsArrayLength);
+                    data.put("mtFilter", mtFilter);
+                    return data;
+                }
+
+                @Override
+                protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {
+                    MethodType mtTarget = (MethodType) data.get("mtTarget");
+                    MethodType mtFilter = (MethodType) data.get("mtFilter");
+                    int filterArgsPos = (int) data.get("filterArgsPos");
+                    int filtersArgsArrayLength = (int) data.get("filtersArgsArrayLength");
+                    MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),
+                            mtTarget.parameterList(), kind);
+                    MethodHandle[] filters = new MethodHandle[filtersArgsArrayLength];
+                    for (int i = 0; i < filtersArgsArrayLength; i++) {
+                        filters[i] = TestMethods.filterGenerator(mtFilter.parameterType(i),
+                                mtTarget.parameterType(filterArgsPos + i), kind);
+                    }
+                    return MethodHandles.filterArguments(target, filterArgsPos, filters);
+                }
+            },
+    FILTER_RETURN_VALUE("filterReturnValue") {
+                @Override
+                public Map<String, Object> getTestCaseData() {
+                    Map<String, Object> data = new HashMap<>();
+                    int desiredArity = Helper.RNG.nextInt(Helper.MAX_ARITY);
+                    MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
+                    data.put("mtTarget", mtTarget);
+                    // Arity after reducing because of long and double take 2 slots.
+                    int realArity = mtTarget.parameterCount();
+                    int filterArgsPos = Helper.RNG.nextInt(realArity + 1);
+                    int filtersArgsArrayLength = Helper.RNG.nextInt(realArity + 1 - filterArgsPos);
+                    MethodType mtFilter = TestMethods.randomMethodTypeGenerator(filtersArgsArrayLength);
+                    data.put("mtFilter", mtFilter);
+                    return data;
+                }
+
+                @Override
+                protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {
+                    MethodType mtTarget = (MethodType) data.get("mtTarget");
+                    MethodType mtFilter = (MethodType) data.get("mtFilter");
+                    MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),
+                            mtTarget.parameterList(), kind);
+                    MethodHandle filter = TestMethods.filterGenerator(mtTarget.returnType(),
+                            mtFilter.returnType(), kind);
+                    return MethodHandles.filterReturnValue(target, filter);
+                }
+            },
+    INSERT_ARGUMENTS("insertArguments") {
+                @Override
+                public Map<String, Object> getTestCaseData() {
+                    Map<String, Object> data = new HashMap<>();
+                    int desiredArity = Helper.RNG.nextInt(Helper.MAX_ARITY);
+                    MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
+                    data.put("mtTarget", mtTarget);
+                    // Arity after reducing because of long and double take 2 slots.
+                    int realArity = mtTarget.parameterCount();
+                    int insertArgsPos = Helper.RNG.nextInt(realArity + 1);
+                    data.put("insertArgsPos", insertArgsPos);
+                    int insertArgsArrayLength = Helper.RNG.nextInt(realArity + 1 - insertArgsPos);
+                    MethodType mtInsertArgs = MethodType.methodType(void.class, mtTarget.parameterList()
+                            .subList(insertArgsPos, insertArgsPos + insertArgsArrayLength));
+                    data.put("mtInsertArgs", mtInsertArgs);
+                    return data;
+                }
+
+                @Override
+                protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {
+                    MethodType mtTarget = (MethodType) data.get("mtTarget");
+                    MethodType mtInsertArgs = (MethodType) data.get("mtInsertArgs");
+                    int insertArgsPos = (int) data.get("insertArgsPos");
+                    MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),
+                            mtTarget.parameterList(), kind);
+                    Object[] insertList = Helper.randomArgs(mtInsertArgs.parameterList());
+                    return MethodHandles.insertArguments(target, insertArgsPos, insertList);
+                }
+            },
+    PERMUTE_ARGUMENTS("permuteArguments") {
+                @Override
+                public Map<String, Object> getTestCaseData() {
+                    Map<String, Object> data = new HashMap<>();
+                    int desiredArity = Helper.RNG.nextInt(Helper.MAX_ARITY / 2);
+                    MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
+                    // Arity after reducing because of long and double take 2 slots.
+                    int realArity = mtTarget.parameterCount();
+                    int[] permuteArgsReorderArray = new int[realArity];
+                    int mtParmuteArgsNum = Helper.RNG.nextInt(Helper.MAX_ARITY);
+                    mtParmuteArgsNum = mtParmuteArgsNum == 0 ? 1 : mtParmuteArgsNum;
+                    MethodType mtPermuteArgs = TestMethods.randomMethodTypeGenerator(mtParmuteArgsNum);
+                    mtTarget = mtTarget.changeReturnType(mtPermuteArgs.returnType());
+                    for (int i = 0; i < realArity; i++) {
+                        int mtPermuteArgsParNum = Helper.RNG.nextInt(mtPermuteArgs.parameterCount());
+                        permuteArgsReorderArray[i] = mtPermuteArgsParNum;
+                        mtTarget = mtTarget.changeParameterType(
+                                i, mtPermuteArgs.parameterType(mtPermuteArgsParNum));
+                    }
+                    data.put("mtTarget", mtTarget);
+                    data.put("permuteArgsReorderArray", permuteArgsReorderArray);
+                    data.put("mtPermuteArgs", mtPermuteArgs);
+                    return data;
+                }
+
+                @Override
+                protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {
+                    MethodType mtTarget = (MethodType) data.get("mtTarget");
+                    MethodType mtPermuteArgs = (MethodType) data.get("mtPermuteArgs");
+                    int[] permuteArgsReorderArray = (int[]) data.get("permuteArgsReorderArray");
+                    MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),
+                            mtTarget.parameterList(), kind);
+                    return MethodHandles.permuteArguments(target, mtPermuteArgs, permuteArgsReorderArray);
+                }
+            },
+    THROW_EXCEPTION("throwException") {
+                @Override
+                public Map<String, Object> getTestCaseData() {
+                    Map<String, Object> data = new HashMap<>();
+                    int desiredArity = Helper.RNG.nextInt(Helper.MAX_ARITY);
+                    MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
+                    data.put("mtTarget", mtTarget);
+                    return data;
+                }
+
+                @Override
+                protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {
+                    MethodType mtTarget = (MethodType) data.get("mtTarget");
+                    Class<?> rType = mtTarget.returnType();
+                    return MethodHandles.throwException(rType, Exception.class
+                    );
+                }
+            },
+    GUARD_WITH_TEST("guardWithTest") {
+                @Override
+                public Map<String, Object> getTestCaseData() {
+                    Map<String, Object> data = new HashMap<>();
+                    int desiredArity = Helper.RNG.nextInt(Helper.MAX_ARITY);
+                    MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
+                    data.put("mtTarget", mtTarget);
+                    // Arity after reducing because of long and double take 2 slots.
+                    int realArity = mtTarget.parameterCount();
+                    int modifierMHArgNum = Helper.RNG.nextInt(realArity + 1);
+                    data.put("modifierMHArgNum", modifierMHArgNum);
+                    return data;
+                }
+
+                @Override
+                protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {
+                    MethodType mtTarget = (MethodType) data.get("mtTarget");
+                    int modifierMHArgNum = (int) data.get("modifierMHArgNum");
+                    TestMethods.Kind targetKind;
+                    TestMethods.Kind fallbackKind;
+                    if (kind.equals(TestMethods.Kind.ONE)) {
+                        targetKind = TestMethods.Kind.ONE;
+                        fallbackKind = TestMethods.Kind.TWO;
+                    } else {
+                        targetKind = TestMethods.Kind.TWO;
+                        fallbackKind = TestMethods.Kind.ONE;
+                    }
+                    MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),
+                            mtTarget.parameterList(), targetKind);
+                    MethodHandle fallback = TestMethods.methodHandleGenerator(mtTarget.returnType(),
+                            mtTarget.parameterList(), fallbackKind);
+                    MethodHandle test = TestMethods.methodHandleGenerator(boolean.class,
+                            mtTarget.parameterList().subList(0, modifierMHArgNum), kind);
+                    return MethodHandles.guardWithTest(test, target, fallback);
+                }
+            },
+    CATCH_EXCEPTION("catchException") {
+                @Override
+                public Map<String, Object> getTestCaseData() {
+                    Map<String, Object> data = new HashMap<>();
+                    int desiredArity = Helper.RNG.nextInt(Helper.MAX_ARITY);
+                    MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
+                    data.put("mtTarget", mtTarget);
+                    // Arity after reducing because of long and double take 2 slots.
+                    int realArity = mtTarget.parameterCount();
+                    int modifierMHArgNum = Helper.RNG.nextInt(realArity + 1);
+                    data.put("modifierMHArgNum", modifierMHArgNum);
+                    return data;
+                }
+
+                @Override
+                protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {
+                    MethodType mtTarget = (MethodType) data.get("mtTarget");
+                    int modifierMHArgNum = (int) data.get("modifierMHArgNum");
+                    MethodHandle target;
+                    if (kind.equals(TestMethods.Kind.ONE)) {
+                        target = TestMethods.methodHandleGenerator(mtTarget.returnType(),
+                                mtTarget.parameterList(), TestMethods.Kind.ONE);
+                    } else {
+                        target = TestMethods.methodHandleGenerator(mtTarget.returnType(),
+                                mtTarget.parameterList(), TestMethods.Kind.EXCEPT);
+                    }
+                    List<Class<?>> handlerParamList = new ArrayList<>(mtTarget.parameterCount() + 1);
+                    handlerParamList.add(Exception.class);
+                    handlerParamList.addAll(mtTarget.parameterList().subList(0, modifierMHArgNum));
+                    MethodHandle handler = TestMethods.methodHandleGenerator(
+                            mtTarget.returnType(), handlerParamList, TestMethods.Kind.TWO);
+                    return MethodHandles.catchException(target, Exception.class, handler);
+                }
+            },
+    INVOKER("invoker") {
+                @Override
+                public Map<String, Object> getTestCaseData() {
+                    Map<String, Object> data = new HashMap<>();
+                    int desiredArity = Helper.RNG.nextInt(Helper.MAX_ARITY);
+                    MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
+                    data.put("mtTarget", mtTarget);
+                    return data;
+                }
+
+                @Override
+                protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {
+                    MethodType mtTarget = (MethodType) data.get("mtTarget");
+                    return MethodHandles.invoker(mtTarget);
+                }
+            },
+    EXACT_INVOKER("exactInvoker") {
+                @Override
+                public Map<String, Object> getTestCaseData() {
+                    Map<String, Object> data = new HashMap<>();
+                    int desiredArity = Helper.RNG.nextInt(Helper.MAX_ARITY);
+                    MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
+                    data.put("mtTarget", mtTarget);
+                    return data;
+                }
+
+                @Override
+                protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {
+                    MethodType mtTarget = (MethodType) data.get("mtTarget");
+                    return MethodHandles.exactInvoker(mtTarget);
+                }
+            },
+    SPREAD_INVOKER("spreadInvoker") {
+                @Override
+                public Map<String, Object> getTestCaseData() {
+                    Map<String, Object> data = new HashMap<>();
+                    int desiredArity = Helper.RNG.nextInt(Helper.MAX_ARITY);
+                    MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
+                    data.put("mtTarget", mtTarget);
+                    // Arity after reducing because of long and double take 2 slots.
+                    int realArity = mtTarget.parameterCount();
+                    int modifierMHArgNum = Helper.RNG.nextInt(realArity + 1);
+                    data.put("modifierMHArgNum", modifierMHArgNum);
+                    return data;
+                }
+
+                @Override
+                protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {
+                    MethodType mtTarget = (MethodType) data.get("mtTarget");
+                    int modifierMHArgNum = (int) data.get("modifierMHArgNum");
+                    return MethodHandles.spreadInvoker(mtTarget, modifierMHArgNum);
+                }
+            },
+    ARRAY_ELEMENT_GETTER("arrayElementGetter") {
+                @Override
+                public Map<String, Object> getTestCaseData() {
+                    Map<String, Object> data = new HashMap<>();
+                    int desiredArity = Helper.RNG.nextInt(Helper.MAX_ARITY);
+                    MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
+                    data.put("mtTarget", mtTarget);
+                    return data;
+                }
+
+                @Override
+                protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {
+                    MethodType mtTarget = (MethodType) data.get("mtTarget");
+                    Class<?> rType = mtTarget.returnType();
+                    if (rType == void.class) {
+                        rType = Object.class;
+                    }
+                    return MethodHandles.arrayElementGetter(Array.newInstance(rType, 2).getClass());
+                }
+            },
+    ARRAY_ELEMENT_SETTER("arrayElementSetter") {
+                @Override
+                public Map<String, Object> getTestCaseData() {
+                    Map<String, Object> data = new HashMap<>();
+                    int desiredArity = Helper.RNG.nextInt(Helper.MAX_ARITY);
+                    MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
+                    data.put("mtTarget", mtTarget);
+                    return data;
+                }
+
+                @Override
+                protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {
+                    MethodType mtTarget = (MethodType) data.get("mtTarget");
+                    Class<?> rType = mtTarget.returnType();
+                    if (rType == void.class) {
+                        rType = Object.class;
+                    }
+                    return MethodHandles.arrayElementSetter(Array.newInstance(rType, 2).getClass());
+                }
+            },
+    CONSTANT("constant") {
+                @Override
+                public Map<String, Object> getTestCaseData() {
+                    Map<String, Object> data = new HashMap<>();
+                    int desiredArity = Helper.RNG.nextInt(Helper.MAX_ARITY);
+                    MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
+                    data.put("mtTarget", mtTarget);
+                    return data;
+                }
+
+                @Override
+                protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {
+                    MethodType mtTarget = (MethodType) data.get("mtTarget");
+                    Class<?> rType = mtTarget.returnType();
+                    if (rType == void.class) {
+                        rType = Object.class;
+                    }
+                    if (rType.equals(boolean.class)) {
+                        // There should be the same return values because for default values there are special "zero" forms
+                        return MethodHandles.constant(rType, true);
+                    } else {
+                        return MethodHandles.constant(rType, kind.getValue(rType));
+                    }
+                }
+            },
+    IDENTITY("identity") {
+                @Override
+                public Map<String, Object> getTestCaseData() {
+                    Map<String, Object> data = new HashMap<>();
+                    int desiredArity = Helper.RNG.nextInt(Helper.MAX_ARITY);
+                    MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);
+                    data.put("mtTarget", mtTarget);
+                    return data;
+                }
+
+                @Override
+                protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {
+                    MethodType mtTarget = (MethodType) data.get("mtTarget");
+                    Class<?> rType = mtTarget.returnType();
+                    if (rType == void.class) {
+                        rType = Object.class;
+                    }
+                    return MethodHandles.identity(rType);
+                }
+            };
+
+    /**
+     * Test method's name.
+     */
+    public final String name;
+
+    private TestMethods(String name) {
+        this.name = name;
+    }
+
+    protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {
+        throw new UnsupportedOperationException("TESTBUG: getMH method is not implemented for test method " + this);
+    }
+
+    /**
+     * Creates an adapter method handle depending on a test method from
+     * MethodHandles class. Adapter is what is returned by the test method. This
+     * method is able to create two kinds of adapters, their type will be the
+     * same, but return values are different.
+     *
+     * @param data a Map containing data to create a method handle, can be
+     * obtained by {@link #getTestCaseData} method
+     * @param kind defines whether adapter ONE or adapter TWO will be
+     * initialized. Should be equal to TestMethods.Kind.ONE or
+     * TestMethods.Kind.TWO
+     * @return Method handle adapter that behaves according to
+     * TestMethods.Kind.ONE or TestMethods.Kind.TWO
+     * @throws java.lang.NoSuchMethodException
+     * @throws java.lang.IllegalAccessException
+     */
+    public MethodHandle getTestCaseMH(Map<String, Object> data, TestMethods.Kind kind)
+            throws NoSuchMethodException, IllegalAccessException {
+        if (data == null) {
+            throw new Error(String.format("TESTBUG: Data for test method %s is not prepared",
+                    this.name));
+        }
+        if (!kind.equals(TestMethods.Kind.ONE) && !kind.equals(TestMethods.Kind.TWO)) {
+            throw new IllegalArgumentException("TESTBUG: Wrong \"kind\" (" + kind
+                    + ") arg to getTestCaseMH function."
+                    + " Should be Kind.ONE or Kind.TWO");
+        }
+        return getMH(data, kind);
+    }
+
+    /**
+     * Returns a data Map needed for {@link #getTestCaseMH} method.
+     *
+     * @return data Map needed for {@link #getTestCaseMH} method
+     */
+    public Map<String, Object> getTestCaseData() {
+        throw new UnsupportedOperationException(
+                "TESTBUG: getTestCaseData method is not implemented for test method " + this);
+    }
+
+    /**
+     * Enumeration used in methodHandleGenerator to define whether a MH returned
+     * by this method returns "2" in different type representations, "4", or
+     * throw an Exception.
+     */
+    public static enum Kind {
+
+        ONE(2),
+        TWO(4),
+        EXCEPT(0);
+
+        private final int value;
+
+        private Object getValue(Class<?> cl) {
+            return Helper.castToWrapper(value, cl);
+        }
+
+        private MethodHandle getBasicMH(Class<?> rType) throws NoSuchMethodException, IllegalAccessException {
+            MethodHandle result = null;
+            switch (this) {
+                case ONE:
+                case TWO:
+                    if (rType.equals(void.class)) {
+                        result = MethodHandles.lookup().findVirtual(Kind.class, "returnVoid", MethodType.methodType(void.class));
+                        result = MethodHandles.insertArguments(result, 0, this);
+                    } else {
+                        result = MethodHandles.constant(rType, getValue(rType));
+                    }
+                    break;
+                case EXCEPT:
+                    result = MethodHandles.throwException(rType, Exception.class);
+                    result = MethodHandles.insertArguments(result, 0, new Exception());
+                    break;
+            }
+            return result;
+        }
+
+        private void returnVoid() {
+        }
+
+        private Kind(int value) {
+            this.value = value;
+        }
+    }
+
+    /**
+     * Routine used to obtain a randomly generated method type.
+     *
+     * @param arity Arity of returned method type.
+     * @return MethodType generated randomly.
+     */
+    private static MethodType randomMethodTypeGenerator(int arity) {
+        final Class<?>[] CLASSES = {
+            Object.class,
+            int.class,
+            boolean.class,
+            byte.class,
+            short.class,
+            char.class,
+            long.class,
+            float.class,
+            double.class
+        };
+        if (arity > Helper.MAX_ARITY) {
+            throw new IllegalArgumentException(
+                    String.format("Arity should not exceed %d!", Helper.MAX_ARITY));
+        }
+        List<Class<?>> list = Helper.randomClasses(CLASSES, arity);
+        list = Helper.getParams(list, false, arity);
+        int i = Helper.RNG.nextInt(CLASSES.length + 1);
+        Class<?> rtype = i == CLASSES.length ? void.class : CLASSES[i];
+        return MethodType.methodType(rtype, list);
+    }
+
+    /**
+     * Routine used to obtain a method handles of a given type an kind (return
+     * value).
+     *
+     * @param returnType Type of MH return value.
+     * @param argTypes Types of MH args.
+     * @param kind Defines whether the obtained MH returns "1" or "2".
+     * @return Method handle of the given type.
+     * @throws NoSuchMethodException
+     * @throws IllegalAccessException
+     */
+    private static MethodHandle methodHandleGenerator(Class<?> returnType,
+            List<Class<?>> argTypes, TestMethods.Kind kind)
+            throws NoSuchMethodException, IllegalAccessException {
+        MethodHandle result;
+        result = kind.getBasicMH(returnType);
+        return Helper.addTrailingArgs(result, argTypes.size(), argTypes);
+    }
+
+    /**
+     * Routine that generates filter method handles to test
+     * MethodHandles.filterArguments method.
+     *
+     * @param inputType Filter's argument type.
+     * @param returnType Filter's return type.
+     * @param kind Filter's return value definer.
+     * @return A filter method handle, that takes one argument.
+     * @throws NoSuchMethodException
+     * @throws IllegalAccessException
+     */
+    private static MethodHandle filterGenerator(Class<?> inputType, Class<?> returnType,
+            TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {
+        MethodHandle tmpMH = kind.getBasicMH(returnType);
+        if (inputType.equals(void.class)) {
+            return tmpMH;
+        }
+        ArrayList<Class<?>> inputTypeList = new ArrayList<>(1);
+        inputTypeList.add(inputType);
+        return Helper.addTrailingArgs(tmpMH, 1, inputTypeList);
+    }
+
+    private static int argSlotsCount(MethodType mt) {
+        int result = 0;
+        for (Class cl : mt.parameterArray()) {
+            if (cl.equals(long.class) || cl.equals(double.class)) {
+                result += 2;
+            } else {
+                result++;
+            }
+        }
+        return result;
+    }
+
+    private static List<Class<?>> reduceArgListToSlotsCount(List<Class<?>> list,
+            int desiredSlotCount) {
+        List<Class<?>> result = new ArrayList<>(desiredSlotCount);
+        int count = 0;
+        for (Class<?> cl : list) {
+            if (count >= desiredSlotCount) {
+                break;
+            }
+            if (cl.equals(long.class) || cl.equals(double.class)) {
+                count += 2;
+            } else {
+                count++;
+            }
+            result.add(cl);
+        }
+        return result;
+    }
+}
--- a/jdk/test/java/lang/invoke/MethodHandles/CatchExceptionTest.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/test/java/lang/invoke/MethodHandles/CatchExceptionTest.java	Wed Jul 05 20:01:50 2017 +0200
@@ -42,6 +42,7 @@
 public class CatchExceptionTest {
     private static final List<Class<?>> ARGS_CLASSES;
     protected static final int MAX_ARITY = Helper.MAX_ARITY - 1;
+
     static {
         Class<?> classes[] = {
                 Object.class,
@@ -52,11 +53,8 @@
                 double[].class,
                 String.class,
         };
-        List<Class<?>> list = new ArrayList<>(MAX_ARITY);
-        for (int i = 0; i < MAX_ARITY; ++i) {
-            list.add(classes[Helper.RNG.nextInt(classes.length)]);
-        }
-        ARGS_CLASSES = Collections.unmodifiableList(list);
+        ARGS_CLASSES = Collections.unmodifiableList(
+                Helper.randomClasses(classes, MAX_ARITY));
     }
 
     private final TestCase testCase;
@@ -66,7 +64,6 @@
     private int dropped;
     private MethodHandle thrower;
 
-
     public CatchExceptionTest(TestCase testCase, final boolean isVararg, final int argsCount,
             final int catchDrops) {
         this.testCase = testCase;
@@ -107,37 +104,7 @@
     }
 
     private List<Class<?>> getThrowerParams(boolean isVararg, int argsCount) {
-        boolean unmodifiable = true;
-        List<Class<?>> classes;
-        classes = ARGS_CLASSES.subList(0,
-                Math.min(argsCount, (MAX_ARITY / 2) - 1));
-        int extra = 0;
-        if (argsCount >= MAX_ARITY / 2) {
-            classes = new ArrayList<>(classes);
-            unmodifiable = false;
-            extra = (int) classes.stream().filter(Helper::isDoubleCost).count();
-            int i = classes.size();
-            while (classes.size() + extra < argsCount) {
-                Class<?> aClass = ARGS_CLASSES.get(i);
-                if (Helper.isDoubleCost(aClass)) {
-                    ++extra;
-                    if (classes.size() + extra >= argsCount) {
-                        break;
-                    }
-                }
-                classes.add(aClass);
-            }
-        }
-        if (isVararg && classes.size() > 0) {
-            if (unmodifiable) {
-                classes = new ArrayList<>(classes);
-            }
-            int last = classes.size() - 1;
-            Class<?> aClass = classes.get(classes.size() - 1);
-            aClass = Array.newInstance(aClass, 2).getClass();
-            classes.set(last, aClass);
-        }
-        return classes;
+        return Helper.getParams(ARGS_CLASSES, isVararg, argsCount);
     }
 
 
--- a/jdk/test/java/lang/invoke/lambda/LUtils.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/test/java/lang/invoke/lambda/LUtils.java	Wed Jul 05 20:01:50 2017 +0200
@@ -37,8 +37,6 @@
  * support infrastructure to invoke a java class from the command line
  */
 class LUtils {
-    static final sun.tools.jar.Main jarTool =
-            new sun.tools.jar.Main(System.out, System.err, "jar-tool");
     static final com.sun.tools.javac.Main javac =
             new com.sun.tools.javac.Main();
     static final File cwd = new File(".").getAbsoluteFile();
@@ -49,6 +47,10 @@
     static final File JAVA_BIN_FILE = new File(JAVAHOME, "bin");
     static final File JAVA_CMD = new File(JAVA_BIN_FILE,
             isWindows ? "java.exe" : "java");
+    static final File JAR_BIN_FILE =
+            new File(new File(JAVAHOME).getParentFile(), "bin");
+    static final File JAR_CMD = new File(JAR_BIN_FILE,
+            isWindows ? "jar.exe" : "jar");
 
     protected LUtils() {
     }
--- a/jdk/test/java/lang/invoke/lambda/LambdaAccessControlDoPrivilegedTest.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/test/java/lang/invoke/lambda/LambdaAccessControlDoPrivilegedTest.java	Wed Jul 05 20:01:50 2017 +0200
@@ -67,12 +67,17 @@
         compile(javacArgs);
         File jarFile = new File("foo.jar");
         String[] jargs = {"cvf", jarFile.getName(), doprivClass.getName()};
-        jarTool.run(jargs);
+        TestResult tr = doExec(JAR_CMD.getAbsolutePath(),
+                                "cvf", jarFile.getName(),
+                                doprivClass.getName());
+        if (tr.exitValue != 0){
+            throw new RuntimeException(tr.toString());
+        }
         doprivJava.delete();
         doprivClass.delete();
-        TestResult tr = doExec(JAVA_CMD.getAbsolutePath(),
-                               "-Xbootclasspath/p:foo.jar",
-                               "-cp", ".", "Bar");
+        tr = doExec(JAVA_CMD.getAbsolutePath(),
+                    "-Xbootclasspath/p:foo.jar",
+                    "-cp", ".", "Bar");
         tr.assertZero("testDoPrivileged fails");
         barJava.delete();
         barClass.delete();
--- a/jdk/test/java/math/BigDecimal/ZeroScalingTests.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/test/java/math/BigDecimal/ZeroScalingTests.java	Wed Jul 05 20:01:50 2017 +0200
@@ -23,8 +23,10 @@
 
 /*
  * @test
- * @bug 4902952 4905407 4916149
- * @summary Tests that the scale of zero is propagated properly and has the proper effect.
+ * @bug 4902952 4905407 4916149 8057793
+ * @summary Tests that the scale of zero is propagated properly and has the
+ * proper effect and that setting the scale to zero does not mutate the
+ * BigDecimal.
  * @author Joseph D. Darcy
  */
 
@@ -445,6 +447,16 @@
         return failures;
     }
 
+    static int setScaleDoesNotMutateTest() {
+        BigDecimal total = new BigDecimal("258815507198903607775511093103396443816569106750031264155319238473795838680758514810110764742309284477206138527975952150289602995045050194333030191178778772026538699925775139201970526695485362661420908248887297829319881475178467494779683293036572059595504702727301324759997409522995072582369210284334718757260859794972695026582432867589093687280300148141501712013226636373167978223780290547640482160818746599330924736802844173226042389174403401903999447463440670236056324929325189403433689"
+                + ".426167432065785331444814035799717606745777287606858873045971898862329763544687891847664736523584843544347118836628373041412918374550458884706686730726101338872517021688769782894793734049819222924171842793485919753186993388451909096042127903835765393729547730953942175461146061715108701615615142134282261293656760570061554783195726716403304101469782303957325142638493327692352838806741611887655695029948975509680496573999174402058593454203190963443179532640446352828089016874853634851387762579319853267317320515941105912189838719919259277721994880193541634872882180184303434360412344059435559680494807415573269199203376126242271766939666939316648575065702750502798973418978204972336924254702551350654650573582614211506856383897692911422458286912085339575875324832979140870119455620532272318122103640233069115700020760625493816902806241630788230268031695140687964931377988962507263990468276009750998066442971308866347136022907166625330623130307555914930120150437900510530537258665172619821272937026713977709974434967165159545592482710663639966781678268622620229577009317698254134914742098420792313931843709810905414336383757407675429663714210967924767434203021205270369316797752411974617662200898086335322218191674846795163102021505555508444216708745911194321674887527227200297039471799580744303346354057273540730643842091810899490590914195225087593013834388801018488174855060306804024894292757613618190472234110859436472645203753139820658279559340251226992556744343475086923568365637919479462424794554522865559888240039662899509652221329892034706445253487898044421278283079233226845124525434586324657471286953226255430662125870993375281512713207125720748163498642795960457639954616530163959004770092547297392499137383176609646505351001304840762905826237024982330597805063521162285806541220110524989649256399233792799406995068469271941269511818994954109392839548141262324660472253632382325038836831429045617036015122388070240133760858500132713255407855625837956886349324981003917084922808187223285051144454915441134217743066575863563572152133978905444998209075763950909784148142018992367290485890072303179512881131769414783097454103103347826517701720263541869335631166977965013552647906729408522950996105479525445916501155305220090853891226367184989434453290788068397817927893708837722255115237672194162924260945492012622891770365546831236789867922136747819364833843397165107825773447549885351449899330007200651144003961228091210630807333236718793283427788965479074476288255387824982443633190938302785760754436525586544523339170400053128503337395428393881357669568532722167493096151221381017320147344991331421789379785964440840684363041795410525097564979585773948558651896834067324427900848255265001498890329859444233861478388742393060996236783742654761350763876989363052609107226398858310051497856931093693697981165801539060516895227818925342535261227134364063673285588256280386915163875872231395348293505967057794409379709079685798908660258077792158532257603211711587587586356431658240229896344639704");
+        if (total.setScale(0, RoundingMode.DOWN).equals(total.setScale(0, RoundingMode.DOWN))) {
+            return 0;
+        } else {
+            return 1;
+        }
+    }
+
     public static void main(String argv[]) {
         int failures = 0;
 
@@ -455,6 +467,7 @@
         failures += setScaleTests();
         failures += toEngineeringStringTests();
         failures += ulpTests();
+        failures += setScaleDoesNotMutateTest();
 
         if (failures > 0 ) {
             throw new RuntimeException("Incurred " + failures + " failures" +
--- a/jdk/test/java/math/BigInteger/BigIntegerTest.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/test/java/math/BigInteger/BigIntegerTest.java	Wed Jul 05 20:01:50 2017 +0200
@@ -71,6 +71,7 @@
     static final int BITS_TOOM_COOK_SQUARE = 6912;
     static final int BITS_SCHOENHAGE_BASE = 640;
     static final int BITS_BURNIKEL_ZIEGLER = 2560;
+    static final int BITS_BURNIKEL_ZIEGLER_OFFSET = 1280;
 
     static final int ORDER_SMALL = 60;
     static final int ORDER_MEDIUM = 100;
@@ -288,19 +289,19 @@
      * where {@code abs(u) > abs(v)} and {@code a > b && b > 0}, then if
      * {@code w/z = q1*z + r1} and {@code u/v = q2*v + r2}, then
      * {@code q1 = q2*pow(2,a-b)} and {@code r1 = r2*pow(2,b)}.  The test
-     * ensures that {@code v} is just under the B-Z threshold and that {@code w}
-     * and {@code z} are both over the threshold.  This implies that {@code u/v}
-     * uses the standard division algorithm and {@code w/z} uses the B-Z
-     * algorithm.  The results of the two algorithms are then compared using the
-     * observation described in the foregoing and if they are not equal a
-     * failure is logged.
+     * ensures that {@code v} is just under the B-Z threshold, that {@code z} is
+     * over the threshold and {@code w} is much larger than {@code z}. This
+     * implies that {@code u/v} uses the standard division algorithm and
+     * {@code w/z} uses the B-Z algorithm.  The results of the two algorithms
+     * are then compared using the observation described in the foregoing and
+     * if they are not equal a failure is logged.
      */
     public static void divideLarge() {
         int failCount = 0;
 
-        BigInteger base = BigInteger.ONE.shiftLeft(BITS_BURNIKEL_ZIEGLER - 33);
+        BigInteger base = BigInteger.ONE.shiftLeft(BITS_BURNIKEL_ZIEGLER + BITS_BURNIKEL_ZIEGLER_OFFSET - 33);
         for (int i=0; i<SIZE; i++) {
-            BigInteger addend = new BigInteger(BITS_BURNIKEL_ZIEGLER - 34, rnd);
+            BigInteger addend = new BigInteger(BITS_BURNIKEL_ZIEGLER + BITS_BURNIKEL_ZIEGLER_OFFSET - 34, rnd);
             BigInteger v = base.add(addend);
 
             BigInteger u = v.multiply(BigInteger.valueOf(2 + rnd.nextInt(Short.MAX_VALUE - 1)));
@@ -312,14 +313,14 @@
                 v = v.negate();
             }
 
-            int a = 17 + rnd.nextInt(16);
+            int a = BITS_BURNIKEL_ZIEGLER_OFFSET + rnd.nextInt(16);
             int b = 1 + rnd.nextInt(16);
-            BigInteger w = u.multiply(BigInteger.valueOf(1L << a));
-            BigInteger z = v.multiply(BigInteger.valueOf(1L << b));
+            BigInteger w = u.multiply(BigInteger.ONE.shiftLeft(a));
+            BigInteger z = v.multiply(BigInteger.ONE.shiftLeft(b));
 
             BigInteger[] divideResult = u.divideAndRemainder(v);
-            divideResult[0] = divideResult[0].multiply(BigInteger.valueOf(1L << (a - b)));
-            divideResult[1] = divideResult[1].multiply(BigInteger.valueOf(1L << b));
+            divideResult[0] = divideResult[0].multiply(BigInteger.ONE.shiftLeft(a - b));
+            divideResult[1] = divideResult[1].multiply(BigInteger.ONE.shiftLeft(b));
             BigInteger[] bzResult = w.divideAndRemainder(z);
 
             if (divideResult[0].compareTo(bzResult[0]) != 0 ||
--- a/jdk/test/java/net/NetworkInterface/Test.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/test/java/net/NetworkInterface/Test.java	Wed Jul 05 20:01:50 2017 +0200
@@ -22,7 +22,9 @@
  */
 
 /* @test
- * @bug 4405354 6594296
+ * @bug 4405354 6594296 8058216
+ * @run main Test
+ * @run main/othervm -Djava.net.preferIPv4Stack=true Test
  * @summary Basic tests for NetworkInterface
  */
 import java.net.NetworkInterface;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/channels/FileChannel/BlockDeviceSize.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 8054029
+ * @summary Block devices should not report size=0 on Linux
+ */
+
+import java.io.RandomAccessFile;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.channels.FileChannel;
+import java.nio.file.AccessDeniedException;
+import java.nio.file.NoSuchFileException;
+import static java.nio.file.StandardOpenOption.*;
+
+
+public class BlockDeviceSize {
+    private static final String BLK_FNAME = "/dev/sda1";
+    private static final Path BLK_PATH = Paths.get(BLK_FNAME);
+
+    public static void main(String[] args) throws Throwable {
+        try (FileChannel ch = FileChannel.open(BLK_PATH, READ);
+             RandomAccessFile file = new RandomAccessFile(BLK_FNAME, "r")) {
+
+            long size1 = ch.size();
+            long size2 = file.length();
+            if (size1 != size2) {
+                throw new RuntimeException("size differs when retrieved" +
+                        " in different ways: " + size1 + " != " + size2);
+            }
+            System.out.println("OK");
+
+        } catch (NoSuchFileException nsfe) {
+            System.err.println("File " + BLK_FNAME + " not found." +
+                    " Skipping test");
+        } catch (AccessDeniedException ade) {
+            System.err.println("Access to " + BLK_FNAME + " is denied." +
+                    " Run test as root.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/AccessController/LimitedDoPrivilegedWithNullPerms.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2013,2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8050281
+ * @summary Test that NullPointerException is thrown if any element of perms
+ * parameter is null
+ * @run testng LimitedDoPrivilegedWithNullPerms
+ */
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.Permission;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.PropertyPermission;
+import org.testng.annotations.Test;
+
+public class LimitedDoPrivilegedWithNullPerms {
+
+    AccessControlContext acc = AccessController.getContext();
+    Permission p1 = new PropertyPermission("user.name", "read");
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void test1() {
+        AccessController.doPrivileged(
+                (PrivilegedAction<Void>) () -> null, acc, null);
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void test2() {
+        AccessController.doPrivileged(
+                (PrivilegedAction<Void>) () -> null, acc, p1, null);
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void test3() {
+        AccessController.doPrivilegedWithCombiner(
+                (PrivilegedAction<Void>) () -> null, acc, null);
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void test4() {
+        AccessController.doPrivilegedWithCombiner(
+                (PrivilegedAction<Void>) () -> null, acc, p1, null);
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void test5() throws PrivilegedActionException {
+        AccessController.doPrivileged(
+                (PrivilegedExceptionAction<Void>) () -> null,
+                acc, null);
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void test6() throws PrivilegedActionException {
+        AccessController.doPrivileged(
+                (PrivilegedExceptionAction<Void>) () -> null,
+                acc, p1, null);
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void test7() throws PrivilegedActionException {
+        AccessController.doPrivilegedWithCombiner(
+                (PrivilegedExceptionAction<Void>) () -> null,
+                acc, null);
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void test8() throws PrivilegedActionException {
+        AccessController.doPrivilegedWithCombiner(
+                (PrivilegedExceptionAction<Void>) () -> null,
+                acc, p1, null);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/AccessController/LimitedDoPrivilegedWithThread.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2013,2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8050281
+ * @summary Test limited doprivileged action with trhead calls.
+ * @run main/othervm/policy=policy LimitedDoPrivilegedWithThread
+ */
+import java.io.FilePermission;
+import java.security.AccessControlContext;
+import java.security.AccessControlException;
+import java.security.AccessController;
+import java.security.Permission;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+import java.util.PropertyPermission;
+
+public class LimitedDoPrivilegedWithThread {
+
+    private static final Permission PROPERTYPERM
+            = new PropertyPermission("user.name", "read");
+    private static final Permission FILEPERM
+            = new FilePermission("*", "read");
+    private static final AccessControlContext ACC
+            = new AccessControlContext(
+                    new ProtectionDomain[]{new ProtectionDomain(null, null)});
+
+    public static void main(String args[]) {
+        //parent thread without any permission
+        AccessController.doPrivileged(
+                (PrivilegedAction) () -> {
+                    Thread ct = new Thread(
+                            new ChildThread(PROPERTYPERM, FILEPERM));
+                    ct.start();
+                    try {
+                        ct.join();
+                    } catch (InterruptedException ie) {
+                        Thread.currentThread().interrupt();
+                        ie.printStackTrace();
+                        throw new RuntimeException("Unexpected InterruptedException");
+                    }
+                    return null;
+                }, ACC);
+    }
+}
+
+class ChildThread implements Runnable {
+
+    private final Permission P1;
+    private final Permission P2;
+    private boolean catchACE = false;
+
+    public ChildThread(Permission p1, Permission p2) {
+        this.P1 = p1;
+        this.P2 = p2;
+    }
+
+    @Override
+    public void run() {
+        //Verified that child thread has permission p1,
+        runTest(null, P1, false, 1);
+        //Verified that child thread inherits parent thread's access control context
+        AccessControlContext childAcc = AccessController.getContext();
+        runTest(childAcc, P1, true, 2);
+        //Verified that we can give permision p2 to limit the "privilege" of the
+        //class calling doprivileged action, stack walk will continue
+        runTest(null, P2, true, 3);
+
+    }
+
+    public void runTest(AccessControlContext acc, Permission perm,
+            boolean expectACE, int id) {
+
+        AccessController.doPrivileged(
+                (PrivilegedAction) () -> {
+                    try {
+                        AccessController.getContext().checkPermission(P1);
+                    } catch (AccessControlException ace) {
+                        catchACE = true;
+                    }
+                    if (catchACE ^ expectACE) {
+                        throw new RuntimeException("test" + id + " failed");
+                    }
+                    return null;
+                }, acc, perm);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/AccessController/policy	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,4 @@
+grant{
+	permission java.util.PropertyPermission "user.name", "read";
+ 	permission java.io.FilePermission "*", "read";
+};
--- a/jdk/test/java/sql/test/sql/TimestampTests.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/test/java/sql/test/sql/TimestampTests.java	Wed Jul 05 20:01:50 2017 +0200
@@ -27,14 +27,40 @@
 import java.sql.Timestamp;
 import java.time.Instant;
 import java.time.LocalDateTime;
+import java.time.ZoneId;
 import java.util.Calendar;
+import java.util.TimeZone;
 import static org.testng.Assert.*;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 import util.BaseTest;
 
 public class TimestampTests extends BaseTest {
 
+    private static TimeZone defaultTimeZone = null;
+
+    /*
+     * Need to set and use a custom TimeZone which does not
+     * observe daylight savings time for this test.
+     */
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+        defaultTimeZone = TimeZone.getDefault();
+        TimeZone tzone = TimeZone.getTimeZone("GMT+01");
+        assertFalse(tzone.observesDaylightTime());
+        TimeZone.setDefault(tzone);
+    }
+
+    /*
+     * Conservatively reset the default time zone after test.
+     */
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+        TimeZone.setDefault(defaultTimeZone);
+    }
+
     /*
      * Validate an IllegalArgumentException is thrown for an invalid Timestamp
      */
@@ -610,6 +636,12 @@
                 "Error with Nanos");
     }
 
+    @Test(dataProvider = "validTimestampLongValues")
+    public void test52(long value, String ts) {
+        Timestamp ts1 = new Timestamp(value);
+        assertEquals(ts1.toString(), ts, "ts1.toString() != ts");
+    }
+
     /*
      * DataProvider used to provide Timestamps which are not valid and are used
      * to validate that an IllegalArgumentException will be thrown from the
@@ -678,6 +710,40 @@
         };
     }
 
+    @DataProvider(name = "validTimestampLongValues")
+    private Object[][] validTimestampLongValues() {
+        return new Object[][]{
+            {1L, "1970-01-01 01:00:00.001"},
+            {-3600*1000L - 1, "1969-12-31 23:59:59.999"},
+            {-(20000L*365*24*60*60*1000), "18018-08-28 01:00:00.0"},
+            {Timestamp.valueOf("1961-08-30 11:22:33").getTime(), "1961-08-30 11:22:33.0"},
+            {Timestamp.valueOf("1961-08-30 11:22:33.54321000").getTime(), "1961-08-30 11:22:33.543"}, // nanoprecision lost
+            {new Timestamp(114, 10, 10, 10, 10, 10, 100000000).getTime(), "2014-11-10 10:10:10.1"},
+            {new Timestamp(0, 10, 10, 10, 10, 10, 100000).getTime(), "1900-11-10 10:10:10.0"}, // nanoprecision lost
+            {new Date(114, 10, 10).getTime(), "2014-11-10 00:00:00.0"},
+            {new Date(0, 10, 10).getTime(), "1900-11-10 00:00:00.0"},
+            {LocalDateTime.of(1960, 10, 10, 10, 10, 10, 50000).atZone(ZoneId.of("America/Los_Angeles"))
+                .toInstant().toEpochMilli(), "1960-10-10 19:10:10.0"},
+
+            // millisecond timestamps wraps around at year 1, so Long.MIN_VALUE looks similar
+            // Long.MAX_VALUE, while actually representing 292278994 BCE
+            {Long.MIN_VALUE, "292278994-08-17 08:12:55.192"},
+            {Long.MAX_VALUE + 1, "292278994-08-17 08:12:55.192"},
+            {Long.MAX_VALUE, "292278994-08-17 08:12:55.807"},
+            {Long.MIN_VALUE - 1, "292278994-08-17 08:12:55.807"},
+
+            // wrap around point near 0001-01-01, test that we never get a negative year:
+            {-(1970L*365*24*60*60*1000), "0001-04-25 01:00:00.0"},
+            {-(1970L*365*24*60*60*1000 + 115*24*60*60*1000L), "0001-12-31 01:00:00.0"},
+            {-(1970L*365*24*60*60*1000 + 115*24*60*60*1000L - 23*60*60*1000L), "0001-01-01 00:00:00.0"},
+
+            {LocalDateTime.of(0, 1, 1, 10, 10, 10, 50000).atZone(ZoneId.of("America/Los_Angeles"))
+                .toInstant().toEpochMilli() - 2*24*60*60*1000L, "0001-01-01 19:03:08.0"}, // 1 BCE
+            {LocalDateTime.of(0, 1, 1, 10, 10, 10, 50000).atZone(ZoneId.of("America/Los_Angeles"))
+                .toInstant().toEpochMilli() - 3*24*60*60*1000L, "0002-12-31 19:03:08.0"} // 2 BCE
+        };
+    }
+
     /*
      * DataProvider used to provide Timestamp and Nanos values in order to
      * validate that the correct Nanos value is generated from the specified
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/zip/DataDescriptorSignatureMissing.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2012 Google, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8056934
+ * @summary Check ability to read zip files created by python zipfile
+ * implementation, which fails to write optional (but recommended) data
+ * descriptor signatures.  Repro scenario is a Java -> Python -> Java round trip:
+ * - ZipOutputStream creates zip file with DEFLATED entries and data
+ *   descriptors with optional signature "PK0x0708".
+ * - Python reads those entries, preserving the 0x08 flag byte
+ * - Python outputs those entries with data descriptors lacking the
+ *   optional signature.
+ * - ZipInputStream cannot handle the missing signature
+ *
+ * No way to adapt the technique in this test to get a ZIP64 zip file
+ * without data descriptors was found.
+ *
+ * @ignore This test has brittle dependencies on an external working python.
+ */
+
+import java.io.*;
+import java.util.zip.*;
+
+public class DataDescriptorSignatureMissing  {
+    void printStream(InputStream is) throws IOException {
+        Reader r = new InputStreamReader(is);
+        StringBuilder sb = new StringBuilder();
+        char[] buf = new char[1024];
+        int n;
+        while ((n = r.read(buf)) > 0) {
+            sb.append(buf, 0, n);
+        }
+        System.out.print(sb);
+    }
+
+    int entryCount(File zipFile) throws IOException {
+        try (FileInputStream fis = new FileInputStream(zipFile);
+             ZipInputStream zis = new ZipInputStream(fis)) {
+            for (int count = 0;; count++)
+                if (zis.getNextEntry() == null)
+                    return count;
+        }
+    }
+
+    void test(String[] args) throws Throwable {
+        if (! new File("/usr/bin/python").canExecute())
+            return;
+
+        // Create a java zip file with DEFLATED entries and data
+        // descriptors with signatures.
+        final File in = new File("in.zip");
+        final File out = new File("out.zip");
+        final int count = 3;
+        try (FileOutputStream fos = new FileOutputStream(in);
+             ZipOutputStream zos = new ZipOutputStream(fos)) {
+            for (int i = 0; i < count; i++) {
+                ZipEntry ze = new ZipEntry("hello.python" + i);
+                ze.setMethod(ZipEntry.DEFLATED);
+                zos.putNextEntry(ze);
+                zos.write(new byte[10]);
+                zos.closeEntry();
+            }
+        }
+
+        // Copy the zip file using python's zipfile module
+        String[] python_program_lines = {
+            "import os",
+            "import zipfile",
+            "input_zip = zipfile.ZipFile('in.zip', mode='r')",
+            "output_zip = zipfile.ZipFile('out.zip', mode='w')",
+            "count08 = 0",
+            "for input_info in input_zip.infolist():",
+            "  output_info = input_info",
+            "  if output_info.flag_bits & 0x08 == 0x08:",
+            "    count08 += 1",
+            "  output_zip.writestr(output_info, input_zip.read(input_info))",
+            "output_zip.close()",
+            "if count08 == 0:",
+            "  raise ValueError('Expected to see entries with 0x08 flag_bits set')",
+        };
+        StringBuilder python_program_builder = new StringBuilder();
+        for (String line : python_program_lines)
+            python_program_builder.append(line).append('\n');
+        String python_program = python_program_builder.toString();
+        String[] cmdline = { "/usr/bin/python", "-c", python_program };
+        ProcessBuilder pb = new ProcessBuilder(cmdline);
+        pb.redirectErrorStream(true);
+        Process p = pb.start();
+        printStream(p.getInputStream());
+        p.waitFor();
+        equal(p.exitValue(), 0);
+
+        File pythonZipFile = new File("out.zip");
+        check(pythonZipFile.exists());
+
+        equal(entryCount(in),
+              entryCount(out));
+
+        // We expect out to be identical to in, except for the removal of
+        // the optional data descriptor signatures.
+        final int SIG_LENGTH = 4;       // length of a zip signature - PKxx
+        equal(in.length(),
+              out.length() + SIG_LENGTH * count);
+
+        in.delete();
+        out.delete();
+    }
+
+    //--------------------- Infrastructure ---------------------------
+    volatile int passed = 0, failed = 0;
+    void pass() {passed++;}
+    void fail() {failed++; Thread.dumpStack();}
+    void fail(String msg) {System.err.println(msg); fail();}
+    void unexpected(Throwable t) {failed++; t.printStackTrace();}
+    void check(boolean cond) {if (cond) pass(); else fail();}
+    void equal(Object x, Object y) {
+        if (x == null ? y == null : x.equals(y)) pass();
+        else fail(x + " not equal to " + y);}
+    public static void main(String[] args) throws Throwable {
+        new DataDescriptorSignatureMissing().instanceMain(args);}
+    public void instanceMain(String[] args) throws Throwable {
+        try {test(args);} catch (Throwable t) {unexpected(t);}
+        System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+        if (failed > 0) throw new AssertionError("Some tests failed");}
+}
--- a/jdk/test/javax/management/monitor/AttributeArbitraryDataTypeTest.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/test/javax/management/monitor/AttributeArbitraryDataTypeTest.java	Wed Jul 05 20:01:50 2017 +0200
@@ -58,9 +58,9 @@
 public class AttributeArbitraryDataTypeTest implements NotificationListener {
 
     // Flag to notify that a message has been received
-    private boolean counterMessageReceived = false;
-    private boolean gaugeMessageReceived = false;
-    private boolean stringMessageReceived = false;
+    private volatile boolean counterMessageReceived = false;
+    private volatile boolean gaugeMessageReceived = false;
+    private volatile boolean stringMessageReceived = false;
 
     // Match enum
     public enum Match { do_not_match_0,
@@ -195,21 +195,33 @@
                      " has reached or exceeded the threshold");
                 echo("\t\tDerived Gauge = " + n.getDerivedGauge());
                 echo("\t\tTrigger = " + n.getTrigger());
-                counterMessageReceived = true;
+
+                synchronized (this) {
+                    counterMessageReceived = true;
+                    notifyAll();
+                }
             } else if (type.equals(MonitorNotification.
                                    THRESHOLD_HIGH_VALUE_EXCEEDED)) {
                 echo("\t\t" + n.getObservedAttribute() +
                      " has reached or exceeded the high threshold");
                 echo("\t\tDerived Gauge = " + n.getDerivedGauge());
                 echo("\t\tTrigger = " + n.getTrigger());
-                gaugeMessageReceived = true;
+
+                synchronized (this) {
+                    gaugeMessageReceived = true;
+                    notifyAll();
+                }
             } else if (type.equals(MonitorNotification.
                                    STRING_TO_COMPARE_VALUE_MATCHED)) {
                 echo("\t\t" + n.getObservedAttribute() +
                      " matches the string-to-compare value");
                 echo("\t\tDerived Gauge = " + n.getDerivedGauge());
                 echo("\t\tTrigger = " + n.getTrigger());
-                stringMessageReceived = true;
+
+                synchronized (this) {
+                    stringMessageReceived = true;
+                    notifyAll();
+                }
             } else {
                 echo("\t\tSkipping notification of type: " + type);
             }
@@ -358,6 +370,17 @@
 
             // Check if notification was received
             //
+            synchronized (this) {
+                while (!counterMessageReceived) {
+                    try {
+                        wait();
+                    } catch (InterruptedException e) {
+                        System.err.println("Got unexpected exception: " + e);
+                        e.printStackTrace();
+                        break;
+                    }
+                }
+            }
             if (counterMessageReceived) {
                 echo("\tOK: CounterMonitor notification received");
             } else {
@@ -525,6 +548,17 @@
 
             // Check if notification was received
             //
+            synchronized (this) {
+                while (!gaugeMessageReceived) {
+                    try {
+                        wait();
+                    } catch (InterruptedException e) {
+                        System.err.println("Got unexpected exception: " + e);
+                        e.printStackTrace();
+                        break;
+                    }
+                }
+            }
             if (gaugeMessageReceived) {
                 echo("\tOK: GaugeMonitor notification received");
             } else {
@@ -680,6 +714,17 @@
 
             // Check if notification was received
             //
+            synchronized (this) {
+                while (!stringMessageReceived) {
+                    try {
+                        wait();
+                    } catch (InterruptedException e) {
+                        System.err.println("Got unexpected exception: " + e);
+                        e.printStackTrace();
+                        break;
+                    }
+                }
+            }
             if (stringMessageReceived) {
                 echo("\tOK: StringMonitor notification received");
             } else {
--- a/jdk/test/javax/management/monitor/CounterMonitorTest.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/test/javax/management/monitor/CounterMonitorTest.java	Wed Jul 05 20:01:50 2017 +0200
@@ -43,9 +43,6 @@
     // modulus number
     private Number modulus = new Integer(7);
 
-    // offset number
-    private int offset = 0;
-
     // difference mode flag
     private boolean differenceModeFlag = true;
 
@@ -58,9 +55,6 @@
     // counter values
     private int[] values = new int[] {4, 6, 9, 11};
 
-    // time to wait for notification (in seconds)
-    private int timeout = 5;
-
     // flag to notify that a message has been received
     private volatile boolean messageReceived = false;
 
@@ -92,8 +86,9 @@
                 echo("\t\t" + n.getObservedAttribute() +
                      " has reached or exceeded the threshold");
                 echo("\t\tDerived Gauge = " + n.getDerivedGauge());
-                messageReceived = true;
+
                 synchronized (this) {
+                    messageReceived = true;
                     notifyAll();
                 }
             } else {
@@ -205,22 +200,17 @@
     }
 
     /*
-     * Wait until timeout reached
+     * Wait messageReceived to be true
      */
-    void doWait() {
-        for (int i = 0; i < timeout; i++) {
-            echo("\tdoWait: Waiting for " + timeout + " seconds. " +
-                 "i = " + i + ", messageReceived = " + messageReceived);
-            if (messageReceived) {
+    synchronized void doWait() {
+        while (!messageReceived) {
+            try {
+                wait();
+            } catch (InterruptedException e) {
+                System.err.println("Got unexpected exception: " + e);
+                e.printStackTrace();
                 break;
             }
-            try {
-                synchronized (this) {
-                    wait(1000);
-                }
-            } catch (InterruptedException e) {
-                // OK: Ignore...
-            }
         }
     }
 
--- a/jdk/test/javax/management/monitor/GaugeMonitorDeadlockTest.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/test/javax/management/monitor/GaugeMonitorDeadlockTest.java	Wed Jul 05 20:01:50 2017 +0200
@@ -36,8 +36,9 @@
  */
 
 import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
 import java.util.concurrent.atomic.AtomicInteger;
-import javax.management.Attribute;
 import javax.management.JMX;
 import javax.management.MBeanServer;
 import javax.management.Notification;
@@ -47,10 +48,16 @@
 import javax.management.monitor.GaugeMonitorMBean;
 
 public class GaugeMonitorDeadlockTest {
+    private static enum When {IN_GET_ATTRIBUTE, IN_NOTIFY};
+    private static long checkingTime;
 
     public static void main(String[] args) throws Exception {
         if (args.length != 1)
             throw new Exception("Arg should be test number");
+        double factor = Double.parseDouble(System.getProperty("test.timeout.factor", "1.0"));
+        checkingTime = (long)factor*1000;
+        System.out.println("=== checkingTime = " + checkingTime + "ms");
+
         int testNo = Integer.parseInt(args[0]) - 1;
         TestCase test = testCases[testNo];
         System.out.println("Test: " + test.getDescription());
@@ -58,8 +65,6 @@
         System.out.println("Test passed");
     }
 
-    private static enum When {IN_GET_ATTRIBUTE, IN_NOTIFY};
-
     private static abstract class TestCase {
         TestCase(String description, When when) {
             this.description = description;
@@ -98,16 +103,29 @@
             monitorProxy.setNotifyLow(true);
             monitorProxy.start();
 
+            System.out.println("=== Waiting observedProxy.getGetCount() to be "
+                    + "changed, presumable deadlock if timeout?");
             final int initGetCount = observedProxy.getGetCount();
-            int getCount = initGetCount;
-            for (int i = 0; i < 2000; i++) { // 2000 * 10 = 20 seconds
-                getCount = observedProxy.getGetCount();
-                if (getCount != initGetCount)
-                    break;
-                Thread.sleep(10);
+            long checkedTime = System.currentTimeMillis();
+            long nowTime;
+            ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
+            while (observedProxy.getGetCount() == initGetCount) {
+                Thread.sleep(100);
+
+                nowTime = System.currentTimeMillis();
+                if (nowTime - checkedTime >= checkingTime) {
+                    System.out.println("=== Checking deadlocked ...");
+                    if (threadMXBean.findDeadlockedThreads() != null) {
+                        for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) {
+                            System.out.println(info);
+                        }
+                        throw new Error("Found deadlocked threads: "
+                                + threadMXBean.findDeadlockedThreads().length);
+                    }
+                    checkedTime = System.currentTimeMillis();
+                }
             }
-            if (getCount <= initGetCount)
-                throw new Exception("Test failed: presumable deadlock");
+
             // This won't show up as a deadlock in CTRL-\ or in
             // ThreadMXBean.findDeadlockedThreads(), because they don't
             // see that thread A is waiting for thread B (B.join()), and
@@ -117,13 +135,13 @@
             // so if we want to test notify behaviour we can trigger by
             // exceeding the threshold.
             if (when == When.IN_NOTIFY) {
+                final Thread testedThread = new Thread(sensitiveThing);
                 final AtomicInteger notifCount = new AtomicInteger();
                 final NotificationListener listener = new NotificationListener() {
                     public void handleNotification(Notification n, Object h) {
-                        Thread t = new Thread(sensitiveThing);
-                        t.start();
+                        testedThread.start();
                         try {
-                            t.join();
+                            testedThread.join();
                         } catch (InterruptedException e) {
                             throw new RuntimeException(e);
                         }
@@ -132,12 +150,36 @@
                 };
                 mbs.addNotificationListener(monitorName, listener, null, null);
                 observedProxy.setThing(1000);
-                for (int i = 0; i < 2000 && notifCount.get() == 0; i++)
-                    Thread.sleep(10);
-                if (notifCount.get() == 0)
-                    throw new Exception("Test failed: presumable deadlock");
+                System.out.println("=== Waiting notifications, presumable "
+                        + "deadlock if timeout?");
+                long startTime = System.currentTimeMillis();
+                checkedTime = startTime;
+                while (notifCount.get() == 0) {
+                    Thread.sleep(100);
+
+                    nowTime = System.currentTimeMillis();
+                    if (nowTime - checkedTime >= checkingTime) {
+                        System.out.println("=== Checking the thread state ...");
+                        if (testedThread.isAlive()) {
+                            System.out.println("=== Waiting testedThread to die "
+                                    + "after " + (nowTime - startTime) + "ms");
+
+                            ThreadInfo tinfo = threadMXBean.getThreadInfo(testedThread.getId());
+                            if (Thread.State.BLOCKED.equals(tinfo.getThreadState())) {
+                                for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) {
+                                    System.out.println(info);
+                                }
+                            } else {
+                                System.out.println(tinfo);
+                            }
+                        } else {
+                            System.out.println("=== The testedThread is dead as wished, "
+                                    + "the test must be passed soon.");
+                        }
+                        checkedTime = System.currentTimeMillis();
+                    }
+                }
             }
-
         }
 
         abstract void doSensitiveThing(GaugeMonitorMBean monitorProxy,
--- a/jdk/test/javax/management/monitor/NonComparableAttributeValueTest.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/test/javax/management/monitor/NonComparableAttributeValueTest.java	Wed Jul 05 20:01:50 2017 +0200
@@ -39,7 +39,7 @@
 public class NonComparableAttributeValueTest implements NotificationListener {
 
     // Flag to notify that a message has been received
-    private boolean messageReceived = false;
+    private volatile boolean messageReceived = false;
 
     // MBean class
     public class ObservedObject implements ObservedObjectMBean {
@@ -69,7 +69,11 @@
                 echo("\t\t" + n.getObservedAttribute() + " is null");
                 echo("\t\tDerived Gauge = " + n.getDerivedGauge());
                 echo("\t\tTrigger = " + n.getTrigger());
-                messageReceived = true;
+
+                synchronized (this) {
+                    messageReceived = true;
+                    notifyAll();
+                }
             } else {
                 echo("\t\tSkipping notification of type: " + type);
             }
@@ -134,12 +138,9 @@
             echo(">>> START the CounterMonitor");
             counterMonitor.start();
 
-            // Wait for granularity period (multiplied by 2 for sure)
-            //
-            Thread.sleep(granularityperiod * 2);
-
             // Check if notification was received
             //
+            doWait();
             if (messageReceived) {
                 echo("\tOK: CounterMonitor notification received");
             } else {
@@ -212,12 +213,9 @@
             echo(">>> START the GaugeMonitor");
             gaugeMonitor.start();
 
-            // Wait for granularity period (multiplied by 2 for sure)
-            //
-            Thread.sleep(granularityperiod * 2);
-
             // Check if notification was received
             //
+            doWait();
             if (messageReceived) {
                 echo("\tOK: GaugeMonitor notification received");
             } else {
@@ -289,12 +287,9 @@
             echo(">>> START the StringMonitor");
             stringMonitor.start();
 
-            // Wait for granularity period (multiplied by 2 for sure)
-            //
-            Thread.sleep(granularityperiod * 2);
-
             // Check if notification was received
             //
+            doWait();
             if (messageReceived) {
                 echo("\tOK: StringMonitor notification received");
             } else {
@@ -334,6 +329,21 @@
     }
 
     /*
+     * Wait messageReceived to be true
+     */
+    synchronized void doWait() {
+        while (!messageReceived) {
+            try {
+                wait();
+            } catch (InterruptedException e) {
+                System.err.println("Got unexpected exception: " + e);
+                e.printStackTrace();
+                break;
+            }
+        }
+    }
+
+    /*
      * Standalone entry point.
      *
      * Run the test and report to stdout.
--- a/jdk/test/javax/management/monitor/ReflectionExceptionTest.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/test/javax/management/monitor/ReflectionExceptionTest.java	Wed Jul 05 20:01:50 2017 +0200
@@ -87,7 +87,11 @@
                 echo("\tObservedAttribute: " + mn.getObservedAttribute());
                 echo("\tDerivedGauge: " + mn.getDerivedGauge());
                 echo("\tTrigger: " + mn.getTrigger());
-                messageReceived = true;
+
+                synchronized (this) {
+                    messageReceived = true;
+                    notifyAll();
+                }
             }
         }
     }
@@ -135,12 +139,9 @@
             echo(">>> START the CounterMonitor");
             counterMonitor.start();
 
-            // Wait for granularity period (multiplied by 2 for sure)
-            //
-            Thread.sleep(granularityperiod * 2);
-
             // Check if notification was received
             //
+            doWait();
             if (messageReceived) {
                 echo("\tOK: CounterMonitor got RUNTIME_ERROR notification!");
             } else {
@@ -203,12 +204,9 @@
             echo(">>> START the GaugeMonitor");
             gaugeMonitor.start();
 
-            // Wait for granularity period (multiplied by 2 for sure)
-            //
-            Thread.sleep(granularityperiod * 2);
-
             // Check if notification was received
             //
+            doWait();
             if (messageReceived) {
                 echo("\tOK: GaugeMonitor got RUNTIME_ERROR notification!");
             } else {
@@ -270,12 +268,9 @@
             echo(">>> START the StringMonitor");
             stringMonitor.start();
 
-            // Wait for granularity period (multiplied by 2 for sure)
-            //
-            Thread.sleep(granularityperiod * 2);
-
             // Check if notification was received
             //
+            doWait();
             if (messageReceived) {
                 echo("\tOK: StringMonitor got RUNTIME_ERROR notification!");
             } else {
@@ -349,8 +344,23 @@
         }
     }
 
+    /*
+     * Wait messageReceived to be true
+     */
+    synchronized void doWait() {
+        while (!messageReceived) {
+            try {
+                wait();
+            } catch (InterruptedException e) {
+                System.err.println("Got unexpected exception: " + e);
+                e.printStackTrace();
+                break;
+            }
+        }
+    }
+
     // Flag to notify that a message has been received
-    private boolean messageReceived = false;
+    private volatile boolean messageReceived = false;
 
     private MBeanServer server;
     private ObjectName obsObjName;
--- a/jdk/test/javax/management/monitor/RuntimeExceptionTest.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/test/javax/management/monitor/RuntimeExceptionTest.java	Wed Jul 05 20:01:50 2017 +0200
@@ -86,7 +86,11 @@
                 echo("\tObservedAttribute: " + mn.getObservedAttribute());
                 echo("\tDerivedGauge: " + mn.getDerivedGauge());
                 echo("\tTrigger: " + mn.getTrigger());
-                messageReceived = true;
+
+                synchronized (this) {
+                    messageReceived = true;
+                    notifyAll();
+                }
             }
         }
     }
@@ -134,12 +138,9 @@
             echo(">>> START the CounterMonitor");
             counterMonitor.start();
 
-            // Wait for granularity period (multiplied by 2 for sure)
-            //
-            Thread.sleep(granularityperiod * 2);
-
             // Check if notification was received
             //
+            doWait();
             if (messageReceived) {
                 echo("\tOK: CounterMonitor got RUNTIME_ERROR notification!");
             } else {
@@ -202,12 +203,9 @@
             echo(">>> START the GaugeMonitor");
             gaugeMonitor.start();
 
-            // Wait for granularity period (multiplied by 2 for sure)
-            //
-            Thread.sleep(granularityperiod * 2);
-
             // Check if notification was received
             //
+            doWait();
             if (messageReceived) {
                 echo("\tOK: GaugeMonitor got RUNTIME_ERROR notification!");
             } else {
@@ -269,12 +267,9 @@
             echo(">>> START the StringMonitor");
             stringMonitor.start();
 
-            // Wait for granularity period (multiplied by 2 for sure)
-            //
-            Thread.sleep(granularityperiod * 2);
-
             // Check if notification was received
             //
+            doWait();
             if (messageReceived) {
                 echo("\tOK: StringMonitor got RUNTIME_ERROR notification!");
             } else {
@@ -347,8 +342,23 @@
         }
     }
 
+    /*
+     * Wait messageReceived to be true
+     */
+    synchronized void doWait() {
+        while (!messageReceived) {
+            try {
+                wait();
+            } catch (InterruptedException e) {
+                System.err.println("Got unexpected exception: " + e);
+                e.printStackTrace();
+                break;
+            }
+        }
+    }
+
     // Flag to notify that a message has been received
-    private boolean messageReceived = false;
+    private volatile boolean messageReceived = false;
 
     private MBeanServer server;
     private ObjectName obsObjName;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JWindow/ShapedAndTranslucentWindows/Common.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,417 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.swing.*;
+import javax.swing.border.EmptyBorder;
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.geom.Area;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.security.SecureRandom;
+
+public abstract class Common {
+
+    ExtendedRobot robot;
+    Class<? extends JFrame> windowClass;
+    JFrame background;
+    BufferedImage foreground;
+    Window window;
+    volatile boolean gradientBackgroundEnabled = false;
+    volatile int gradientWidth = 255;
+    volatile int gradientHeight = 255;
+
+    float opacity = 1.0f;
+    float perPixelTranslucency = 1.0f;
+    static Color BG_COLOR = Color.BLUE;
+    static Color FG_COLOR = Color.RED;
+    static final int delay = 1000;
+    static final SecureRandom random = new SecureRandom();
+    static final int dl = 100;
+    static final Class[] WINDOWS_TO_TEST = { JWindow.class, JFrame.class, JDialog.class };
+
+    volatile int clicked;
+
+    public Common(Class windowClass, float opacity, float perPixelTranslucency, boolean gradient) throws Exception {
+        this.gradientBackgroundEnabled = gradient;
+        this.perPixelTranslucency = perPixelTranslucency;
+        this.opacity = opacity;
+        robot = new ExtendedRobot();
+        this.windowClass = windowClass;
+        EventQueue.invokeAndWait(this::initBackgroundFrame);
+        EventQueue.invokeAndWait(this::initGUI);
+    }
+
+    public Common(Class windowClass) throws Exception {
+        this(windowClass, 1.0f, 1.0f, false);
+    }
+
+    public Common(Class windowClass, boolean gradient) throws Exception {
+        this(windowClass, 1.0f, 1.0f, gradient);
+    }
+
+    public abstract void doTest() throws Exception;
+
+    public void dispose() {
+        window.dispose();
+        background.dispose();
+    }
+
+    public void applyShape() {};
+
+    public void applyDynamicShape() {
+        final Area a = new Area();
+        Dimension size = window.getSize();
+        for (int x = 0; x < 3; x++) {
+            for (int y = 0; y < 3; y++) {
+                a.add(new Area(new Rectangle2D.Double(
+                        x * size.getWidth() / 17*6, y * size.getHeight() / 17*6,
+                        size.getWidth() / 17*5, size.getHeight() / 17*5)));
+            }
+        }
+        window.setShape(a);
+    }
+
+    public BufferedImage getForegroundWindow() throws Exception {
+        final BufferedImage f[] = new BufferedImage[1];
+        EventQueue.invokeAndWait( () -> {
+            f[0] = new BufferedImage(window.getWidth(),
+                    window.getHeight(), BufferedImage.TYPE_INT_RGB);
+            window.printAll(f[0].createGraphics());
+        });
+        robot.waitForIdle(delay);
+        return f[0];
+    }
+
+    public static boolean checkTranslucencyMode(GraphicsDevice.WindowTranslucency mode) {
+
+        if (!GraphicsEnvironment
+                .getLocalGraphicsEnvironment()
+                .getDefaultScreenDevice()
+                .isWindowTranslucencySupported(mode)){
+            System.out.println(mode+" translucency mode isn't supported");
+            return false;
+        } else {
+            return true;
+        }
+
+    }
+
+    public void applyAppDragNResizeSupport() {
+        MouseAdapter m = new MouseAdapter() {
+
+            private Point dragOrigin = null;
+            private Dimension origSize = null;
+            private Point origLoc = null;
+            private boolean left = false;
+            private boolean top = false;
+            private boolean bottom = false;
+            private boolean right = false;
+
+            public void mousePressed(MouseEvent e) {
+                dragOrigin = e.getLocationOnScreen();
+                origSize = window.getSize();
+                origLoc = window.getLocationOnScreen();
+                right = (origLoc.x + window.getWidth() - dragOrigin.x) < 5;
+                left = !right && dragOrigin.x - origLoc.x < 5;
+                bottom = (origLoc.y + window.getHeight() - dragOrigin.y) < 5;
+                top = !bottom && dragOrigin.y - origLoc.y < 5;
+            }
+
+            public void mouseReleased(MouseEvent e) { resize(e); }
+            public void mouseDragged(MouseEvent e) { resize(e); }
+
+            void resize(MouseEvent e) {
+                Point dragDelta = e.getLocationOnScreen();
+                dragDelta.translate(-dragOrigin.x, -dragOrigin.y);
+                Point newLoc = new Point(origLoc);
+                newLoc.translate(dragDelta.x, dragDelta.y);
+                Dimension newSize = new Dimension(origSize);
+                if (left || right) {
+                    newSize.width += right ? dragDelta.x : -dragDelta.x;
+                }
+                if (top || bottom) {
+                    newSize.height += bottom ? dragDelta.y : -dragDelta.y;
+                }
+                if (right || (top || bottom) && !left) {
+                    newLoc.x = origLoc.x;
+                }
+                if (bottom || (left || right) && !top) {
+                    newLoc.y = origLoc.y;
+                }
+                window.setBounds(newLoc.x, newLoc.y, newSize.width, newSize.height);
+            }
+        };
+        for (Component comp : window.getComponents()) {
+            comp.addMouseListener(m);
+            comp.addMouseMotionListener(m);
+        }
+
+        window.addMouseListener(m);
+        window.addMouseMotionListener(m);
+    }
+
+    public void checkTranslucentShape() throws Exception {
+        foreground = getForegroundWindow();
+        Point[] points = new Point[4];
+
+        Dimension size = window.getSize();
+        Point location = window.getLocationOnScreen();
+
+        points[0] = new Point(20, 20);
+        points[1] = new Point(20, size.height-20);
+        points[2] = new Point(size.width-20, 20);
+        points[3] = new Point(size.width-20, size.height-20);
+
+        for (Point p : points){
+            p.translate(location.x, location.y);
+            Color actual = robot.getPixelColor(p.x, p.y);
+            if (actual.equals(BG_COLOR)|| actual.equals(FG_COLOR))
+                throw new RuntimeException("Error in point "+p+": "+actual+" equals to foreground or background color");
+            else
+                System.out.println("OK with foreground point "+p);
+        }
+    }
+
+    public void checkDynamicShape() throws Exception {
+        Point[] points = new Point[4];
+
+        Dimension size = window.getSize();
+
+        int blockSizeX = (int) (size.getWidth() / 17);
+        int blockSizeY = (int) (size.getHeight() / 17);
+
+        // background
+        points[0] = new Point((int) (blockSizeX * 5.5), (int) (blockSizeY * 5.5));
+        points[1] = new Point((int) (size.getWidth() - blockSizeX * 5.5), (int) (size.getHeight() - blockSizeY * 5.5));
+        points[2] = new Point((int) (blockSizeX * 5.5), (int) (size.getHeight() - blockSizeY * 5.5));
+        points[3] = new Point((int) (size.getWidth() - blockSizeX * 5.5), (int) (blockSizeY * 5.5));
+        checkShape(points, true);
+
+        // foreground
+        if (opacity < 1.0f){
+            checkTranslucentShape();
+        } else {
+            points[0] = new Point(3 * blockSizeX, 3 * blockSizeY);
+            points[1] = new Point(14 * blockSizeX, 14 * blockSizeY);
+            points[2] = new Point(3 * blockSizeX, 14 * blockSizeY);
+            points[3] = new Point(14 * blockSizeX, 3 * blockSizeY);
+            checkShape(points, false);
+        }
+    }
+
+    public void checkShape(Point[] points, boolean areBackgroundPoints) throws Exception {
+
+        Point location = window.getLocationOnScreen();
+
+        for (Point p : points) {
+            p.translate(location.x, location.y);
+            Color pixel = robot.getPixelColor(p.x, p.y);
+            if (areBackgroundPoints) {
+                if (pixel.getRed() != 0
+                    || pixel.getGreen() != 0 )
+                    throw new RuntimeException("Background point " + p +
+                            " color " + pixel +
+                            " does not equal to background color " + BG_COLOR);
+                else
+                    System.out.println("OK with background point " + p);
+            } else {
+                if (pixel.equals(BG_COLOR))
+                    throw new RuntimeException("Foreground point " + p +
+                            " color " + pixel +
+                            " equals to background color " + BG_COLOR);
+                else
+                    System.out.println("OK with foreground point " + p);
+            }
+        }
+    }
+
+    public void initBackgroundFrame() {
+        background = new JFrame();
+        background.setUndecorated(true);
+        background.getContentPane().setBackground(BG_COLOR);
+        background.setSize(500, 500);
+        background.setLocation(dl, dl);
+        background.setVisible(true);
+    }
+
+    public void initGUI() {
+        Container contentPane;
+        if (windowClass.equals(Frame.class)) {
+            window = new JFrame();
+            ((JFrame) window).setUndecorated(true);
+            contentPane = ((JFrame) window).getContentPane();
+        } else  if (windowClass.equals(Dialog.class)) {
+            window = new JDialog(background);
+            ((JDialog) window).setUndecorated(true);
+            contentPane = ((JDialog) window).getContentPane();
+        } else {
+            window = new JWindow(background);
+            contentPane = ((JWindow) window).getContentPane();
+        }
+
+        if (perPixelTranslucency < 1.0f) {
+            contentPane.setBackground(colorWithOpacity(FG_COLOR, perPixelTranslucency));
+            window.setBackground(colorWithOpacity(FG_COLOR, perPixelTranslucency));
+        } else {
+            contentPane.setBackground(FG_COLOR);
+            window.setBackground(FG_COLOR);
+        }
+
+        window.setLocation(2 * dl, 2 * dl);
+        window.setSize(255, 255);
+        window.setPreferredSize(new Dimension(255, 255));
+        createSwingComponents();
+        if (opacity < 1.0f)
+            window.setOpacity(opacity);
+
+        window.addComponentListener(new ComponentAdapter() {
+            @Override
+            public void componentResized(ComponentEvent e) {
+                applyShape();
+            }
+        });
+        applyShape();
+        window.setVisible(true);
+        applyAppDragNResizeSupport();
+        window.toFront();
+    }
+
+    public void createSwingComponents() {
+        Container contentPane;
+        if (gradientBackgroundEnabled) {
+            JPanel jPanel = new JPanel() {
+                @Override
+                protected void paintComponent(Graphics g) {
+                    if (g instanceof Graphics2D) {
+                        Color background = Color.RED;
+                        Paint p = new GradientPaint(0.0f, 0.0f, colorWithOpacity(background, 0),
+                                0.0f, gradientHeight - 3, colorWithOpacity(background, 1), true);
+                        Graphics2D g2d = (Graphics2D) g;
+                        g2d.setPaint(p);
+                        g2d.fillRect(0, 3, gradientWidth, gradientHeight - 3);
+                    } else {
+                        super.paintComponent(g);
+                    }
+                }
+            };
+            jPanel.setBorder(new EmptyBorder(15, 5, 5, 5));
+            jPanel.setOpaque(false);
+
+            contentPane = jPanel;
+
+            RootPaneContainer.class.cast(window).setContentPane(contentPane);
+        } else {
+            contentPane = RootPaneContainer.class.cast(window).getContentPane();
+        }
+        contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
+
+        JButton button = new JButton("JButton");
+        window.add(button);
+
+        JTextArea textArea = new JTextArea("JTextArea");
+        window.add(textArea);
+
+        JCheckBox checkbox = new JCheckBox("JCheckBox");
+        checkbox.setOpaque(false);
+        window.add(checkbox);
+
+        JComboBox comboBox = new JComboBox(new String[]{"JComboBox", "Some item"});
+        window.add(comboBox);
+
+        JLabel label = new JLabel("JLabel");
+        window.add(label);
+
+        JTextField textField = new JTextField("JTextField");
+        window.add(textField);
+
+        JPanel panel = new JPanel();
+        panel.setOpaque(false);
+        window.add(panel);
+
+        JComboBox comboBox2 = new JComboBox(new String[]{"JComboBox2", "Another item"});
+        window.add(comboBox2);
+
+        JRadioButton radioButton = new JRadioButton("JRadioButton");
+        radioButton.setOpaque(false);
+        window.add(radioButton);
+    }
+
+    Color colorWithOpacity(Color color, float opacity) {
+        return new Color(color.getColorSpace(), color.getColorComponents(null), opacity);
+    }
+
+    public void checkTranslucent() throws Exception {
+        checkTranslucentShape();
+
+        // Drag
+        Point location = window.getLocationOnScreen();
+        robot.dragAndDrop(location.x + 30, location.y + 5, location.x + dl + random.nextInt(dl), location.y + random.nextInt(dl));
+        robot.waitForIdle(delay);
+        checkTranslucentShape();
+
+        // Resize
+        location = window.getLocationOnScreen();
+        robot.dragAndDrop(location.x + 4, location.y + 4, location.x + random.nextInt(2*dl)-dl, location.y + random.nextInt(2*dl)-dl);
+        robot.waitForIdle(delay);
+        checkTranslucentShape();
+
+        EventQueue.invokeAndWait(this::dispose);
+    }
+
+    public void checkDynamic() throws Exception {
+        checkDynamicShape();
+
+        // Drag
+        Point location = window.getLocationOnScreen();
+        robot.dragAndDrop(location.x + 30, location.y + 5, location.x + dl + random.nextInt(dl), location.y + random.nextInt(dl));
+        robot.waitForIdle(delay);
+        checkDynamicShape();
+
+        // Resize
+        location = window.getLocationOnScreen();
+        robot.dragAndDrop(location.x + 4, location.y + 4, location.x + random.nextInt(2*dl)-dl, location.y + random.nextInt(2*dl)-dl);
+        robot.waitForIdle(delay);
+        checkDynamicShape();
+
+        EventQueue.invokeAndWait(this::dispose);
+    }
+
+    void checkClick(int x, int y, int flag) throws Exception {
+
+        System.out.println("Trying to click point " + x + ", " + y + ", looking for " + flag + " flag to trigger.");
+
+        clicked = 0;
+        robot.mouseMove(x, y);
+        robot.click();
+
+        for (int i = 0; i < 100; i++)
+            if ((clicked & (1 << flag)) == 0)
+                robot.delay(50);
+            else
+                break;
+
+        if ((clicked & (1 << flag)) == 0)
+            throw new RuntimeException("FAIL: Flag " + flag + " is not triggered for point " + x + ", " + y + "!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JWindow/ShapedAndTranslucentWindows/PerPixelTranslucent.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.*;
+
+/*
+ * @test
+ * @summary Check if a per-pixel translucent window is dragged and resized
+ *          by mouse correctly.
+ * Test Description: Check if PERPIXEL_TRANSLUCENT translucency type is supported
+ *      on the current platform. Proceed if they are supported. Create a window
+ *      with some components in it, make window undecorated, apply translucent
+ *      background of 0.5. Drag and resize the window using AWT Robot and verify
+ *      that translucency is correctly applied with pixels checking. Make the
+ *      window appear on top of a known background. Repeat this for JWindow,
+ *      JDialog, JFrame.
+ * Expected Result: If PERPIXEL_TRANSLUCENT translucency type is supported, the
+ *      window should appear with the translucency. Only window background
+ *      should be translucent, all the controls should be opaque.
+ * @author mrkam
+ * @library ../../../../lib/testlibrary
+ * @build Common ExtendedRobot
+ * @run main PerPixelTranslucent
+ */
+
+public class PerPixelTranslucent extends Common {
+
+    public static void main(String[] ignored) throws Exception {
+        if (checkTranslucencyMode(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSLUCENT))
+            for (Class<Window> windowClass: WINDOWS_TO_TEST)
+                new PerPixelTranslucent(windowClass).doTest();
+    }
+
+    public PerPixelTranslucent(Class windowClass) throws Exception {
+        super(windowClass, 1.0f, 0.5f, false);
+    }
+
+    public void doTest() throws Exception {
+        robot.waitForIdle(delay);
+        checkTranslucent();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JWindow/ShapedAndTranslucentWindows/PerPixelTranslucentCanvas.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.*;
+import javax.swing.*;
+import java.awt.image.BufferedImage;
+
+/*
+ * @test
+ * @summary Check if a per-pixel translucent window shows up with correct translucency
+ * @author mrkam
+ * @library ../../../../lib/testlibrary
+ * @build Common ExtendedRobot
+ * @run main PerPixelTranslucentCanvas
+ */
+
+public class PerPixelTranslucentCanvas extends Common {
+
+    JPanel center;
+    Color OVAL_COLOR = Color.BLUE;
+
+    public static void main(String[] ignored) throws Exception {
+        FG_COLOR = new Color(200, 0, 0, 100);
+        BG_COLOR = Color.GREEN;
+        for (Class<Window> windowClass: WINDOWS_TO_TEST)
+            new PerPixelTranslucentCanvas(windowClass).doTest();
+    }
+
+    public PerPixelTranslucentCanvas(Class windowClass) throws Exception {
+        super(windowClass);
+    }
+
+    @Override
+    public void createSwingComponents() {
+        Container contentPane = RootPaneContainer.class.cast(window).getContentPane();
+        BorderLayout bl = new BorderLayout(10, 10);
+        contentPane.setLayout(bl);
+
+        JLabel label = new JLabel("North", new ImageIcon(
+                new BufferedImage(30, 30, BufferedImage.TYPE_INT_RGB)), SwingConstants.CENTER);
+        contentPane.add(label, BorderLayout.NORTH);
+
+        JButton button = new JButton("West");
+        contentPane.add(button, BorderLayout.WEST);
+
+        center = new JPanel() {
+            @Override
+            public void paint(Graphics g) {
+                g.setColor(OVAL_COLOR);
+                g.fillOval(0, 0, getWidth(), getHeight());
+            }
+        };
+        contentPane.add(center, BorderLayout.CENTER);
+
+        JTextField jTextField = new JTextField("South");
+        contentPane.add(jTextField, BorderLayout.SOUTH);
+    }
+
+    @Override
+    public void doTest() throws Exception {
+        robot.waitForIdle(delay);
+
+        Rectangle bounds = center.getBounds();
+        Point loc = center.getLocationOnScreen();
+
+        final int x = loc.x + bounds.width / 2;
+        final int y = loc.y + bounds.height / 2;
+
+        Color color = robot.getPixelColor(x, y);
+        if (OVAL_COLOR.getRGB() != color.getRGB())
+            throw new RuntimeException("bounds = " + bounds + "\n" +
+                    "loc = " + loc + "\n" +
+                    "background loc = " + background.getX() + ", " + background.getY() + "\n" +
+                    "so middle point over background is " + (x - background.getX()) + ", " + (y - background.getY()) + "\n" +
+                    "Oval is not opaque in the middle point (" + x + ", " + y + ", " + color + ")");
+
+        color = robot.getPixelColor(loc.x - 5, loc.y - 5);
+        if (FG_COLOR.getRGB() == color.getRGB())
+            throw new RuntimeException("Background is not translucent (" + color + ")");
+
+        EventQueue.invokeAndWait(this::dispose);
+        robot.waitForIdle();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JWindow/ShapedAndTranslucentWindows/PerPixelTranslucentGradient.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.*;
+
+/*
+ * @test
+ * @bug 8032644
+ * @summary Check if a per-pixel translucent window is dragged and resized by
+ *          mouse correctly
+ * Test Description: Check if PERPIXEL_TRANSLUCENT translucency type is supported
+ *      on the current platform. Proceed if they are supported. Create a window
+ *      with some components in it, make window undecorated, apply translucent
+ *      background of 0 and have a gradient painted as background from
+ *      fully-transparent to fully-opaque in componentResized listener. Drag and
+ *      resize the window using AWT Robot and verify that translucency is
+ *      correctly applied with pixels checking. Make the window appear on top of
+ *      a known background. Repeat this for JWindow, JDialog, JFrame.
+ * Expected Result: If PERPIXEL_TRANSLUCENT translucency type is supported,
+ *      the window should appear as specified with the translucency. Only window
+ *      background should be translucent, all the controls should be opaque.
+ * @author mrkam
+ * @library ../../../../lib/testlibrary
+ * @build Common ExtendedRobot
+ * @run main PerPixelTranslucentGradient
+ */
+
+public class PerPixelTranslucentGradient extends Common {
+
+    public static void main(String[] ignored) throws Exception {
+        if (checkTranslucencyMode(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSLUCENT))
+            for (Class<Window> windowClass: WINDOWS_TO_TEST)
+                new PerPixelTranslucentGradient(windowClass).doTest();
+    }
+
+    public PerPixelTranslucentGradient(Class windowClass) throws Exception {
+        super(windowClass, 1.0f, 0f, true);
+    }
+
+    public void doTest() throws Exception {
+        robot.waitForIdle(delay);
+        checkTranslucent();
+    }
+
+    @Override
+    public void applyShape() {
+        gradientWidth = window.getWidth();
+        gradientHeight = window.getHeight();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JWindow/ShapedAndTranslucentWindows/PerPixelTranslucentSwing.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.swing.*;
+import java.awt.*;
+
+/*
+ * @test
+ * @summary Check if a per-pixel translucent window shows only the area having
+ *          opaque pixels
+ * Test Description: Check if PERPIXEL_TRANSLUCENT Translucency type is supported
+ *      on the current platform. Proceed if it is supported. Create a swing window
+ *      with some swing components in it and a transparent background (alpha 0.0).
+ *      Bring this window on top of a known background. Do this test for JFrame,
+ *      JWindow and JDialog
+ * Expected Result: Only the components present in the window must be shown. Other
+ *      areas of the window must be transparent so that the background shows
+ * @author mrkam
+ * @library ../../../../lib/testlibrary
+ * @build Common ExtendedRobot
+ * @run main PerPixelTranslucentSwing
+ */
+
+public class PerPixelTranslucentSwing extends Common {
+
+    JButton north;
+
+    public static void main(String[] ignored) throws Exception {
+        FG_COLOR = new Color(200, 0, 0, 0);
+        if (checkTranslucencyMode(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSLUCENT))
+            for (Class<Window> windowClass: WINDOWS_TO_TEST)
+                new PerPixelTranslucentSwing(windowClass).doTest();
+    }
+
+    public PerPixelTranslucentSwing(Class windowClass) throws Exception {
+        super(windowClass);
+    }
+
+    @Override
+    public void createSwingComponents() {
+        Container contentPane = RootPaneContainer.class.cast(window).getContentPane();
+        BorderLayout bl = new BorderLayout(10, 5);
+        contentPane.setLayout(bl);
+
+        north = new JButton("North");
+        contentPane.add(north, BorderLayout.NORTH);
+
+        JList center = new JList(new String[] {"Center"});
+        contentPane.add(center, BorderLayout.CENTER);
+
+        JTextField south = new JTextField("South");
+        contentPane.add(south, BorderLayout.SOUTH);
+
+        window.pack();
+        window.setVisible(true);
+
+        north.requestFocus();
+    }
+
+    @Override
+    public void doTest() throws Exception {
+        robot.waitForIdle(delay);
+
+        // Check for background translucency
+        Rectangle bounds = north.getBounds();
+        Point loc = north.getLocationOnScreen();
+
+        Color color = robot.getPixelColor(loc.x + bounds.width / 2, loc.y + bounds.height + 3);
+        System.out.println(color);
+        if (FG_COLOR.getRGB() == color.getRGB())
+            throw new RuntimeException("Background is not translucent (" + color + ")");
+
+        EventQueue.invokeAndWait(this::dispose);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JWindow/ShapedAndTranslucentWindows/SetShapeAndClickSwing.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.geom.Area;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Rectangle2D;
+
+/*
+ * @test
+ * @summary Check if a window set with shape clips the contents
+ * Test Description: Check if PERPIXEL_TRANSPARENT translucency type is supported
+ *      by the current platform. Proceed if it is supported. Apply different types
+ *      of shapes on a Window which contains some awt components. Shape should be
+ *      applied in such a way that some components are partially clipped off. Check
+ *      if the components appear only partially and events work correctly for those
+ *      components - i.e. events occur only on the areas which appear and do not
+ *      occur on the clipped off areas. Events should be checked by clicking on the
+ *      visible and clipped regions. Repeat this for Window, Dialog and Frame.
+ * Expected Result: If PERPIXEL_TRANSPARENT translucency type is supported, clicking
+ *      on clipped region should deliver the event to the background (it should be
+ *      another Window behind the test window)
+ * @author mrkam
+ * @library ../../../../lib/testlibrary
+ * @build Common ExtendedRobot
+ * @run main SetShapeAndClickSwing
+ */
+
+public class SetShapeAndClickSwing extends Common {
+
+    Component south, center, north;
+
+    public static void main(String[] args) throws Exception {
+        if (checkTranslucencyMode(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSPARENT))
+            for (Class<Window> windowClass: WINDOWS_TO_TEST)
+                new SetShapeAndClickSwing(windowClass).doTest();
+    }
+
+    public SetShapeAndClickSwing(Class windowClass) throws Exception {
+        super(windowClass);
+    }
+
+    @Override
+    public void initBackgroundFrame() {
+        super.initBackgroundFrame();
+        background.addMouseListener(new MouseAdapter() {
+            @Override
+            public void mouseClicked(MouseEvent e) {
+                clicked |= 1 << 0;
+            }
+        });
+    }
+
+    @Override
+    public void createSwingComponents() {
+        window.setSize(200,200);
+        window.setLayout(new BorderLayout());
+
+        south = new JLabel("South");
+        south.addMouseListener(new MouseAdapter() {
+            @Override
+            public void mouseClicked(MouseEvent e) {
+                clicked |= 1 << 3;
+            }
+        });
+        window.add(south, BorderLayout.SOUTH);
+
+        center = new JList();
+        center.addMouseListener(new MouseAdapter() {
+            @Override
+            public void mouseClicked(MouseEvent e) {
+                clicked |= 1 << 2;
+            }
+        });
+        window.add(center, BorderLayout.CENTER);
+
+        north = new JTextField("North");
+        north.addMouseListener(new MouseAdapter() {
+            @Override
+            public void mouseClicked(MouseEvent e) {
+                clicked |= 1 << 1;
+            }
+        });
+        window.add(north, BorderLayout.NORTH);
+    }
+
+    @Override
+    public void doTest() throws Exception {
+
+        robot.waitForIdle();
+
+        Point wls = window.getLocationOnScreen();
+        Point ls;
+        int y;
+        ls = north.getLocationOnScreen();
+        checkClick(ls.x + north.getWidth() / 3, ls.y + north.getHeight() / 2, 1);
+
+        ls = center.getLocationOnScreen();
+        checkClick(ls.x + center.getWidth() * 3 / 4, ls.y + center.getHeight() * 3 / 4, 2);
+
+        ls = south.getLocationOnScreen();
+        checkClick(ls.x + south.getWidth() * 2 / 3, ls.y + south.getHeight() / 2, 3);
+
+        ls = center.getLocationOnScreen();
+        checkClick(ls.x + center.getWidth() / 4, ls.y + center.getHeight() / 4, 2);
+
+        ls = north.getLocationOnScreen();
+        y = ls.y + north.getHeight() / 2;
+        checkClick(wls.x + 200 - (y - wls.y), y, 0);
+
+        EventQueue.invokeAndWait(window::toFront);
+        robot.waitForIdle();
+
+        ls = center.getLocationOnScreen();
+        y = ls.y + center.getHeight() / 2;
+        checkClick(wls.x + 200 - (y - wls.y), y, 0);
+
+        EventQueue.invokeAndWait(window::toFront);
+        robot.waitForIdle();
+
+        ls = south.getLocationOnScreen();
+        y = ls.y + south.getHeight() / 2;
+        checkClick(wls.x + 200 - (y - wls.y), y, 0);
+
+        EventQueue.invokeAndWait(window::dispose);
+        EventQueue.invokeAndWait(background::dispose);
+
+        robot.waitForIdle();
+    }
+
+    @Override
+    public void applyShape() {
+        Area shape = new Area(new Rectangle2D.Float(0, 0, 200, 200));
+        GeneralPath gp;
+        gp = new GeneralPath();
+        gp.moveTo(190, 0);
+        gp.lineTo(200, 0);
+        gp.lineTo(200, 10);
+        gp.lineTo(10, 200);
+        gp.lineTo(0, 200);
+        gp.lineTo(0, 190);
+        gp.closePath();
+        shape.subtract(new Area(gp));
+
+        window.setShape(shape);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JWindow/ShapedAndTranslucentWindows/ShapedPerPixelTranslucentGradient.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.*;
+
+/*
+ * @test
+ * @bug 7043845
+ * @summary Check if shaped and per-pixel translucent window is dragged and
+ *          resized by mouse correctly.
+ * Test Description: Check if PERPIXEL_TRANSLUCENT and PERPIXEL_TRANSPARENT
+ *      translucency types are supported on the current platform. Proceed if
+ *      they are supported. Create a window with some components in it, make
+ *      window undecorated, apply shape in componentResized listener. The shape
+ *      should match the window size; apply translucent background of 0 and have
+ *      a gradient painted as background from fully-transparent to fully-opaque
+ *      in componentResized listener. Drag and resize the window using AWT Robot
+ *      and verify that shape and translucency are correctly applied with pixels
+ *      checking. Make the window appear on top of a known background. Repeat
+ *      this for JWindow, JDialog, JFrame.
+ * Expected Result: If PERPIXEL_TRANSLUCENT and PERPIXEL_TRANSPARENT translucency
+ *      types are supported, the window should appear as specified with the
+ *      expected shape and translucency. Window background should have
+ *      translucent gradient in parts that are not clipped by shape, all the
+ *      controls should be opaque.
+ * @author mrkam
+ * @library ../../../../lib/testlibrary
+ * @build Common ExtendedRobot
+ * @run main ShapedPerPixelTranslucentGradient
+ */
+
+public class ShapedPerPixelTranslucentGradient extends Common {
+
+    public static void main(String[] ignored) throws Exception {
+        if (checkTranslucencyMode(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSLUCENT)
+            && checkTranslucencyMode(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSPARENT))
+            for (Class<Window> windowClass: WINDOWS_TO_TEST)
+                new ShapedPerPixelTranslucentGradient(windowClass).doTest();
+    }
+
+    public ShapedPerPixelTranslucentGradient(Class windowClass) throws Exception {
+        super(windowClass, 1.0f, 0f, true);
+    }
+
+    public void doTest() throws Exception {
+        robot.waitForIdle(delay);
+        checkDynamic();
+    }
+
+    @Override
+    public void applyShape() {
+        applyDynamicShape();
+        gradientWidth = window.getWidth();
+        gradientHeight = window.getHeight();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JWindow/ShapedAndTranslucentWindows/ShapedTranslucentPerPixelTranslucentGradient.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.*;
+
+/*
+ * @test
+ * @summary Check if shaped, translucent and per-pixel translucent window is
+ *          dragged and resized by mouse correctly.
+ * Test Description: Check if PERPIXEL_TRANSLUCENT, TRANSLUCENT and
+ *      PERPIXEL_TRANSPARENT translucency types are supported on the current
+ *      platform. Proceed if they are supported. Create a window with some
+ *      components in it, make window undecorated, apply shape in componentResized
+ *      listener. The shape should match the window size; apply opacity of 0.7,
+ *      apply translucent background of 0 and have a gradient painted as
+ *      background from fully-transparent to fully-opaque in componentResized
+ *      listener. Drag and resize the window using AWT Robot and verify that
+ *      shape and translucency are correctly applied with pixels checking. Make
+ *      the window appear on top of a known background. Repeat this for JWindow,
+ *      JDialog, JFrame.
+ * Expected Result: If PERPIXEL_TRANSLUCENT, TRANSLUCENT and PERPIXEL_TRANSPARENT
+ *      translucency types are supported, the window should appear as specified
+ *      with the expected shape and translucency. Window background should have
+ *      translucent gradient in parts that are not clipped by shape, all the
+ *      controls should be equally translucent.
+ * @author mrkam
+ * @library ../../../../lib/testlibrary
+ * @build Common ExtendedRobot
+ * @run main ShapedTranslucentPerPixelTranslucentGradient
+ */
+
+public class ShapedTranslucentPerPixelTranslucentGradient extends Common {
+
+    public static void main(String[] ignored) throws Exception {
+        if (checkTranslucencyMode(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSLUCENT)
+            && checkTranslucencyMode(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSPARENT)
+            && checkTranslucencyMode(GraphicsDevice.WindowTranslucency.TRANSLUCENT))
+            for (Class<Window> windowClass: WINDOWS_TO_TEST)
+                new ShapedTranslucentPerPixelTranslucentGradient(windowClass).doTest();
+    }
+
+    public ShapedTranslucentPerPixelTranslucentGradient(Class windowClass) throws Exception {
+        super(windowClass, 0.7f, 0f, true);
+    }
+
+    public void doTest() throws Exception {
+        robot.waitForIdle(delay);
+        checkDynamic();
+    }
+
+    @Override
+    public void applyShape() {
+        applyDynamicShape();
+        gradientWidth = window.getWidth();
+        gradientHeight = window.getHeight();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JWindow/ShapedAndTranslucentWindows/TranslucentJComboBox.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+
+/*
+ * @test
+ * @bug 8024627
+ * @summary Check if a JComboBox present in a window set with opacity less than
+ *          1.0 shows a translucent drop down
+ * Test Description: Check if TRANSLUCENT translucency type is supported on the
+ *      current platform. Proceed if supported. Show a window which contains an
+ *      JComboBox and set with opacity less than 1.0. Another Window having a canvas
+ *      component drawn with an image can be used as the background for the test
+ *      window. Click on the ComboBox to show the drop down. Check if the drop down
+ *      appears translucent. Repeat this for JWindow, JDialog and JFrame
+ * Expected Result: If TRANSLUCENT Translucency type is supported, the drop down
+ *      should appear translucent.
+ * @author mrkam
+ * @library ../../../../lib/testlibrary
+ * @build Common ExtendedRobot
+ * @run main TranslucentJComboBox
+ */
+
+public class TranslucentJComboBox extends Common {
+
+    JComponent south;
+    JComponent center;
+    JPanel north;
+    volatile boolean southClicked = false;
+
+    public static void main(String[] args) throws Exception {
+        if (checkTranslucencyMode(GraphicsDevice.WindowTranslucency.TRANSLUCENT))
+            for (Class<Window> windowClass: WINDOWS_TO_TEST)
+                new TranslucentJComboBox(windowClass).doTest();
+    }
+
+    public TranslucentJComboBox(Class windowClass) throws Exception {
+        super(windowClass, 0.3f, 1.0f, false);
+    }
+
+    @Override
+    public void initBackgroundFrame() {
+        super.initBackgroundFrame();
+    }
+
+    @Override
+    public void createSwingComponents() {
+        Container contentPane = RootPaneContainer.class.cast(window).getContentPane();
+        window.setLayout(new BorderLayout());
+
+        north = new JPanel();
+        contentPane.add(north, BorderLayout.NORTH);
+
+        center = new JList(new String [] { "Center" });
+        contentPane.add(center, BorderLayout.CENTER);
+
+        JComboBox jComboBox = new JComboBox();
+        for(int i = 0; i < 20; i++) {
+            jComboBox.addItem("item " + i);
+        }
+        south = jComboBox;
+
+        south.addMouseListener(new MouseAdapter() {
+            @Override
+            public void mouseClicked(MouseEvent e) {
+                southClicked = true;
+            }
+        });
+        contentPane.add(south, BorderLayout.SOUTH);
+    }
+
+
+    @Override
+    public void doTest() throws Exception {
+        robot.waitForIdle(delay);
+        // Make window an active
+        Point ls = north.getLocationOnScreen();
+        robot.mouseMove(ls.x + north.getWidth()/2, ls.y + north.getHeight()/2);
+        robot.click();
+
+        // Invoke list
+        ls = south.getLocationOnScreen();
+
+        Point p1 = new Point(
+                (int) (ls.x + south.getWidth() * 0.75),
+                ls.y + south.getHeight() * 3);
+
+        Point p2 = new Point(
+                (int) (ls.x + south.getWidth() * 0.75),
+                ls.y - south.getHeight() * 2);
+
+        Color c1 = robot.getPixelColor(p1.x, p1.y);
+        Color c2 = robot.getPixelColor(p2.x, p2.y);
+
+        int x = ls.x + south.getWidth()/2;
+        int y = ls.y + south.getHeight()/2;
+
+        System.out.println("Trying to click point "+x+", "+y+
+                ", looking for flag to trigger.");
+
+        robot.mouseMove(x, y);
+        robot.waitForIdle(delay);
+        robot.click();
+        robot.waitForIdle(delay);
+
+        if (!southClicked)
+            throw new RuntimeException("Flag is not triggered for point "+x+", "+y+"!");
+
+        robot.waitForIdle();
+
+        Color c1b = robot.getPixelColor(p1.x, p1.y);
+        Color c2b = robot.getPixelColor(p2.x, p2.y);
+
+        if (!c1.equals(c1b) && !south.getBackground().equals(c1b))
+            throw new RuntimeException(
+                    "Check for opaque drop down failed at point " + p1 +
+                            ". Before click: " + c1 + ", after click: " + c1b +
+                            ", expected is " + south.getBackground());
+
+        if (!c2.equals(c2b) && !south.getBackground().equals(c2b))
+            throw new RuntimeException(
+                    "Check for opaque drop down failed at point " + p2 +
+                            ". Before click: " + c2 + ", after click: " + c2b +
+                            ", expected is " + south.getBackground());
+
+        EventQueue.invokeAndWait(this::dispose);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JWindow/ShapedAndTranslucentWindows/TranslucentPerPixelTranslucentGradient.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.*;
+
+/*
+ * @test
+ * @summary Check if a per-pixel translucent and translucent window is dragged
+ *          and resized by mouse correctly
+ * Test Description: Check if PERPIXEL_TRANSLUCENT and TRANSLUCENT translucency
+ *      types are supported on the current platform. Proceed if they are supported.
+ *      Create a window with some components in it, make window undecorated, apply
+ *      opacity of 0.7, apply translucent background of 0 and have a gradient
+ *      painted as background from fully-transparent to fully-opaque in
+ *      componentResized listener. Drag and resize the window using AWT Robot and
+ *      verify that translucency is correctly applied with pixels checking. Make
+ *      the window appear on top of a known background. Repeat this for specified
+ *      JWindow, JDialog, JFrame.
+ * Expected Result: If PERPIXEL_TRANSLUCENT and TRANSLUCENT translucency types
+ *      are supported, the window should appear as specified with the translucency.
+ *      Both window background and all the controls should be translucent but
+ *      background should have a gradient in translucency while controls - not.
+ * @author mrkam
+ * @library ../../../../lib/testlibrary
+ * @build Common ExtendedRobot
+ * @run main TranslucentPerPixelTranslucentGradient
+ */
+
+public class TranslucentPerPixelTranslucentGradient extends Common {
+
+    public static void main(String[] ignored) throws Exception {
+        if (checkTranslucencyMode(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSLUCENT)
+            && checkTranslucencyMode(GraphicsDevice.WindowTranslucency.TRANSLUCENT))
+            for (Class<Window> windowClass: WINDOWS_TO_TEST)
+                new TranslucentPerPixelTranslucentGradient(windowClass).doTest();
+    }
+
+    public TranslucentPerPixelTranslucentGradient(Class windowClass) throws Exception {
+        super(windowClass, 0.7f, 0f, true);
+    }
+
+    public void doTest() throws Exception {
+        robot.waitForIdle(delay);
+        checkTranslucent();
+    }
+
+    @Override
+    public void applyShape() {
+        gradientWidth = window.getWidth();
+        gradientHeight = window.getHeight();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JWindow/ShapedAndTranslucentWindows/TranslucentWindowClickSwing.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+
+/*
+ * @test
+ * @summary Check if swing components present in a window set with opacity less
+ *          than 1.0 appears translucent
+ * Test Description: Check if TRANSLUCENT Translucency type is supported for the
+ *      current platform. Proceed if supported. Show a window containing some swing
+ *      components and set it with opacity less than 1.0. Check if the swing components
+ *      appear translucent and check if events trigger correctly for the components
+ * Expected Result: If TRANSLUCENT Translucency type is supported, the components
+ *      should appear translucent showing the background. They should trigger events
+ *      correctly
+ * @author mrkam
+ * @library ../../../../lib/testlibrary
+ * @build Common ExtendedRobot
+ * @run main TranslucentWindowClickSwing
+ */
+
+public class TranslucentWindowClickSwing extends Common {
+
+    private Component south;
+    private Component center;
+    private Component north;
+
+    public static void main(String[] args) throws Exception{
+        if (checkTranslucencyMode(GraphicsDevice.WindowTranslucency.TRANSLUCENT))
+            new TranslucentWindowClickSwing(JWindow.class).doTest();
+    }
+
+    public TranslucentWindowClickSwing(Class windowClass) throws Exception {
+        super(windowClass, 0.2f, 1.0f, false);
+    }
+
+    @Override
+    public void createSwingComponents() {
+        south = new JButton("South");
+        south.addMouseListener(new MouseAdapter() {
+            @Override
+            public void mouseClicked(MouseEvent e) { clicked |= 1 << 2; }
+        });
+        window.add(south, BorderLayout.SOUTH);
+
+        center = new JList();
+        center.addMouseListener(new MouseAdapter() {
+            @Override
+            public void mouseClicked(MouseEvent e) { clicked |= 1 << 1; }
+        });
+        window.add(center, BorderLayout.CENTER);
+
+        north = new JTextField("North");
+        north.addMouseListener(new MouseAdapter() {
+            @Override
+            public void mouseClicked(MouseEvent e) { clicked |= 1 << 0; }
+        });
+        window.add(north, BorderLayout.NORTH);
+    }
+
+    @Override
+    public void doTest() throws Exception {
+        Point ls;
+        robot.waitForIdle();
+
+        ls = north.getLocationOnScreen();
+        checkClick(ls.x + north.getWidth() / 3, ls.y + north.getHeight() / 2, 0);
+
+        ls = center.getLocationOnScreen();
+        checkClick(ls.x + center.getWidth() / 4, ls.y + center.getHeight() / 4, 1);
+
+        ls = center.getLocationOnScreen();
+        checkClick(ls.x + center.getWidth() * 3 / 4, ls.y + center.getHeight() * 3 / 4, 1);
+
+        ls = south.getLocationOnScreen();
+        checkClick(ls.x + south.getWidth() * 2 / 3, ls.y + south.getHeight() / 2, 2);
+
+        EventQueue.invokeAndWait(this::dispose);
+        robot.waitForIdle();
+    }
+}
--- a/jdk/test/lib/testlibrary/jsr292/com/oracle/testlibrary/jsr292/Helper.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/test/lib/testlibrary/jsr292/com/oracle/testlibrary/jsr292/Helper.java	Wed Jul 05 20:01:50 2017 +0200
@@ -52,7 +52,7 @@
     public static final long TEST_LIMIT;
     static {
         String str = System.getProperty("testLimit");
-        TEST_LIMIT = str != null ? Long.parseUnsignedLong(str) : 2_000L;
+        TEST_LIMIT = str != null ? Long.parseUnsignedLong(str) : 2000L;
         System.out.printf("-DtestLimit=%d%n", TEST_LIMIT);
     }
 
@@ -116,6 +116,48 @@
         return size <= lag ? null : calledLog.get(size - lag - 1);
     }
 
+    public static List<Class<?>> randomClasses(Class<?>[] classes, int size) {
+        List<Class<?>> result = new ArrayList<>(size);
+        for (int i = 0; i < size; ++i) {
+            result.add(classes[RNG.nextInt(classes.length)]);
+        }
+        return result;
+    }
+
+    public static List<Class<?>> getParams(List<Class<?>> classes,
+            boolean isVararg, int argsCount) {
+        boolean unmodifiable = true;
+        List<Class<?>> result = classes.subList(0,
+                Math.min(argsCount, (MAX_ARITY / 2) - 1));
+        int extra = 0;
+        if (argsCount >= MAX_ARITY / 2) {
+            result = new ArrayList<>(result);
+            unmodifiable = false;
+            extra = (int) result.stream().filter(Helper::isDoubleCost).count();
+            int i = result.size();
+            while (result.size() + extra < argsCount) {
+                Class<?> aClass = classes.get(i);
+                if (Helper.isDoubleCost(aClass)) {
+                    ++extra;
+                    if (result.size() + extra >= argsCount) {
+                        break;
+                    }
+                }
+                result.add(aClass);
+            }
+        }
+        if (isVararg && result.size() > 0) {
+            if (unmodifiable) {
+                result = new ArrayList<>(result);
+            }
+            int last = result.size() - 1;
+            Class<?> aClass = result.get(last);
+            aClass = Array.newInstance(aClass, 2).getClass();
+            result.set(last, aClass);
+        }
+        return result;
+    }
+
     public static MethodHandle addTrailingArgs(MethodHandle target, int nargs,
             List<Class<?>> classes) {
         int targetLen = target.type().parameterCount();
@@ -230,7 +272,7 @@
         return randomArgs(params.toArray(new Class<?>[params.size()]));
     }
 
-    private static Object castToWrapper(Object value, Class<?> dst) {
+    public static Object castToWrapper(Object value, Class<?> dst) {
         Object wrap = null;
         if (value instanceof Number) {
             wrap = castToWrapperOrNull(((Number) value).longValue(), dst);
@@ -268,7 +310,7 @@
         if (dst == byte.class || dst == Byte.class) {
             return (byte) (value);
         }
-        if (dst == boolean.class || dst == boolean.class) {
+        if (dst == boolean.class || dst == Boolean.class) {
             return ((value % 29) & 1) == 0;
         }
         return null;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/java2d/OpenGL/DrawHugeImageTest.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * @test
+ * @bug     8040617
+ * @summary Test verifies that an attempt to get an accelerated copy of
+ *          a huge buffered image does not result in an OOME.
+ *
+ * @run     main DrawHugeImageTest
+ */
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.image.BufferedImage;
+import java.awt.image.VolatileImage;
+
+public class DrawHugeImageTest {
+    // we have to render the BI source several times in order
+    // to get an accelerated copy to be used.
+    static {
+        System.setProperty("sun.java2d.accthreshold", "1");
+    }
+    private static final int max_rendering_count = 5;
+
+    private static final Color srcColor = Color.red;
+    private static final Color dstColor = Color.blue;
+
+    public static void main(String[] args) {
+        BufferedImage src = createSrc();
+
+        VolatileImage dst = createDst();
+        System.out.println("Dst: " + dst);
+        boolean status;
+        int count = max_rendering_count;
+
+        do {
+            System.out.println("render image: " + (max_rendering_count - count));
+            status = render(src, dst);
+
+        } while (status && count-- > 0);
+
+        if (!status || count > 0) {
+            throw new RuntimeException("Test failed: " + count);
+        }
+    }
+
+    private static boolean render(BufferedImage src, VolatileImage dst) {
+        int cnt = 5;
+        do {
+            Graphics2D g = dst.createGraphics();
+            g.setColor(dstColor);
+            g.fillRect(0, 0, dst.getWidth(), dst.getHeight());
+            g.drawImage(src, 0, 0, null);
+            g.dispose();
+        } while (dst.contentsLost() && (--cnt > 0));
+
+        if (cnt == 0) {
+            System.err.println("Test failed: unable to render to volatile destination");
+            return false;
+        }
+
+        BufferedImage s = dst.getSnapshot();
+
+        return s.getRGB(1,1) == srcColor.getRGB();
+    }
+
+    private static BufferedImage createSrc() {
+        final int w = 20000;
+        final int h = 5;
+
+        BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR);
+        Graphics2D g = img.createGraphics();
+        g.setColor(srcColor);
+        g.fillRect(0, 0, w, h);
+        g.dispose();
+
+        return img;
+    }
+
+    private static VolatileImage createDst() {
+        GraphicsConfiguration gc =
+                GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
+
+        return gc.createCompatibleVolatileImage(200, 200);
+    }
+}
--- a/jdk/test/sun/security/krb5/auto/Context.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/test/sun/security/krb5/auto/Context.java	Wed Jul 05 20:01:50 2017 +0200
@@ -22,15 +22,14 @@
  */
 
 import com.sun.security.auth.module.Krb5LoginModule;
-import java.security.Key;
+
+import java.lang.reflect.Method;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
 import java.util.Arrays;
-import java.util.Base64;
 import java.util.HashMap;
 import java.util.Map;
 import javax.security.auth.Subject;
-import javax.security.auth.kerberos.KerberosCredMessage;
 import javax.security.auth.kerberos.KerberosKey;
 import javax.security.auth.kerberos.KerberosTicket;
 import javax.security.auth.login.LoginContext;
@@ -41,10 +40,6 @@
 import org.ietf.jgss.GSSName;
 import org.ietf.jgss.MessageProp;
 import org.ietf.jgss.Oid;
-import com.sun.security.jgss.ExtendedGSSContext;
-import com.sun.security.jgss.InquireType;
-import com.sun.security.jgss.AuthorizationDataEntry;
-import com.sun.security.jgss.ExtendedGSSCredential;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.security.Principal;
@@ -78,7 +73,7 @@
 public class Context {
 
     private Subject s;
-    private ExtendedGSSContext x;
+    private GSSContext x;
     private String name;
     private GSSCredential cred;     // see static method delegated().
 
@@ -143,7 +138,6 @@
     /**
      * Logins with username/password as an existing Subject. The
      * same subject can be used multiple times to simulate multiple logins.
-     * @param s existing subject
      */
     public static Context fromUserPass(Subject s,
             String user, char[] pass, boolean storeKey) throws Exception {
@@ -222,7 +216,7 @@
             @Override
             public byte[] run(Context me, byte[] dummy) throws Exception {
                 GSSManager m = GSSManager.getInstance();
-                me.x = (ExtendedGSSContext)m.createContext(
+                me.x = m.createContext(
                           target.indexOf('@') < 0 ?
                             m.createName(target, null) :
                             m.createName(target, GSSName.NT_HOSTBASED_SERVICE),
@@ -267,7 +261,7 @@
                         asInitiator?
                                 GSSCredential.INITIATE_AND_ACCEPT:
                                 GSSCredential.ACCEPT_ONLY);
-                me.x = (ExtendedGSSContext)m.createContext(me.cred);
+                me.x = m.createContext(me.cred);
                 return null;
             }
         }, null);
@@ -285,7 +279,7 @@
      *
      * @return the GSSContext object
      */
-    public ExtendedGSSContext x() {
+    public GSSContext x() {
         return x;
     }
 
@@ -339,7 +333,7 @@
      */
     public void status() throws Exception {
         System.out.println("STATUS OF " + name.toUpperCase());
-        try {
+        if (x != null) {
             StringBuffer sb = new StringBuffer();
             if (x.getAnonymityState()) {
                 sb.append("anon, ");
@@ -362,19 +356,15 @@
             if (x.getSequenceDetState()) {
                 sb.append("seq det, ");
             }
-            if (x instanceof ExtendedGSSContext) {
-                if (((ExtendedGSSContext)x).getDelegPolicyState()) {
-                    sb.append("deleg policy, ");
-                }
+            System.out.println("   Context status of " + name + ": " + sb.toString());
+            if (x.isProtReady() || x.isEstablished()) {
+                System.out.println("   " + x.getSrcName() + " -> " + x.getTargName());
             }
-            System.out.println("Context status of " + name + ": " + sb.toString());
-            System.out.println(x.getSrcName() + " -> " + x.getTargName());
-        } catch (Exception e) {
-            ;// Don't care
         }
+        xstatus();
         if (s != null) {
             System.out.println("====== START SUBJECT CONTENT =====");
-            for (Principal p: s.getPrincipals()) {
+            for (Principal p : s.getPrincipals()) {
                 System.out.println("    Principal: " + p);
             }
             for (Object o : s.getPublicCredentials()) {
@@ -405,51 +395,42 @@
             }
             System.out.println("====== END SUBJECT CONTENT =====");
         }
-        if (x != null && x instanceof ExtendedGSSContext) {
-            if (x.isEstablished()) {
-                ExtendedGSSContext ex = (ExtendedGSSContext)x;
-                Key k = (Key)ex.inquireSecContext(
-                        InquireType.KRB5_GET_SESSION_KEY);
-                if (k == null) {
-                    throw new Exception("(Old) Session key cannot be null");
-                }
-                System.out.println("(Old) Session key is: " + k);
-                Key k2 = (Key)ex.inquireSecContext(
-                        InquireType.KRB5_GET_SESSION_KEY_EX);
-                if (k2 == null) {
-                    throw new Exception("Session key cannot be null");
-                }
-                System.out.println("Session key is: " + k);
-                boolean[] flags = (boolean[])ex.inquireSecContext(
-                        InquireType.KRB5_GET_TKT_FLAGS);
-                if (flags == null) {
-                    throw new Exception("Ticket flags cannot be null");
+    }
+
+    public void xstatus() throws Exception {
+        System.out.println("   Extended context status:");
+        if (x != null) {
+            try {
+                Class<?> clazz = Class.forName("com.sun.security.jgss.ExtendedGSSContext");
+                if (clazz.isAssignableFrom(x.getClass())) {
+                    if (clazz.getMethod("getDelegPolicyState").invoke(x) == Boolean.TRUE) {
+                        System.out.println("   deleg policy");
+                    }
+                    if (x.isEstablished()) {
+                        Class<?> inqType = Class.forName("com.sun.security.jgss.InquireType");
+                        Method inqMethod = clazz.getMethod("inquireSecContext", inqType);
+                        for (Object o : inqType.getEnumConstants()) {
+                            System.out.println("   " + o + ":");
+                            try {
+                                System.out.println("      " + inqMethod.invoke(x, o));
+                            } catch (Exception e) {
+                                System.out.println(e.getCause());
+                            }
+                        }
+                    }
                 }
-                System.out.println("Ticket flags is: " + Arrays.toString(flags));
-                String authTime = (String)ex.inquireSecContext(
-                        InquireType.KRB5_GET_AUTHTIME);
-                if (authTime == null) {
-                    throw new Exception("Auth time cannot be null");
-                }
-                System.out.println("AuthTime is: " + authTime);
-                if (!x.isInitiator()) {
-                    AuthorizationDataEntry[] ad = (AuthorizationDataEntry[])ex.inquireSecContext(
-                            InquireType.KRB5_GET_AUTHZ_DATA);
-                    System.out.println("AuthzData is: " + Arrays.toString(ad));
+            } catch (ClassNotFoundException cnfe) {
+                System.out.println("   -- ExtendedGSSContext not available");
+            }
+        }
+        if (cred != null) {
+            try {
+                Class<?> clazz2 = Class.forName("com.sun.security.jgss.ExtendedGSSCredential");
+                if (!clazz2.isAssignableFrom(cred.getClass())) {
+                    throw new Exception("cred is not extended");
                 }
-                try {
-                    KerberosCredMessage tok = (KerberosCredMessage)ex.inquireSecContext(
-                            InquireType.KRB5_GET_KRB_CRED);
-                    System.out.println("KRB_CRED is " +
-                            (tok == null?"not ":"") + "available");
-                    if (tok != null) {
-                        System.out.println("From " + tok.getSender() + " to "
-                                + tok.getRecipient());
-                        System.out.println(Base64.getEncoder().encodeToString(tok.getEncoded()));
-                    }
-                } catch (Exception e) {
-                    System.out.println("KRB_CRED is not available: " + e);
-                }
+            } catch (ClassNotFoundException cnfe) {
+                System.out.println("   -- ExtendedGSSCredential not available");
             }
         }
     }
@@ -591,7 +572,10 @@
                     if (Context.this.cred == null) {
                         Context.this.cred = m.createCredential(GSSCredential.INITIATE_ONLY);
                     }
-                    return ((ExtendedGSSCredential)Context.this.cred).impersonate(other);
+                    return (GSSCredential)
+                            Class.forName("com.sun.security.jgss.ExtendedGSSCredential")
+                            .getMethod("impersonate", GSSName.class)
+                            .invoke(Context.this.cred, other);
                 }
             });
             Context out = new Context();
--- a/jdk/test/sun/security/krb5/auto/NewInquireTypes.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/test/sun/security/krb5/auto/NewInquireTypes.java	Wed Jul 05 20:01:50 2017 +0200
@@ -29,6 +29,7 @@
  * @run main/othervm NewInquireTypes
  */
 
+import com.sun.security.jgss.ExtendedGSSContext;
 import com.sun.security.jgss.InquireType;
 import sun.security.jgss.GSSUtil;
 import sun.security.krb5.internal.KRBCred;
@@ -52,10 +53,12 @@
 
         Context.handshake(c, s);
 
+        ExtendedGSSContext ctxt = (ExtendedGSSContext)c.x();
         EncryptionKey key = (EncryptionKey)
-                c.x().inquireSecContext(InquireType.KRB5_GET_SESSION_KEY_EX);
+                ctxt.inquireSecContext(InquireType.KRB5_GET_SESSION_KEY_EX);
         KerberosCredMessage cred = (KerberosCredMessage)
-                c.x().inquireSecContext(InquireType.KRB5_GET_KRB_CRED);
+                ctxt.inquireSecContext(InquireType.KRB5_GET_KRB_CRED);
+        c.status();
 
         // Confirm the KRB_CRED message is encrypted with the session key.
         new KRBCred(cred.getEncoded()).encPart.decrypt(
--- a/jdk/test/sun/security/krb5/auto/OkAsDelegate.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/test/sun/security/krb5/auto/OkAsDelegate.java	Wed Jul 05 20:01:50 2017 +0200
@@ -48,6 +48,7 @@
  * @summary Support OK-AS-DELEGATE flag
  */
 import com.sun.security.jgss.ExtendedGSSContext;
+import org.ietf.jgss.GSSContext;
 import org.ietf.jgss.GSSCredential;
 import org.ietf.jgss.GSSException;
 import org.ietf.jgss.Oid;
@@ -102,7 +103,7 @@
         cx.requestCredDeleg(requestDelegState);
         cx.requestDelegPolicy(requestDelegPolicyState);
         s.startAsServer(mech);
-        ExtendedGSSContext sx = (ExtendedGSSContext)s.x();
+        GSSContext sx = s.x();
 
         Context.handshake(c, s);
 
--- a/jdk/test/sun/security/krb5/auto/OkAsDelegateXRealm.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/test/sun/security/krb5/auto/OkAsDelegateXRealm.java	Wed Jul 05 20:01:50 2017 +0200
@@ -42,6 +42,8 @@
 import javax.security.auth.callback.NameCallback;
 import javax.security.auth.callback.PasswordCallback;
 import javax.security.auth.callback.UnsupportedCallbackException;
+
+import com.sun.security.jgss.ExtendedGSSContext;
 import org.ietf.jgss.GSSException;
 import sun.security.jgss.GSSUtil;
 import sun.security.krb5.Config;
@@ -129,7 +131,7 @@
         for (int i=0; i<2; i++) {
             c.startAsClient("host@host.r3.local", GSSUtil.GSS_KRB5_MECH_OID);
             s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
-            c.x().requestDelegPolicy(true);
+            ((ExtendedGSSContext)c.x()).requestDelegPolicy(true);
 
             Context.handshake(c, s);
             boolean succeed = true;
--- a/jdk/test/sun/security/krb5/auto/SSL.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/jdk/test/sun/security/krb5/auto/SSL.java	Wed Jul 05 20:01:50 2017 +0200
@@ -186,13 +186,13 @@
             // Client checks "initiate", then server gets the name
             // and checks "accept". Second connection resume.
             if (!permChecks.equals("IA")) {
-                throw new Exception();
+                throw new Exception(permChecks);
             }
         } else {
             // For bound, JAAS checks "accept" once. Server checks again,
             // client then checks "initiate". Second connection resume.
             if (!permChecks.equals("AAI")) {
-                throw new Exception();
+                throw new Exception(permChecks);
             }
         }
     }
--- a/langtools/.hgtags	Wed Jul 05 20:01:05 2017 +0200
+++ b/langtools/.hgtags	Wed Jul 05 20:01:50 2017 +0200
@@ -273,3 +273,4 @@
 016786f793149135ab6b23c71087c1ca12691d77 jdk9-b28
 13705e2ddeb20a78e066595a1709e61f257189e9 jdk9-b29
 ef5427c13e1e741c457a2ed868e3b6d6bf717754 jdk9-b30
+0046d55383a9d873ffbc7253d7c5e28ab98c5bea jdk9-b31
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java	Wed Jul 05 20:01:50 2017 +0200
@@ -358,11 +358,9 @@
             for (Type aLowerBound : from.getBounds(InferenceBound.LOWER)) {
                 for (Type anotherLowerBound : from.getBounds(InferenceBound.LOWER)) {
                     if (aLowerBound != anotherLowerBound &&
-                        commonSuperWithDiffParameterization(aLowerBound, anotherLowerBound)) {
-                        /* self comment check if any lower bound may be and undetVar,
-                         * in that case the result of this call may be a false positive.
-                         * Should this be restricted to non free types?
-                         */
+                            !inferenceContext.free(aLowerBound) &&
+                            !inferenceContext.free(anotherLowerBound) &&
+                            commonSuperWithDiffParameterization(aLowerBound, anotherLowerBound)) {
                         return generateReferenceToTargetConstraint(tree, from, to,
                             resultInfo, inferenceContext);
                     }
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java	Wed Jul 05 20:01:50 2017 +0200
@@ -397,20 +397,19 @@
         Content htmlComment = new Comment(configuration.getText("doclet.New_Page"));
         Content head = new HtmlTree(HtmlTag.HEAD);
         head.addContent(getGeneratedBy(!configuration.notimestamp));
-        if (configuration.charset.length() > 0) {
-            Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE,
-                    configuration.charset);
-            head.addContent(meta);
-        }
         head.addContent(getTitle());
+        Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE,
+                (configuration.charset.length() > 0) ?
+                        configuration.charset : HtmlConstants.HTML_DEFAULT_CHARSET);
+        head.addContent(meta);
         if (!configuration.notimestamp) {
             SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
-            Content meta = HtmlTree.META("date", dateFormat.format(new Date()));
+            meta = HtmlTree.META("date", dateFormat.format(new Date()));
             head.addContent(meta);
         }
         if (metakeywords != null) {
             for (String metakeyword : metakeywords) {
-                Content meta = HtmlTree.META("keywords", metakeyword);
+                meta = HtmlTree.META("keywords", metakeyword);
                 head.addContent(meta);
             }
         }
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/PackageWriterImpl.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/PackageWriterImpl.java	Wed Jul 05 20:01:50 2017 +0200
@@ -90,8 +90,7 @@
      * {@inheritDoc}
      */
     public Content getPackageHeader(String heading) {
-        String pkgName = packageDoc.name();
-        Content bodyTree = getBody(true, getWindowTitle(pkgName));
+        Content bodyTree = getBody(true, getWindowTitle(utils.getPackageName(packageDoc)));
         addTop(bodyTree);
         addNavLinks(true, bodyTree);
         HtmlTree div = new HtmlTree(HtmlTag.DIV);
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageWriterImpl.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageWriterImpl.java	Wed Jul 05 20:01:50 2017 +0200
@@ -103,8 +103,7 @@
      * {@inheritDoc}
      */
     public Content getPackageHeader(String heading) {
-        String pkgName = packageDoc.name();
-        Content bodyTree = getBody(true, getWindowTitle(pkgName));
+        Content bodyTree = getBody(true, getWindowTitle(utils.getPackageName(packageDoc)));
         addTop(bodyTree);
         addNavLinks(true, bodyTree);
         HtmlTree div = new HtmlTree(HtmlTag.DIV);
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlConstants.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlConstants.java	Wed Jul 05 20:01:50 2017 +0200
@@ -220,4 +220,9 @@
      * Html tag for the member heading.
      */
     public static final HtmlTag MEMBER_HEADING = HtmlTag.H4;
+
+    /**
+     * Default charset for HTML.
+     */
+    public static final String HTML_DEFAULT_CHARSET = "utf-8";
 }
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java	Wed Jul 05 20:01:50 2017 +0200
@@ -311,13 +311,12 @@
         Content htmlComment = new Comment(configuration.getText("doclet.New_Page"));
         Content head = new HtmlTree(HtmlTag.HEAD);
         head.addContent(getGeneratedBy(!noTimeStamp));
-        if (configuration.charset.length() > 0) {
-            Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE,
-                    configuration.charset);
-            head.addContent(meta);
-        }
         Content windowTitle = HtmlTree.TITLE(new StringContent(title));
         head.addContent(windowTitle);
+        Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE,
+                (configuration.charset.length() > 0) ?
+                        configuration.charset : HtmlConstants.HTML_DEFAULT_CHARSET);
+        head.addContent(meta);
         head.addContent(getFramesetJavaScript());
         Content htmlTree = HtmlTree.HTML(configuration.getLocale().getLanguage(),
                 head, frameset);
--- a/langtools/test/com/sun/javadoc/testCharset/TestCharset.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testCharset/TestCharset.java	Wed Jul 05 20:01:50 2017 +0200
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug      7052170
+ * @bug      7052170 8047745
  * @summary  Run a test on -charset to make sure the charset gets generated as a
  *           part of the meta tag.
  * @author   Bhavesh Patel
@@ -42,19 +42,32 @@
     @Test
     void test() {
         javadoc("-d", "out",
-                "-charset", "UTF-8",
+                "-charset", "ISO-8859-1",
                 "-sourcepath", testSrc,
                 "pkg");
         checkExit(Exit.OK);
 
         checkOutput("index.html", true,
-            "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");
+            "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\">");
         checkOutput("pkg/Foo.html", true,
-            "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");
+            "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\">");
 
         checkOutput("index.html", false,
-            "<meta http-equiv=\"Content-Type\" content=\"text/html\" charset=\"UTF-8\">");
+            "<meta http-equiv=\"Content-Type\" content=\"text/html\" charset=\"ISO-8859-1\">");
         checkOutput("pkg/Foo.html", false,
-            "<meta http-equiv=\"Content-Type\" content=\"text/html\" charset=\"UTF-8\">");
+            "<meta http-equiv=\"Content-Type\" content=\"text/html\" charset=\"ISO-8859-1\">");
+    }
+
+    @Test
+    void test1() {
+        javadoc("-d", "out-1",
+                "-sourcepath", testSrc,
+                "pkg");
+        checkExit(Exit.OK);
+
+        checkOutput("index.html", true,
+            "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">");
+        checkOutput("pkg/Foo.html", true,
+            "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">");
     }
 }
--- a/langtools/test/com/sun/javadoc/testUnnamedPackage/TestUnnamedPackage.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testUnnamedPackage/TestUnnamedPackage.java	Wed Jul 05 20:01:50 2017 +0200
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug      4904075 4774450 5015144
+ * @bug      4904075 4774450 5015144 8043698
  * @summary  Reference unnamed package as "Unnamed", not empty string.
  *           Generate a package summary for the unnamed package.
  * @author   jamieh
@@ -51,6 +51,9 @@
                 "This is a package comment for the unnamed package.",
                 "This is a class in the unnamed package.");
 
+        checkOutput("package-summary.html", true,
+                "<title>&lt;Unnamed&gt;</title>");
+
         checkOutput("package-tree.html", true,
                 "<h1 class=\"title\">Hierarchy For Package &lt;Unnamed&gt;</h1>");
 
--- a/langtools/test/tools/javac/Parens1.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/langtools/test/tools/javac/Parens1.java	Wed Jul 05 20:01:50 2017 +0200
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
  * @bug 4391330
  * @summary compiler accepted (Integer).toString(123)
  * @author gafter
  *
- * @compile/fail Parens1.java
+ * @compile/fail/ref=Parens1.out -XDrawDiagnostics Parens1.java
  */
 
 class Parens1 {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/Parens1.out	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,2 @@
+Parens1.java:12:20: compiler.err.illegal.start.of.type
+1 error
--- a/langtools/test/tools/javac/Parens2.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/langtools/test/tools/javac/Parens2.java	Wed Jul 05 20:01:50 2017 +0200
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
  * @bug 4408036
  * @summary Compiler accepted "(i=2);" as a valid expession statement.
  * @author gafter
  *
- * @compile/fail Parens2.java
+ * @compile/fail/ref=Parens2.out -XDrawDiagnostics Parens2.java
  */
 
 class Parens2 {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/Parens2.out	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,2 @@
+Parens2.java:13:9: compiler.err.not.stmt
+1 error
--- a/langtools/test/tools/javac/Parens3.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/langtools/test/tools/javac/Parens3.java	Wed Jul 05 20:01:50 2017 +0200
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
  * @bug 4394546
  * @summary get no err msg if label wrapped in parentheses
  * @author gafter
  *
- * @compile/fail Parens3.java
+ * @compile/fail/ref=Parens3.out -XDrawDiagnostics Parens3.java
  */
 
 class Parens3 {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/Parens3.out	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,3 @@
+Parens3.java:12:5: compiler.err.not.stmt
+Parens3.java:12:10: compiler.err.expected: ';'
+2 errors
--- a/langtools/test/tools/javac/Parens4.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/langtools/test/tools/javac/Parens4.java	Wed Jul 05 20:01:50 2017 +0200
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
  * @bug 4933317
  * @summary javac accepts parens in package names
  * @author gafter
  *
- * @compile/fail Parens4.java
+ * @compile/fail/ref=Parens4.out -XDrawDiagnostics Parens4.java
  */
 
 class Parens4 {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/Parens4.out	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,2 @@
+Parens4.java:12:16: compiler.err.illegal.start.of.type
+1 error
--- a/langtools/test/tools/javac/ParseConditional.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/langtools/test/tools/javac/ParseConditional.java	Wed Jul 05 20:01:50 2017 +0200
@@ -1,34 +1,11 @@
 /*
- * Copyright (c) 1997, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
  * @bug 4092958
  * @summary The compiler was too permissive in its parsing of conditional
  *          expressions.
  * @author turnidge
  *
- * @compile/fail ParseConditional.java
+ * @compile/fail/ref=ParseConditional.out -XDrawDiagnostics ParseConditional.java
  */
 
 public class ParseConditional {
@@ -38,6 +15,11 @@
         int b = 2;
         int c = 3;
         int d = 4;
-        a = condition ? b = c : c = d; // Should get a parse error.
+        // The following line should give an error because the conditional ?: operator
+        // is higher priority than the final assignment operator, between c and d.
+        // As such, the correct parsing is:
+        //   a = (condition ? b = c : c) = d;
+        // and it is illegal to try and assign to the value of the conditional expression.
+        a = condition ? b = c : c = d;
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/ParseConditional.out	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,2 @@
+ParseConditional.java:23:23: compiler.err.unexpected.type: kindname.variable, kindname.value
+1 error
--- a/langtools/test/tools/javac/StoreClass.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/langtools/test/tools/javac/StoreClass.java	Wed Jul 05 20:01:50 2017 +0200
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
  * @bug 4350352
  * @summary InternalError: store unsupported: com.sun.tools.javac.v8.comp.Items
  * @author gafter
  *
- * @compile/fail StoreClass.java
+ * @compile/fail/ref=StoreClass.out -XDrawDiagnostics StoreClass.java
  */
 
 class StoreClass {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/StoreClass.out	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,3 @@
+StoreClass.java:12:19: compiler.err.cant.assign.val.to.final.var: class
+StoreClass.java:13:12: compiler.err.cant.assign.val.to.final.var: class
+2 errors
--- a/langtools/test/tools/javac/SwitchScope.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/langtools/test/tools/javac/SwitchScope.java	Wed Jul 05 20:01:50 2017 +0200
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
  * @bug 4725650
  * @summary Restrict scope of local classes in switch-block-group
  * @author gafter
  *
- * @compile/fail SwitchScope.java
+ * @compile/fail/ref=SwitchScope.out -XDrawDiagnostics SwitchScope.java
  */
 
 public class SwitchScope {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/SwitchScope.out	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,2 @@
+SwitchScope.java:22:28: compiler.err.cant.resolve.location: kindname.class, Local, , , (compiler.misc.location: kindname.class, SwitchScope, null)
+1 error
--- a/langtools/test/tools/javac/SynthName2.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/langtools/test/tools/javac/SynthName2.java	Wed Jul 05 20:01:50 2017 +0200
@@ -1,38 +1,15 @@
 /*
- * Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
  * @bug 4462714
  * @summary using of synthetic names in local class causes ClassFormatError
  * @author gafter
  *
- * @compile/fail SynthName2.java
+ * @compile/fail/ref=SynthName2.out -XDrawDiagnostics SynthName2.java
  */
 
 import java.io.PrintStream;
 
-class SynthName1 {
+class SynthName2 {
     public static void main(String args[]) {
         run(args, System.out);
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/SynthName2.out	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,4 @@
+SynthName2.java:33:9: compiler.err.synthetic.name.conflict: val$zzz, InnClass
+SynthName2.java:34:17: compiler.err.synthetic.name.conflict: val$prm1, InnClass
+SynthName2.java:35:17: compiler.err.synthetic.name.conflict: val$zzz, InnClass
+3 errors
--- a/langtools/test/tools/javac/T6234077.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/langtools/test/tools/javac/T6234077.java	Wed Jul 05 20:01:50 2017 +0200
@@ -1,30 +1,7 @@
 /*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
+ * @test /nodynamiccopyright/
+ * @bug 6234077
+ * @compile/fail/ref=T6234077.out -XDrawDiagnostics T6234077.java
  */
 
-/*
- * @test
- * @bug 6234077
- * @compile/fail T6234077.java
- */
-@Deprecated /** @deprecated */
 public class Foo { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T6234077.out	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,2 @@
+T6234077.java:7:8: compiler.err.class.public.should.be.in.file: Foo
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/8055963/T8055963.java	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8055963
+ * @summary Inference failure with nested invocation
+ * @compile T8055963.java
+ */
+class T8055963 {
+
+    static class C<T> {}
+
+    <T> T choose(T first, T second) { return null; }
+
+    void test() {
+        C<String> cs = choose(new C<String>(), new C<>());
+    }
+}
--- a/make/HotspotWrapper.gmk	Wed Jul 05 20:01:05 2017 +0200
+++ b/make/HotspotWrapper.gmk	Wed Jul 05 20:01:50 2017 +0200
@@ -42,7 +42,7 @@
 # not doing it breaks builds on msys.
 $(HOTSPOT_OUTPUTDIR)/_hotspot.timestamp: $(HOTSPOT_FILES)
 	@$(MKDIR) -p $(HOTSPOT_OUTPUTDIR)
-	@($(CD) $(HOTSPOT_TOPDIR)/make && $(MAKE) -j1 $(HOTSPOT_MAKE_ARGS) SPEC=$(HOTSPOT_SPEC) BASE_SPEC=$(BASE_SPEC))
+	@($(CD) $(HOTSPOT_TOPDIR)/make && $(MAKE) $(HOTSPOT_MAKE_ARGS) SPEC=$(HOTSPOT_SPEC) BASE_SPEC=$(BASE_SPEC))
 	$(TOUCH) $@
 
 hotspot: $(HOTSPOT_OUTPUTDIR)/_hotspot.timestamp
--- a/make/Main.gmk	Wed Jul 05 20:01:05 2017 +0200
+++ b/make/Main.gmk	Wed Jul 05 20:01:50 2017 +0200
@@ -298,7 +298,9 @@
 # Verification targets
 
 verify-modules:
+	@$(call TargetEnter)
 	+($(CD) $(SRC_ROOT)/make && $(MAKE) $(MAKE_ARGS) -f CheckModules.gmk)
+	@$(call TargetExit)
 
 ALL_TARGETS += verify-modules
 
@@ -400,7 +402,7 @@
     main-jars: java.security.jgss-libs
   endif
 
-  images: jars demos samples exploded-image source-tips
+  images: jars demos samples exploded-image verify-modules source-tips
 
   bootcycle-images: images
 
@@ -476,7 +478,7 @@
 
 ################################################################################
 
-all: images docs verify-modules
+all: images docs
 default: exploded-image
 
 ALL_TARGETS += default all
@@ -491,7 +493,7 @@
 # file.
 
 CLEAN_COMPONENTS += langtools corba hotspot jdk nashorn images \
-    bootcycle-build docs docstemp test
+    bootcycle-build docs docstemp test make-support
 CLEAN_TARGETS := $(addprefix clean-, $(CLEAN_COMPONENTS))
 
 # Remove everything, except the output from configure.
--- a/make/common/Modules.gmk	Wed Jul 05 20:01:05 2017 +0200
+++ b/make/common/Modules.gmk	Wed Jul 05 20:01:50 2017 +0200
@@ -26,6 +26,9 @@
 ifndef _MODULES_GMK
 _MODULES_GMK := 1
 
+include JavaCompilation.gmk
+include SetupJavaCompilers.gmk
+
 ################################################################################
 # Module list macros
 
@@ -50,8 +53,32 @@
           $(patsubst %,%/*/$(OPENJDK_TARGET_OS)/classes/*, $(ALL_TOP_SRC_DIRS))))))))))))
 endef
 
-MODULES_LIST_FILE := $(SRC_ROOT)/make/common/modules.list
-MODULE_DEPS_MAKEFILE := $(OUTPUT_ROOT)/module-deps.gmk
+# Find all modules with source for the target platform.
+define FindAllModules
+  $(sort $(filter-out closed demo sample, $(notdir $(patsubst %/,%, $(dir \
+      $(wildcard $(patsubst %, %/*/share, $(ALL_TOP_SRC_DIRS)) \
+      $(patsubst %, %/*/$(OPENJDK_TARGET_OS), $(ALL_TOP_SRC_DIRS)) \
+      $(patsubst %, %/*/$(OPENJDK_TARGET_OS_API_DIR), $(ALL_TOP_SRC_DIRS))))))))
+endef
+
+################################################################################
+
+$(eval $(call SetupJavaCompilation,BUILD_GENMODULESLIST, \
+    SETUP := BOOT_JAVAC, \
+    SRC := $(JDK_TOPDIR)/make/src/classes, \
+    INCLUDES := build/tools/module, \
+    BIN := $(MAKESUPPORT_OUTPUTDIR)/bt_classes_moduleslist))
+
+TOOL_GENMODULESLIST = $(JAVA_SMALL) \
+    -cp "$(MAKESUPPORT_OUTPUTDIR)/bt_classes_moduleslist" \
+    build.tools.module.GenModulesList
+
+MODULES_LIST_FILE := $(MAKESUPPORT_OUTPUTDIR)/modules.list
+MODULE_DEPS_MAKEFILE := $(MAKESUPPORT_OUTPUTDIR)/module-deps.gmk
+
+$(MODULES_LIST_FILE): $(SRC_ROOT)/modules.xml \
+    $(BUILD_GENMODULESLIST)
+	$(TOOL_GENMODULESLIST) -o $@ $(filter %.xml, $^)
 
 $(MODULE_DEPS_MAKEFILE): $(MODULES_LIST_FILE)
 	$(CAT) $^ | $(SED) -e 's/^\([^:]*\):/DEPS_\1 :=/g' > $@
@@ -63,14 +90,6 @@
   $(DEPS_$(strip $1))
 endef
 
-# Find all modules with source for the target platform.
-define FindAllModules
-  $(sort $(filter-out closed demo sample, $(notdir $(patsubst %/,%, $(dir \
-      $(wildcard $(patsubst %, %/*/share, $(ALL_TOP_SRC_DIRS)) \
-      $(patsubst %, %/*/$(OPENJDK_TARGET_OS), $(ALL_TOP_SRC_DIRS)) \
-      $(patsubst %, %/*/$(OPENJDK_TARGET_OS_API_DIR), $(ALL_TOP_SRC_DIRS))))))))
-endef
-
 ################################################################################
 
 # Hook to include the corresponding custom file, if present.
--- a/make/common/SetupJavaCompilers.gmk	Wed Jul 05 20:01:05 2017 +0200
+++ b/make/common/SetupJavaCompilers.gmk	Wed Jul 05 20:01:50 2017 +0200
@@ -34,6 +34,12 @@
 # make JAVAC_WARNINGS="-Xlint:all -Xmaxwarns 10000"
 JAVAC_WARNINGS := -Xlint:all,-deprecation -Werror
 
+# The BOOT_JAVAC setup uses the boot jdk compiler to compile the tools
+# and the interim javac, to be run by the boot jdk.
+$(eval $(call SetupJavaCompiler,BOOT_JAVAC, \
+    JAVAC := $(JAVAC), \
+    FLAGS := -XDignore.symbol.file=true -g -Xlint:all$(COMMA)-deprecation -Werror))
+
 # Any java code executed during a JDK build to build other parts of the JDK must be 
 # executed by the bootstrap JDK (probably with -Xbootclasspath/p: ) and for this 
 # purpose must be built with -target PREVIOUS for bootstrapping purposes, which 
--- a/make/common/modules.list	Wed Jul 05 20:01:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-java.base: 
-java.logging: java.base
-java.security.sasl: java.logging java.base
-java.naming: java.security.sasl java.base
-java.security.acl: java.base
-jdk.charsets: java.base
-java.scripting: java.base
-java.xml: java.base
-java.sql: java.xml java.logging java.base
-jdk.scripting.nashorn: java.scripting java.logging java.base
-java.rmi: java.logging java.base
-java.prefs: java.xml java.base
-java.desktop: jdk.charsets java.prefs java.xml java.logging java.base
-java.corba: java.naming java.rmi java.desktop java.logging java.base
-java.compiler: java.logging java.base
-jdk.compiler: java.compiler java.base
-jdk.javadoc: java.compiler java.xml jdk.compiler java.base
-jdk.rmic: java.corba jdk.compiler jdk.javadoc java.base
-jdk.jvmstat: java.rmi java.base
-jdk.attach: jdk.jvmstat java.base
-jdk.jcmd: jdk.jvmstat jdk.attach java.base
-jdk.jdi: jdk.attach java.base
-jdk.hotspot.agent: java.rmi java.scripting java.desktop java.base jdk.jdi
-jdk.hprof.agent: java.base
-java.management: java.naming java.rmi java.logging java.base
-jdk.jconsole: java.management jdk.jvmstat java.rmi jdk.attach java.desktop java.logging java.base
-java.activation: java.desktop java.logging java.base
-java.xml.bind: java.activation java.compiler java.xml java.desktop java.logging java.base
-jdk.xml.bind: java.activation java.compiler java.xml.bind java.xml java.desktop java.logging jdk.compiler java.base
-jdk.httpserver: java.logging java.base
-java.annotations.common: java.base
-java.xml.soap: java.activation java.xml.bind java.xml java.desktop java.logging java.base
-java.xml.ws: java.activation java.management jdk.httpserver java.rmi java.annotations.common java.xml.bind java.xml java.desktop java.logging java.xml.soap java.base
-jdk.xml.ws: jdk.xml.bind java.compiler java.rmi java.xml.ws java.xml.bind java.xml java.logging java.base
-java.sql.rowset: java.naming java.sql java.xml java.logging java.base
-java.instrument: java.base
-java.security.jgss: java.naming java.security.sasl java.logging java.base
-java.xml.crypto: java.xml java.logging java.base
-jdk.localedata: java.base
-jdk.crypto.ec: java.base
-jdk.crypto.pkcs11: jdk.crypto.ec java.base
-jdk.crypto.mscapi: java.base
-jdk.naming.rmi: java.naming java.rmi java.base
-jdk.zipfs: java.base
-jdk.naming.dns: java.naming java.base
-java.smartcardio: java.base
-jdk.dev: jdk.xml.bind jdk.xml.ws java.scripting jdk.rmic java.xml jdk.compiler java.base
-jdk.snmp: java.management java.security.acl java.logging java.base
-jdk.jdwp.agent: java.base
-jdk.security.auth: java.naming java.security.jgss java.base
-jdk.sctp: java.base
-jdk.runtime: java.desktop java.base
-jdk.jfr: java.management java.xml java.base
-jdk.deploy.osx: java.scripting java.desktop java.base
--- a/modules.xml	Wed Jul 05 20:01:05 2017 +0200
+++ b/modules.xml	Wed Jul 05 20:01:50 2017 +0200
@@ -243,6 +243,7 @@
       <to>java.rmi</to>
       <to>java.security.jgss</to>
       <to>java.security.sasl</to>
+      <to>java.sql</to>
       <to>jdk.charsets</to>
       <to>jdk.deploy.osx</to>
       <to>jdk.dev</to>
@@ -250,6 +251,7 @@
       <to>jdk.jvmstat</to>
       <to>jdk.runtime</to>
       <to>jdk.security.auth</to>
+      <to>jdk.security.jgss</to>
     </export>
     <export>
       <name>sun.net.dns</name>
@@ -326,6 +328,7 @@
     </export>
     <export>
       <name>sun.security.internal.spec</name>
+      <to>jdk.crypto.mscapi</to>
       <to>jdk.crypto.pkcs11</to>
       <to>jdk.crypto.ucrypto</to>
     </export>
@@ -730,6 +733,10 @@
     <export>
       <name>javax.swing.undo</name>
     </export>
+    <export>
+      <name>sun.awt</name>
+      <to>oracle.accessbridge</to>
+    </export>
   </module>
   <module>
     <name>java.instrument</name>
@@ -900,12 +907,7 @@
   <module>
     <name>java.security.jgss</name>
     <depend>java.base</depend>
-    <depend>java.logging</depend>
     <depend>java.naming</depend>
-    <depend>java.security.sasl</depend>
-    <export>
-      <name>com.sun.security.jgss</name>
-    </export>
     <export>
       <name>javax.security.auth.kerberos</name>
     </export>
@@ -924,6 +926,14 @@
       <name>sun.security.krb5.internal.ktab</name>
       <to>jdk.security.auth</to>
     </export>
+    <export>
+      <name>sun.security.jgss</name>
+      <to>jdk.security.jgss</to>
+    </export>
+    <export>
+      <name>sun.security.krb5.internal</name>
+      <to>jdk.security.jgss</to>
+    </export>
   </module>
   <module>
     <name>java.security.sasl</name>
@@ -934,7 +944,7 @@
     </export>
     <export>
       <name>com.sun.security.sasl.util</name>
-      <to>java.security.jgss</to>
+      <to>jdk.security.jgss</to>
     </export>
   </module>
   <module>
@@ -1570,6 +1580,10 @@
     </export>
   </module>
   <module>
+    <name>jdk.crypto.mscapi</name>
+    <depend>java.base</depend>
+  </module>
+  <module>
     <name>jdk.crypto.pkcs11</name>
     <depend>java.base</depend>
     <depend>jdk.crypto.ec</depend>
@@ -1752,6 +1766,16 @@
     </export>
   </module>
   <module>
+    <name>jdk.security.jgss</name>
+    <depend>java.base</depend>
+    <depend>java.logging</depend>
+    <depend re-exports="true">java.security.jgss</depend>
+    <depend>java.security.sasl</depend>
+    <export>
+      <name>com.sun.security.jgss</name>
+    </export>
+  </module>
+  <module>
     <name>jdk.xml.bind</name>
     <depend>java.activation</depend>
     <depend>java.base</depend>
--- a/nashorn/.hgtags	Wed Jul 05 20:01:05 2017 +0200
+++ b/nashorn/.hgtags	Wed Jul 05 20:01:50 2017 +0200
@@ -264,3 +264,4 @@
 00c31e5eaf26f9b238165157b9d1c617b03abcb6 jdk9-b28
 e541ebaf2ab7038333ad0c13f4decd327c26dd15 jdk9-b29
 072dbed6c5d968a6b9e156c36cd8838b4ff86ea1 jdk9-b30
+77efdecfa2a5c28672b7c7dcc2d1b52dcb90d493 jdk9-b31
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FieldObjectCreator.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FieldObjectCreator.java	Wed Jul 05 20:01:50 2017 +0200
@@ -231,7 +231,7 @@
             if (symbol != null) {
                 if (hasArguments() && symbol.isParam()) {
                     symbol.setFieldIndex(paramCount++);
-                } else {
+                } else if (!isValidArrayIndex(getArrayIndex(tuple.key))) {
                     symbol.setFieldIndex(fieldCount++);
                 }
             }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java	Wed Jul 05 20:01:50 2017 +0200
@@ -439,8 +439,8 @@
 
     // current ScriptContext to use - can be null.
     private ScriptContext scontext;
-    // associated Property object for "context" property.
-    private jdk.nashorn.internal.runtime.Property scontextProperty;
+    // current ScriptEngine associated - can be null.
+    private ScriptEngine engine;
 
     /**
      * Set the current script context
@@ -448,7 +448,6 @@
      */
     public void setScriptContext(final ScriptContext scontext) {
         this.scontext = scontext;
-        scontextProperty.setValue(this, this, scontext, false);
     }
 
     // global constants for this global - they can be replaced with MethodHandle.constant until invalidated
@@ -581,6 +580,7 @@
             return;
         }
 
+        this.engine = engine;
         init(engine);
     }
 
@@ -917,6 +917,13 @@
             }
         }
 
+        switch (nameStr) {
+            case "context":
+                return sctxt;
+            case "engine":
+                return global.engine;
+        }
+
         if (self == UNDEFINED) {
             // scope access and so throw ReferenceError
             throw referenceError(global, "not.defined", nameStr);
@@ -1789,9 +1796,6 @@
         }
 
         if (engine != null) {
-            final int NOT_ENUMERABLE_NOT_CONFIG = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE;
-            scontextProperty = addOwnProperty("context", NOT_ENUMERABLE_NOT_CONFIG, null);
-            addOwnProperty("engine", NOT_ENUMERABLE_NOT_CONFIG, engine);
             // default file name
             addOwnProperty(ScriptEngine.FILENAME, Attribute.NOT_ENUMERABLE, null);
             // __noSuchProperty__ hook for ScriptContext search of missing variables
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java	Wed Jul 05 20:01:50 2017 +0200
@@ -54,6 +54,7 @@
 import static jdk.nashorn.internal.parser.TokenType.TERNARY;
 import static jdk.nashorn.internal.parser.TokenType.WHILE;
 
+import java.io.Serializable;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -2977,11 +2978,13 @@
      * Encapsulates part of the state of the parser, enough to reconstruct the state of both parser and lexer
      * for resuming parsing after skipping a function body.
      */
-    private static class ParserState {
+    private static class ParserState implements Serializable {
         private final int position;
         private final int line;
         private final int linePosition;
 
+        private static final long serialVersionUID = -2382565130754093694L;
+
         ParserState(final int position, final int line, final int linePosition) {
             this.position = position;
             this.line = line;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/AccessorProperty.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/AccessorProperty.java	Wed Jul 05 20:01:50 2017 +0200
@@ -119,7 +119,7 @@
      *   produce different boun method handles wrapping the same access mechanism
      *   depending on callsite
      */
-    private MethodHandle[] GETTER_CACHE = new MethodHandle[NOOF_TYPES];
+    private transient MethodHandle[] GETTER_CACHE = new MethodHandle[NOOF_TYPES];
 
     /**
      * Create a new accessor property. Factory method used by nasgen generated code.
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Property.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Property.java	Wed Jul 05 20:01:50 2017 +0200
@@ -101,7 +101,7 @@
     private final int slot;
 
     /** SwitchPoint that is invalidated when property is changed, optional */
-    protected SwitchPoint changeCallback;
+    protected transient SwitchPoint changeCallback;
 
     private static final long serialVersionUID = 2099814273074501176L;
 
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyMap.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyMap.java	Wed Jul 05 20:01:50 2017 +0200
@@ -568,9 +568,7 @@
         for (final Property property : otherProperties) {
             // This method is only safe to use with non-slotted, native getter/setter properties
             assert property.getSlot() == -1;
-            if (isValidArrayIndex(getArrayIndex(property.getKey()))) {
-                newMap.setContainsArrayKeys();
-            }
+            assert !(isValidArrayIndex(getArrayIndex(property.getKey())));
         }
 
         return newMap;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java	Wed Jul 05 20:01:50 2017 +0200
@@ -125,6 +125,15 @@
 
         @Override
         public Comparison compareConversion(final Class<?> sourceType, final Class<?> targetType1, final Class<?> targetType2) {
+            if (sourceType == ConsString.class) {
+                if (String.class == targetType1 || CharSequence.class == targetType1) {
+                    return Comparison.TYPE_1_BETTER;
+                }
+
+                if (String.class == targetType2 || CharSequence.class == targetType2) {
+                    return Comparison.TYPE_2_BETTER;
+                }
+            }
             return linkerServices.compareConversion(sourceType, targetType1, targetType2);
         }
     }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java	Wed Jul 05 20:01:50 2017 +0200
@@ -131,11 +131,16 @@
             }
             return getInvocation(EMPTY_ELEM_GETTER, self, linkerServices, desc);
         case "setProp":
-        case "setElem":
+        case "setElem": {
+            final boolean strict = NashornCallSiteDescriptor.isStrict(desc);
+            if (strict) {
+                throw typeError("cant.set.property", getArgument(linkRequest), ScriptRuntime.safeToString(self));
+            }
             if (desc.getOperand() != null) {
                 return getInvocation(EMPTY_PROP_SETTER, self, linkerServices, desc);
             }
             return getInvocation(EMPTY_ELEM_SETTER, self, linkerServices, desc);
+        }
         default:
             break;
         }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Messages.properties	Wed Jul 05 20:01:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Messages.properties	Wed Jul 05 20:01:50 2017 +0200
@@ -92,7 +92,7 @@
 
 # other wrong usages of property
 type.error.property.has.no.setter=Cannot set property "{0}" of {1} that has only a getter
-type.error.cant.set.proto.to.non.object=Cannot set Object {0}'s __proto__ to be a non-object like {1}
+type.error.cant.set.proto.to.non.object=Cannot set Object {0}''s __proto__ to be a non-object like {1}
 type.error.no.such.function={1} has no such function "{0}"
 type.error.no.such.java.class=No such Java class: {0}
 type.error.no.such.java.constructor=No such Java constructor: {0}
@@ -125,10 +125,10 @@
 type.error.cant.load.script=Cannot load script from {0}
 type.error.JSON.stringify.cyclic=JSON.stringify got a cyclic data structure
 type.error.cant.convert.string.to.char=Cannot convert string to character; its length must be exactly 1
-type.error.cant.convert.number.to.char=Cannot convert number to character; it's out of 0-65535 range
+type.error.cant.convert.number.to.char=Cannot convert number to character; it is out of 0-65535 range
 type.error.cant.convert.to.java.string=Cannot convert object of type {0} to a Java argument of string type
 type.error.cant.convert.to.java.number=Cannot convert object of type {0} to a Java argument of number type
-type.error.cant.convert.to.javascript.array=Can only convert Java arrays and lists to JavaScript arrays. Can't convert object of type {0}.
+type.error.cant.convert.to.javascript.array=Can only convert Java arrays and lists to JavaScript arrays. Cannot convert object of type {0}.
 type.error.extend.expects.at.least.one.argument=Java.extend needs at least one argument.
 type.error.extend.expects.at.least.one.type.argument=Java.extend needs at least one type argument.
 type.error.extend.expects.java.types=Java.extend needs Java types as its arguments.
@@ -141,10 +141,10 @@
 type.error.extend.ERROR_FINAL_FINALIZER=Can not extend class because {0} has a final finalize method.
 type.error.no.constructor.matches.args=Can not construct {0} with the passed arguments; they do not match any of its constructor signatures.
 type.error.no.method.matches.args=Can not invoke method {0} with the passed arguments; they do not match any of its method signatures.
-type.error.method.not.constructor=Java method {0} can't be used as a constructor.
+type.error.method.not.constructor=Java method {0} cannot be used as a constructor.
 type.error.env.not.object=$ENV must be an Object.
 type.error.unsupported.java.to.type=Unsupported Java.to target type {0}.
-type.error.constructor.requires.new=Constructor {0} requires 'new'.
+type.error.constructor.requires.new=Constructor {0} requires "new".
 type.error.new.on.nonpublic.javatype=new cannot be used with non-public java type {0}.
 
 range.error.dataview.constructor.offset=Wrong offset or length in DataView constructor
--- a/nashorn/test/script/basic/JDK-8043232.js	Wed Jul 05 20:01:05 2017 +0200
+++ b/nashorn/test/script/basic/JDK-8043232.js	Wed Jul 05 20:01:50 2017 +0200
@@ -29,14 +29,14 @@
  */
 
 // call explicit constructor
-print(new (java.awt["Color(int,int,int)"])(255,0,255));
+print(new (java.lang["String(char[],int,int)"])(['a','b', 'c', 'd'], 1, 3));
 // print the constructor itself
-print(java.awt["Color(int,int,int)"]);
+print(java.lang["String(char[],int,int)"]);
 
 // store constructor to call later
-var Color = java.awt["Color(int,int,int)"];
+var Color = java.lang["String(char[],int,int)"];
 // call stored constructor
-print(new Color(33, 233, 2))
+print(new Color(['r','r', 'e', 'd'], 1, 3))
 
 // check if default constructor works
 var obj = new (java.lang["Object()"])();
--- a/nashorn/test/script/basic/JDK-8043232.js.EXPECTED	Wed Jul 05 20:01:05 2017 +0200
+++ b/nashorn/test/script/basic/JDK-8043232.js.EXPECTED	Wed Jul 05 20:01:50 2017 +0200
@@ -1,14 +1,14 @@
-java.awt.Color[r=255,g=0,b=255]
-[jdk.internal.dynalink.beans.SimpleDynamicMethod Color java.awt.Color.java.awt.Color(int,int,int)]
-java.awt.Color[r=33,g=233,b=2]
+bcd
+[jdk.internal.dynalink.beans.SimpleDynamicMethod String java.lang.String.java.lang.String(char[],int,int)]
+red
 TypeError: No such Java class: java.lang.NonExistent
 TypeError: No such Java constructor: Object(String)
 TypeError: Java constructor signature invalid: Object()xxxxx
 TypeError: Java constructor signature invalid: Object(
 TypeError: Java constructor signature invalid: Object)
-TypeError: Java method [jdk.internal.dynalink.beans.OverloadedDynamicMethod java.lang.System.getProperty] cant be used as a constructor.
-TypeError: Java method [jdk.internal.dynalink.beans.OverloadedDynamicMethod java.io.PrintStream.println] cant be used as a constructor.
-TypeError: Constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod Color java.awt.Color.java.awt.Color(int,int,int)] requires new.
+TypeError: Java method [jdk.internal.dynalink.beans.OverloadedDynamicMethod java.lang.System.getProperty] cannot be used as a constructor.
+TypeError: Java method [jdk.internal.dynalink.beans.OverloadedDynamicMethod java.io.PrintStream.println] cannot be used as a constructor.
+TypeError: Constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod String java.lang.String.java.lang.String(char[],int,int)] requires "new".
 TypeError: No such Java constructor: Runnable()
 TypeError: No such Java constructor: Runnable(int)
 java.lang.InstantiationException: java.io.InputStream
--- a/nashorn/test/script/basic/JDK-8049086.js	Wed Jul 05 20:01:05 2017 +0200
+++ b/nashorn/test/script/basic/JDK-8049086.js	Wed Jul 05 20:01:50 2017 +0200
@@ -58,7 +58,7 @@
 // (a) Java methods (b) Java classes (as these respond to new)
 // (c) FunctionalInterface objects (d) JSObjects that are 'functions'
 
-print("java.awt.Color is java function? " + Java.isJavaFunction(java.awt.Color));
+print("java.lang.String is java function? " + Java.isJavaFunction(java.lang.String));
 print("java.lang.Runnable instance is java function? "
     + Java.isJavaFunction(new java.lang.Runnable(function() {})));
 print("eval is java function? " + Java.isJavaFunction(eval));
--- a/nashorn/test/script/basic/JDK-8049086.js.EXPECTED	Wed Jul 05 20:01:05 2017 +0200
+++ b/nashorn/test/script/basic/JDK-8049086.js.EXPECTED	Wed Jul 05 20:01:50 2017 +0200
@@ -13,7 +13,7 @@
 Object is script object? true
 {} is script object? true
 /foo/ is script object? true
-java.awt.Color is java function? true
+java.lang.String is java function? true
 java.lang.Runnable instance is java function? true
 eval is java function? false
 println is java function? true
--- a/nashorn/test/script/basic/JDK-8049242.js	Wed Jul 05 20:01:05 2017 +0200
+++ b/nashorn/test/script/basic/JDK-8049242.js	Wed Jul 05 20:01:50 2017 +0200
@@ -29,14 +29,14 @@
  */
 
 // call explicit constructor
-print(new (Java.type("java.awt.Color")["(int,int,int)"])(255,0,255));
+print(new (Java.type("java.lang.String")["(char[],int,int)"])(['a', 'b', 'c'],0, 3));
 // print the constructor itself
-print(Java.type("java.awt.Color")["(int,int,int)"]);
+print(Java.type("java.lang.String")["(char[],int,int)"]);
 
 // store constructor to call later
-var Color = Java.type("java.awt.Color")["(int,int,int)"];
+var Color = Java.type("java.lang.String")["(char[],int,int)"];
 // call stored constructor
-print(new Color(33, 233, 2))
+print(new Color(['j', 'a', 'v', 'a'], 1, 3))
 
 // check if default constructor works
 var obj = new (Java.type("java.lang.Object")["()"])();
--- a/nashorn/test/script/basic/JDK-8049242.js.EXPECTED	Wed Jul 05 20:01:05 2017 +0200
+++ b/nashorn/test/script/basic/JDK-8049242.js.EXPECTED	Wed Jul 05 20:01:50 2017 +0200
@@ -1,10 +1,10 @@
-java.awt.Color[r=255,g=0,b=255]
-[jdk.internal.dynalink.beans.SimpleDynamicMethod Color java.awt.Color.java.awt.Color(int,int,int)]
-java.awt.Color[r=33,g=233,b=2]
+abc
+[jdk.internal.dynalink.beans.SimpleDynamicMethod String java.lang.String.java.lang.String(char[],int,int)]
+ava
 TypeError: null is not a function
 TypeError: null is not a function
 TypeError: null is not a function
-TypeError: Constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod Color java.awt.Color.java.awt.Color(int,int,int)] requires new.
+TypeError: Constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod String java.lang.String.java.lang.String(char[],int,int)] requires "new".
 TypeError: null is not a function
 TypeError: null is not a function
 java.lang.InstantiationException: java.io.InputStream
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8056978.js	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8056978: ClassCastException: cannot cast jdk.nashorn.internal.scripts.JO*
+ *
+ * @test
+ * @run
+ */
+
+var obj1 = {
+    'name': 'test name',
+    '1': '1',
+    '2': '2',
+    '3': '3',
+    '4': '4',
+    '5': '5'
+};
+
+var obj2 = {
+    'name': 'hello'
+};
+
+print(obj2['name']);
+print(obj2.name);
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8056978.js.EXPECTED	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,2 @@
+hello
+hello
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8058422.js	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8058422: Users should be able to overwrite "context" and "engine" variables
+ *
+ * @test
+ * @run
+ */
+
+var m = new javax.script.ScriptEngineManager();
+var e = m.getEngineByName("nashorn");
+e.put("foo", "hello");
+var obj = e.eval("context.getAttribute('foo')");
+if (obj != "hello") {
+    fail("Expected 'obj' to be 'hello'");
+}
+
+e.put("context", "bar");
+if (e.eval("context") != "bar") {
+    fail("Expected 'context' to be 'bar'");
+}
+
+if (e.eval("foo") != "hello") {
+    fail("Expected 'foo' to be 'hello'");
+}
+
+if (e.eval("engine") != e) {
+    fail("'engine' is not evaluaed to current engine");
+}
+
+e.put("engine", "foobar");
+if (e.eval("engine") != "foobar") {
+    fail("'engine' is not evalued to 'foobar'");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8058545.js	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8058545: With strict mode, bean property assignment of a non-existent property should result in TypeError
+ *
+ * @test
+ * @run
+ */
+
+'use strict';
+var File = Java.type("java.io.File");
+var f = new File(".");
+try {
+    f.foo = 33;
+    fail("Should have thrown TypeError");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("Expected TypeError, got " + e);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8058615.js	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8058615: Overload resolution ambiguity involving ConsString
+ *
+ * @test
+ * @run
+ */
+
+var strw = new java.io.StringWriter();
+var bufw = new java.io.BufferedWriter(strw);
+var s = "hello ";
+bufw.write(s + "world");
+bufw.close();
+print(strw.toString());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8058615.js.EXPECTED	Wed Jul 05 20:01:50 2017 +0200
@@ -0,0 +1,1 @@
+hello world
--- a/nashorn/test/src/jdk/nashorn/api/scripting/ScopeTest.java	Wed Jul 05 20:01:05 2017 +0200
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScopeTest.java	Wed Jul 05 20:01:50 2017 +0200
@@ -582,6 +582,60 @@
         assertEquals(e.eval("x", newCtxt), 2);
     }
 
+    // @bug 8058422: Users should be able to overwrite "context" and "engine" variables
+    @Test
+    public static void contextOverwriteTest() throws ScriptException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        final Bindings b = new SimpleBindings();
+        b.put("context", "hello");
+        b.put("foo", 32);
+        final ScriptContext newCtxt = new SimpleScriptContext();
+        newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+        e.setContext(newCtxt);
+        assertEquals(e.eval("context"), "hello");
+        assertEquals(((Number)e.eval("foo")).intValue(), 32);
+    }
+
+    // @bug 8058422: Users should be able to overwrite "context" and "engine" variables
+    @Test
+    public static void contextOverwriteInScriptTest() throws ScriptException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        e.put("foo", 32);
+
+        assertEquals(((Number)e.eval("foo")).intValue(), 32);
+        assertEquals(e.eval("context = 'bar'"), "bar");
+        assertEquals(((Number)e.eval("foo")).intValue(), 32);
+    }
+
+    // @bug 8058422: Users should be able to overwrite "context" and "engine" variables
+    @Test
+    public static void engineOverwriteTest() throws ScriptException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        final Bindings b = new SimpleBindings();
+        b.put("engine", "hello");
+        b.put("foo", 32);
+        final ScriptContext newCtxt = new SimpleScriptContext();
+        newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+        e.setContext(newCtxt);
+        assertEquals(e.eval("engine"), "hello");
+        assertEquals(((Number)e.eval("foo")).intValue(), 32);
+    }
+
+    // @bug 8058422: Users should be able to overwrite "context" and "engine" variables
+    @Test
+    public static void engineOverwriteInScriptTest() throws ScriptException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        e.put("foo", 32);
+
+        assertEquals(((Number)e.eval("foo")).intValue(), 32);
+        assertEquals(e.eval("engine = 'bar'"), "bar");
+        assertEquals(((Number)e.eval("foo")).intValue(), 32);
+    }
+
     // @bug 8044750: megamorphic getter for scope objects does not call __noSuchProperty__ hook
     @Test
     public static void testMegamorphicGetInGlobal() throws Exception {