Merge jdk7-b114
authorduke
Wed, 05 Jul 2017 17:24:21 +0200
changeset 6726 750c1ccb2f2d
parent 6725 39b3cef7bd46 (diff)
parent 6621 a8f89695bf9b (current diff)
child 6727 bf7b4fe11602
child 6728 b075f5f317b7
child 6737 aa880dd6d3b7
child 6780 9353ae6eae7d
child 6784 a8595558375c
child 6797 1c74ecb366a0
child 6799 aced6801fb45
child 6801 2d6f4aa03058
child 6803 17f7431708c8
child 6892 d954b585d3a1
child 6913 812a208bccda
child 6933 6b9085d37f01
child 7060 e0bc5b441d60
child 7089 ab450c645fa4
child 7097 767197e73343
Merge
--- a/.hgtags-top-repo	Wed Jul 05 17:23:40 2017 +0200
+++ b/.hgtags-top-repo	Wed Jul 05 17:24:21 2017 +0200
@@ -87,3 +87,4 @@
 2a02d4a6955c7c078aee9a604cb3be409800d82c jdk7-b110
 9702d6fef68e17533ee7fcf5923b11ead3e912ce jdk7-b111
 b852103caf73da70068473777ae867a457bb3ae1 jdk7-b112
+c1df968c4527bfab5f97662a89245f15d12d378b jdk7-b113
--- a/Makefile	Wed Jul 05 17:23:40 2017 +0200
+++ b/Makefile	Wed Jul 05 17:24:21 2017 +0200
@@ -558,9 +558,12 @@
 # rule to test
 ################################################################
 
-.NOTPARALLEL: test
+.NOTPARALLEL: test_run
 
-test: test_clean test_start test_summary
+test:
+	$(MAKE) test_run
+
+test_run: test_clean test_start test_summary
 
 test_start:
 	@$(ECHO) "Tests started at `$(DATE)`"
@@ -586,7 +589,7 @@
 # Get failure list from log
 $(OUTPUTDIR)/test_failures.txt: $(OUTPUTDIR)/test_log.txt
 	@$(RM) $@
-	@( $(EGREP) '^FAILED:' $< || $(ECHO) "" ) > $@
+	@( $(EGREP) '^FAILED:' $< || $(ECHO) "" ) | $(NAWK) 'length>0' > $@
 
 # Get log file of all tests run
 JDK_TO_TEST := $(shell 							\
@@ -598,10 +601,11 @@
     $(ECHO) "$(PRODUCT_HOME)"; 						\
   fi 									\
 )
+TEST_TARGETS=all
 $(OUTPUTDIR)/test_log.txt:
 	$(RM) $@
-	( $(CD) test &&                                     \
-          $(MAKE) NO_STOPPING=- PRODUCT_HOME=$(JDK_TO_TEST) \
+	( $(CD) test &&                                                     \
+          $(MAKE) NO_STOPPING=- PRODUCT_HOME=$(JDK_TO_TEST) $(TEST_TARGETS) \
         ) | tee $@
 
 ################################################################
@@ -614,7 +618,7 @@
 #  PHONY
 ################################################################
 
-.PHONY: all  test test_start test_summary test_clean \
+.PHONY: all  test test_run test_start test_summary test_clean \
 	generic_build_repo_series \
 	what clobber insane \
         dev dev-build dev-sanity dev-clobber \
--- a/corba/.hgtags	Wed Jul 05 17:23:40 2017 +0200
+++ b/corba/.hgtags	Wed Jul 05 17:24:21 2017 +0200
@@ -87,3 +87,4 @@
 0e1f80fda2271f53d4bbb59ec3f301dfbcef6a0a jdk7-b110
 640fa4d4e2ad4c2d7e4815c955026740d8c52b7a jdk7-b111
 cc67fdc4fee9a5b25caee4e71b51a8ff24ae7d1a jdk7-b112
+a89a6c5be9d1a754868d3d359cbf7ad36aa95631 jdk7-b113
--- a/hotspot/.hgtags	Wed Jul 05 17:23:40 2017 +0200
+++ b/hotspot/.hgtags	Wed Jul 05 17:24:21 2017 +0200
@@ -122,3 +122,4 @@
 2f25f2b8de2700a1822463b1bd3d02b5e218018f jdk7-b110
 07b042e13dde4f3479ba9ec55120fcd5e8623323 jdk7-b111
 5511edd5d719f3fc9fdd04879482026a3d2c8652 jdk7-b112
+beef35b96b81129c375d572357fb9548d9020db1 jdk7-b113
--- a/jaxp/.hgtags	Wed Jul 05 17:23:40 2017 +0200
+++ b/jaxp/.hgtags	Wed Jul 05 17:24:21 2017 +0200
@@ -87,3 +87,4 @@
 d422dbdd09766269344b796b3a46a5b3f74557e1 jdk7-b110
 8106c747067c905d814a737a57fea0e29057b33f jdk7-b111
 1b05254242881527b4d5d711295c0fe708c8823a jdk7-b112
+bc0c84ce54c34d3e8b0604b94da0d7c75c26755e jdk7-b113
--- a/jaxws/.hgtags	Wed Jul 05 17:23:40 2017 +0200
+++ b/jaxws/.hgtags	Wed Jul 05 17:24:21 2017 +0200
@@ -87,3 +87,4 @@
 95ecac35fb11530752bd0404c9bf02bcfb30990e jdk7-b110
 2575ebca96c7fb1b78f6ae025a97321210aba309 jdk7-b111
 8e0f0054817f0f73fb33e80fb1333fb45b1d513d jdk7-b112
+d35c94fd22362f478f75b4bfcd2bef6a83cb9b3f jdk7-b113
--- a/jdk/.hgtags	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/.hgtags	Wed Jul 05 17:24:21 2017 +0200
@@ -87,3 +87,4 @@
 176586cd040e4dd17a5ff6e91f72df10d7442453 jdk7-b110
 fb63a2688db807a73e2a3de7d9bab298f1bff0e8 jdk7-b111
 b53f226b1d91473ac54184afa827be07b87e0319 jdk7-b112
+61d3b9fbb26bdef56cfa41b9af5bc312a22cbeb8 jdk7-b113
--- a/jdk/make/Makefile	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/make/Makefile	Wed Jul 05 17:24:21 2017 +0200
@@ -75,7 +75,6 @@
 import_fastdebug  -- copy in the fastdebug components \n\
 import_debug      -- copy in the debug components \n\
 modules           -- build the jdk and jre module images (experimental) \n\
-sccs_get          -- make sure all SCCS files are up-to-date (need SCCS) \n\
 create_links      -- create softlinks in Solaris 32bit build to 64bit dirs \n\
 "
 
@@ -278,21 +277,6 @@
 $(OUTPUTDIR) $(TEMPDIR):
 	$(MKDIR) -p $@
 
-# cleanup everything. If the workspace is not being built by the control
-# workspace, and if it is a Teamware workspace, then see if there are
-# any files which are not under SCCS control.
-clean clobber:: 
-ifndef EXTERNALSANITYCONTROL
-	@if [ -d $(TOPDIR)/Codemgr_wsdata ]; then \
-	  $(ECHO) '\nPerforming workspace scan for remnant files.\n' \
-		'  Any files listed below are not under SCCS control in the workspace\n' \
-		'  and you should review them and possibly remove them manually:' ; \
-	  $(FIND) $(TOPDIR)/make $(TOPDIR)/src -type f | \
-		$(SED) 's+SCCS/[ps]\.++' | $(SORT) | $(UNIQ) -c | $(NAWK) '$$1<2 {print $$2;}' ; \
-	  $(ECHO) 'End of workspace scan.' ; \
-	fi
-endif
-
 # this should be the last rule in this file:
 all::
 	@if [ -r $(WARNING_FILE) ]; then \
@@ -341,16 +325,70 @@
 include $(BUILDDIR)/common/internal/BinaryPlugs.gmk
 
 #
-# Get top level sccs_get rule
+# Test rule
 #
-include $(BUILDDIR)/common/Rules-SCCS.gmk
+
+.NOTPARALLEL: test_run
+
+test:
+	$(MAKE) test_run
+
+test_run: test_clean test_start test_summary
+
+test_start:
+	@$(ECHO) "Tests started at `$(DATE)`"
+
+test_clean:
+	$(RM) $(OUTPUTDIR)/test_failures.txt $(OUTPUTDIR)/test_log.txt
 
+test_summary: $(OUTPUTDIR)/test_failures.txt
+	@$(ECHO) "#################################################"
+	@$(ECHO) "Tests completed at `$(DATE)`"
+	@( $(EGREP) '^TEST STATS:' $(OUTPUTDIR)/test_log.txt \
+          || $(ECHO) "No TEST STATS seen in log" )
+	@$(ECHO) "For complete details see: $(OUTPUTDIR)/test_log.txt"
+	@$(ECHO) "#################################################"
+	@if [ -s $< ] ; then                                           \
+          $(ECHO) "ERROR: Test failure count: `$(CAT) $< | $(WC) -l`"; \
+          $(CAT) $<;                                                   \
+          exit 1;                                                      \
+        else                                                           \
+          $(ECHO) "Success! No failures detected";                     \
+        fi
+
+# Get failure list from log
+$(OUTPUTDIR)/test_failures.txt: $(OUTPUTDIR)/test_log.txt
+	@$(RM) $@
+	@( $(EGREP) '^FAILED:' $< || $(ECHO) "" ) | $(NAWK) 'length>0' > $@
+
+# Get log file of all tests run
+JDK_TO_TEST := $(shell 							\
+  if [ -d "$(ABS_OUTPUTDIR)/j2sdk-image" ] ; then 			\
+    $(ECHO) "$(ABS_OUTPUTDIR)/j2sdk-image"; 				\
+  elif [ -d "$(ABS_OUTPUTDIR)/bin" ] ; then 				\
+    $(ECHO) "$(ABS_OUTPUTDIR)"; 					\
+  elif [ "$(PRODUCT_HOME)" != "" -a -d "$(PRODUCT_HOME)/bin" ] ; then 	\
+    $(ECHO) "$(PRODUCT_HOME)"; 						\
+  fi 									\
+)
+
+TEST_TARGETS=jdk_all
+$(OUTPUTDIR)/test_log.txt:
+	$(RM) $@
+	( $(CD) ../test &&                                              \
+          $(MAKE) NO_STOPPING=- PRODUCT_HOME=$(JDK_TO_TEST) $(TEST_TARGETS) \
+        ) | tee $@
+
+#
 # JPRT rules
+#
+
 include jprt.gmk
 
 #
 # Phonies to avoid accidents.
 #
 .PHONY: all build clean clobber optimized debug fastdebug create_links \
-	import import_product import_fastdebug import_debug
+	import import_product import_fastdebug import_debug \
+	test test_run test_start test_clean test_summary
 
--- a/jdk/make/common/Cscope.gmk	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/make/common/Cscope.gmk	Wed Jul 05 17:24:21 2017 +0200
@@ -76,7 +76,7 @@
 # What files should we include?  A simple rule might be just those files under
 # SCM control, however this would miss files we create like the opcodes and
 # CClassHeaders.  The following attempts to find everything that is *useful*.
-# (.del files are created by sccsrm, demo directories contain many .java files
+# (demo directories contain many .java files
 # that probably aren't useful for development, and the pkgarchive may contain
 # duplicates of files within the source hierarchy).  The ordering of the .raw
 # file is an attempt to make cscope display the most relevant files first.
--- a/jdk/make/common/Defs.gmk	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/make/common/Defs.gmk	Wed Jul 05 17:24:21 2017 +0200
@@ -334,7 +334,7 @@
 DOCSDIRSUFFIX       =
 
 # The MESSAGE, WARNING and ERROR files are used to store sanityck and 
-# SCCS check messages, warnings and errors. 
+# warnings and errors. 
 ifndef ERROR_FILE
   ERROR_FILE   = $(OUTPUTDIR)/sanityCheckErrors.txt
 endif
@@ -634,38 +634,6 @@
 
 VERSION_DEFINES = -DRELEASE='"$(RELEASE)"'
 
-# Note: As a rule, GNU Make rules should not appear in any of the 
-# Defs*.gmk files. These were added for Kestrel-Solaris and do address
-# a TeamWare bug. They should be moved elsewhere for Merlin.
-# 
-#  Override gnumake built-in rules which do sccs get operations badly.
-#  (They put the checked out code in the current directory, not in the
-#  directory of the original file.) 
-# Since this is a symptom of a teamware failure, complain and die on the spot.
-
-# This message immediately goes to stdout and the build terminates.
-define SCCS-trouble
-$(error  \
-"ERROR: File $@ referenced while building in $(CURRENT_DIRECTORY) \
- is out of date with respect to its SCCS file $<. \
- This can happen from an unresolved Teamware conflict, a file movement, or \
- a failure in which SCCS files are updated but the 'sccs get' was not done. \
- You should double check for other out of date files in your workspace. \
- Or run: cd $(TOPDIR) && $(MAKE) sccs_get")
-endef
-
-%:: s.%
-	@$(SCCS-trouble)
-%:: SCCS/s.%
-	@$(SCCS-trouble)
-	@$(ECHO) "         is out of date with respect to its SCCS file." >> $(WARNING_FILE)
-	@$(ECHO) "         This file may be from an unresolved Teamware conflict." >> $(WARNING_FILE)
-	@$(ECHO) "         This is also a symptom of a Teamware bringover/putback failure" >> $(WARNING_FILE)
-	@$(ECHO) "         in which SCCS files are updated but not checked out." >> $(WARNING_FILE)
-	@$(ECHO) "         Check for other out of date files in your workspace." >> $(WARNING_FILE)
-	@$(ECHO) "" >> $(WARNING_FILE)
-	@#exit 666
-
 ifdef INSANE
   export INSANE
 endif
--- a/jdk/make/common/Rules-SCCS.gmk	Wed Jul 05 17:23:40 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-#
-# 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.  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.
-#
-
-#
-# Only get these rules if SCCS is available
-#
-
-ifdef SCCS
-
-# SCCS command to extract out latest source
-SCCS_GET=$(SCCS) get -s
-
-#
-# Make sure all files in workspace are fresh
-#
-TEMP_ALL_FILES=$(JDK_TOPDIR)/temp_filelist
-$(TEMP_ALL_FILES): $(JDK_TOPDIR)/Codemgr_wsdata/nametable
-	$(prep-target)
-	@$(CUT) -d' ' -f1 $< \
-	    | $(GREP) -v '^VERSION' \
-	    | $(GREP) -v '^deleted_files' \
-	    | $(GREP) -v '^Codemgr_wsdata' > $@
-
-sccs_get: $(TEMP_ALL_FILES)
-	@$(PRINTF) "Workspace has %d files\n"  `$(CAT) $< | $(WC) -l`
-	@count=0; \
-	for i in `$(CAT) $<` ; do \
-	    f=$(JDK_TOPDIR)/$$i; \
-	    count=`$(EXPR) $$count '+' 1`; \
-	    if [ `$(EXPR) $$count '%' 100` = 0 ] ; then \
-		$(PRINTF) "\rChecked $$count files"; \
-	    fi; \
-	    if [ ! -f $$f ] ; then \
-		$(PRINTF) "\r$(SCCS_GET) $$f\n"; \
-		(cd `$(DIRNAME) $$f` && $(SCCS_GET) `$(BASENAME) $$f`); \
-	    elif /usr/bin/test $$f -ot `$(DIRNAME) $$f`/SCCS/s.`$(BASENAME) $$f` ; then \
-		$(PRINTF) "\r$(SCCS_GET) $$f\n"; \
-		(cd `$(DIRNAME) $$f` && $(SCCS_GET) `$(BASENAME) $$f`); \
-	    fi; \
-	done; \
-	$(PRINTF) "\rChecked $$count files\n"
-
-#
-# Phonies to avoid accidents.
-#
-.PHONY: sccs_get
-
-endif
--- a/jdk/make/common/shared/Defs-utils.gmk	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/make/common/shared/Defs-utils.gmk	Wed Jul 05 17:24:21 2017 +0200
@@ -33,7 +33,7 @@
 #            UTILS_COMMAND_PATH
 #         /usr/bin/ 
 #            UTILS_USR_BIN_PATH
-#         /usr/ccs/bin/ (sccs, m4, lex, yacc, as, ar, strip, mcs)
+#         /usr/ccs/bin/ (m4, lex, yacc, as, ar, strip, mcs)
 #            UTILS_CCS_BIN_PATH
 #         Dev Tools: zip, unzip, etc that we may have special versions of
 #            UTILS_DEVTOOL_PATH
@@ -117,7 +117,6 @@
 RMDIR          = $(UTILS_COMMAND_PATH)rmdir
 RPM            = $(UTILS_COMMAND_PATH)rpm
 RPMBUILD       = $(UTILS_COMMAND_PATH)rpmbuild
-SCCS           = $(UTILS_CCS_BIN_PATH)sccs
 SED            = $(UTILS_COMMAND_PATH)sed
 SH             = $(UTILS_COMMAND_PATH)sh
 SHOWREV        = $(UTILS_USR_BIN_PATH)showrev
@@ -183,7 +182,7 @@
   NAWK           = $(USRBIN_PATH)gawk
   # Intrinsic unix command, with backslash-escaped character interpretation
   ECHO           = /bin/echo -e
-  # These are really in UTILS_USR_BIN_PATH on Linux (only sccs is not)
+  # These are really in UTILS_USR_BIN_PATH on Linux
   AR             = $(UTILS_USR_BIN_PATH)ar
   AS             = $(UTILS_USR_BIN_PATH)as
   LD             = $(UTILS_USR_BIN_PATH)ld
--- a/jdk/make/common/shared/Defs.gmk	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/make/common/shared/Defs.gmk	Wed Jul 05 17:24:21 2017 +0200
@@ -219,7 +219,7 @@
   PRODUCT_NAME = Java(TM)
   PRODUCT_SUFFIX = SE Runtime Environment
   JDK_RC_PLATFORM_NAME = Platform SE
-  COMPANY_NAME = Oracle
+  COMPANY_NAME = Oracle Corporation
 endif
 
 RUNTIME_NAME = $(PRODUCT_NAME) $(PRODUCT_SUFFIX)
--- a/jdk/make/java/java/FILES_java.gmk	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/make/java/java/FILES_java.gmk	Wed Jul 05 17:24:21 2017 +0200
@@ -284,6 +284,7 @@
     java/util/concurrent/CancellationException.java \
     java/util/concurrent/CompletionService.java \
     java/util/concurrent/ConcurrentHashMap.java \
+    java/util/concurrent/ConcurrentLinkedDeque.java \
     java/util/concurrent/ConcurrentLinkedQueue.java \
     java/util/concurrent/ConcurrentMap.java \
     java/util/concurrent/ConcurrentNavigableMap.java \
--- a/jdk/make/jprt.properties	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/make/jprt.properties	Wed Jul 05 17:24:21 2017 +0200
@@ -25,43 +25,265 @@
 
 # Properties for jprt
 
-# Use whatever release that the submitted job requests
+# At submit time, the release supplied will be in jprt.submit.release
+#    and will be one of the official release names defined in jprt.
+#    jprt supports property value expansion using ${property.name} syntax.
+
+# This tells jprt what default release we want to build
 jprt.tools.default.release=${jprt.submit.release}
 
 # The different build flavors we want, we override here so we just get these 2
 jprt.build.flavors=product,fastdebug
 
-# Standard test target for everybody
-jprt.test.targets=*-*-*-jvm98
+# Define the Windows we want (temporary)
+jprt.my.windows.i586.jdk7b107=windows_i586_5.0
+jprt.my.windows.i586.jdk7temp=windows_i586_5.0
+jprt.my.windows.i586.jdk7=windows_i586_5.1
+jprt.my.windows.i586=${jprt.my.windows.i586.${jprt.tools.default.release}}
+
+# Standard list of jprt build targets for this source tree
+jprt.build.targets= 						\
+    solaris_sparc_5.10-{product|fastdebug}, 			\
+    solaris_sparcv9_5.10-{product|fastdebug}, 			\
+    solaris_i586_5.10-{product|fastdebug}, 			\
+    solaris_x64_5.10-{product|fastdebug}, 			\
+    linux_i586_2.6-{product|fastdebug}, 			\
+    linux_x64_2.6-{product|fastdebug}, 				\
+    ${jprt.my.windows.i586}-{product|fastdebug}, 		\
+    windows_x64_5.2-{product|fastdebug}
+
+# Standard vm test target
+jprt.test.targets=						\
+    solaris_sparc_5.10-product-c1-jvm98, 			\
+    solaris_sparcv9_5.10-product-c2-jvm98, 			\
+    solaris_i586_5.10-product-c1-jvm98, 			\
+    solaris_x64_5.10-product-c2-jvm98, 				\
+    linux_i586_2.6-product-{c1|c2}-jvm98, 			\
+    linux_x64_2.6-product-c2-jvm98, 				\
+    ${jprt.my.windows.i586}-product-c1-jvm98, 			\
+    windows_x64_5.2-product-c2-jvm98
+
+# User can select the test set with jprt submit "-testset name" option
+jprt.my.test.set=${jprt.test.set}
 
-# Test targets in test/Makefile (some longer running tests only test c2)
-jprt.make.rule.test.targets=    \
-   *-product-*-jdk_beans1,      \
-   *-product-*-jdk_beans2,      \
-   *-product-*-jdk_beans3,      \
-   *-product-*-jdk_io,          \
-   *-product-*-jdk_lang,        \
-   *-product-*-jdk_management1, \
-   *-product-*-jdk_management2, \
-   *-product-*-jdk_math,        \
-   *-product-*-jdk_misc,        \
-   *-product-*-jdk_net,         \
-   *-product-*-jdk_nio1,        \
-   *-product-*-jdk_nio2,        \
-   *-product-*-jdk_nio3,        \
-   *-product-*-jdk_security1,   \
-   *-product-*-jdk_security2,   \
-   *-product-*-jdk_security3,   \
-   *-product-*-jdk_text,        \
-   *-product-*-jdk_tools1,      \
-   *-product-*-jdk_tools2,      \
-   *-product-*-jdk_util
+# Default jdk test targets in test/Makefile (no fastdebug & limited c2)
+jprt.make.rule.default.test.targets=				\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_beans1, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_beans1, 		\
+    solaris_i586_5.10-product-c1-jdk_beans1, 			\
+    solaris_x64_5.10-product-c2-jdk_beans1, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_beans1, 			\
+    linux_x64_2.6-product-c2-jdk_beans1, 			\
+    ${jprt.my.windows.i586}-product-c1-jdk_beans1, 		\
+    windows_x64_5.2-product-c2-jdk_beans1, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_io, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_io, 			\
+    solaris_i586_5.10-product-c1-jdk_io, 			\
+    solaris_x64_5.10-product-c2-jdk_io, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_io, 			\
+    linux_x64_2.6-product-c2-jdk_io, 				\
+    ${jprt.my.windows.i586}-product-c1-jdk_io, 			\
+    windows_x64_5.2-product-c2-jdk_io, 				\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_lang, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_lang, 			\
+    solaris_i586_5.10-product-c1-jdk_lang, 			\
+    solaris_x64_5.10-product-c2-jdk_lang, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_lang, 			\
+    linux_x64_2.6-product-c2-jdk_lang, 				\
+    ${jprt.my.windows.i586}-product-c1-jdk_lang, 		\
+    windows_x64_5.2-product-c2-jdk_lang, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_math, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_math, 			\
+    solaris_i586_5.10-product-c1-jdk_math, 			\
+    solaris_x64_5.10-product-c2-jdk_math, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_math, 			\
+    linux_x64_2.6-product-c2-jdk_math, 				\
+    ${jprt.my.windows.i586}-product-c1-jdk_math, 		\
+    windows_x64_5.2-product-c2-jdk_math, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_misc, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_misc, 			\
+    solaris_i586_5.10-product-c1-jdk_misc, 			\
+    solaris_x64_5.10-product-c2-jdk_misc, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_misc, 			\
+    linux_x64_2.6-product-c2-jdk_misc, 				\
+    ${jprt.my.windows.i586}-product-c1-jdk_misc, 		\
+    windows_x64_5.2-product-c2-jdk_misc, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_net, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_net, 			\
+    solaris_i586_5.10-product-c1-jdk_net, 			\
+    solaris_x64_5.10-product-c2-jdk_net, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_net, 			\
+    linux_x64_2.6-product-c2-jdk_net, 				\
+    ${jprt.my.windows.i586}-product-c1-jdk_net, 		\
+    windows_x64_5.2-product-c2-jdk_net, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_nio1, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_nio1, 			\
+    solaris_i586_5.10-product-c1-jdk_nio1, 			\
+    solaris_x64_5.10-product-c2-jdk_nio1, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_nio1, 			\
+    linux_x64_2.6-product-c2-jdk_nio1, 				\
+    ${jprt.my.windows.i586}-product-c1-jdk_nio1, 		\
+    windows_x64_5.2-product-c2-jdk_nio1, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_nio2, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_nio2, 			\
+    solaris_i586_5.10-product-c1-jdk_nio2, 			\
+    solaris_x64_5.10-product-c2-jdk_nio2, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_nio2, 			\
+    linux_x64_2.6-product-c2-jdk_nio2, 				\
+    ${jprt.my.windows.i586}-product-c1-jdk_nio2, 		\
+    windows_x64_5.2-product-c2-jdk_nio2, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_nio3, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_nio3, 			\
+    solaris_i586_5.10-product-c1-jdk_nio3, 			\
+    solaris_x64_5.10-product-c2-jdk_nio3, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_nio3, 			\
+    linux_x64_2.6-product-c2-jdk_nio3, 				\
+    ${jprt.my.windows.i586}-product-c1-jdk_nio3, 		\
+    windows_x64_5.2-product-c2-jdk_nio3, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_security1, 		\
+    solaris_sparcv9_5.10-product-c2-jdk_security1, 		\
+    solaris_i586_5.10-product-c1-jdk_security1, 		\
+    solaris_x64_5.10-product-c2-jdk_security1, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_security1, 		\
+    linux_x64_2.6-product-c2-jdk_security1, 			\
+    ${jprt.my.windows.i586}-product-c1-jdk_security1, 		\
+    windows_x64_5.2-product-c2-jdk_security1, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_text, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_text, 			\
+    solaris_i586_5.10-product-c1-jdk_text, 			\
+    solaris_x64_5.10-product-c2-jdk_text, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_text, 			\
+    linux_x64_2.6-product-c2-jdk_text, 				\
+    ${jprt.my.windows.i586}-product-c1-jdk_text, 		\
+    windows_x64_5.2-product-c2-jdk_text, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_tools1, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_tools1, 		\
+    solaris_i586_5.10-product-c1-jdk_tools1, 			\
+    solaris_x64_5.10-product-c2-jdk_tools1, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_tools1, 			\
+    linux_x64_2.6-product-c2-jdk_tools1, 			\
+    ${jprt.my.windows.i586}-product-c1-jdk_tools1, 		\
+    windows_x64_5.2-product-c2-jdk_tools1, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_util, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_util, 			\
+    solaris_i586_5.10-product-c1-jdk_util, 			\
+    solaris_x64_5.10-product-c2-jdk_util, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_util, 			\
+    linux_x64_2.6-product-c2-jdk_util, 				\
+    ${jprt.my.windows.i586}-product-c1-jdk_util, 		\
+    windows_x64_5.2-product-c2-jdk_util
 
-# Some of these are crashing Xvfb or windows manager, need dedicated DISPLAY per test batch
-jprt2.make.rule.test.targets=    \
-   *-product-*-jdk_awt,         \
-   *-product-*-jdk_rmi,         \
-   *-product-*-jdk_swing,       \
+# All jdk test targets in test/Makefile (still no fastdebug & limited c2)
+jprt.make.rule.all.test.targets=    				\
+    								\
+   ${jprt.make.rule.default.test.targets}, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_awt, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_awt, 			\
+    solaris_i586_5.10-product-c1-jdk_awt, 			\
+    solaris_x64_5.10-product-c2-jdk_awt, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_awt, 			\
+    linux_x64_2.6-product-c2-jdk_awt, 				\
+    ${jprt.my.windows.i586}-product-c1-jdk_awt, 		\
+    windows_x64_5.2-product-c2-jdk_awt, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_beans2, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_beans2, 		\
+    solaris_i586_5.10-product-c1-jdk_beans2, 			\
+    solaris_x64_5.10-product-c2-jdk_beans2, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_beans2, 			\
+    linux_x64_2.6-product-c2-jdk_beans2, 			\
+    ${jprt.my.windows.i586}-product-c1-jdk_beans2, 		\
+    windows_x64_5.2-product-c2-jdk_beans2, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_beans3, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_beans3, 		\
+    solaris_i586_5.10-product-c1-jdk_beans3, 			\
+    solaris_x64_5.10-product-c2-jdk_beans3, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_beans3, 			\
+    linux_x64_2.6-product-c2-jdk_beans3, 			\
+    ${jprt.my.windows.i586}-product-c1-jdk_beans3, 		\
+    windows_x64_5.2-product-c2-jdk_beans3, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_management1, 		\
+    solaris_sparcv9_5.10-product-c2-jdk_management1, 		\
+    solaris_i586_5.10-product-c1-jdk_management1, 		\
+    solaris_x64_5.10-product-c2-jdk_management1, 		\
+    linux_i586_2.6-product-{c1|c2}-jdk_management1, 		\
+    linux_x64_2.6-product-c2-jdk_management1, 			\
+    ${jprt.my.windows.i586}-product-c1-jdk_management1, 	\
+    windows_x64_5.2-product-c2-jdk_management1, 		\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_management2, 		\
+    solaris_sparcv9_5.10-product-c2-jdk_management2, 		\
+    solaris_i586_5.10-product-c1-jdk_management2, 		\
+    solaris_x64_5.10-product-c2-jdk_management2, 		\
+    linux_i586_2.6-product-{c1|c2}-jdk_management2, 		\
+    linux_x64_2.6-product-c2-jdk_management2, 			\
+    ${jprt.my.windows.i586}-product-c1-jdk_management2, 	\
+    windows_x64_5.2-product-c2-jdk_management2, 		\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_rmi, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_rmi, 			\
+    solaris_i586_5.10-product-c1-jdk_rmi, 			\
+    solaris_x64_5.10-product-c2-jdk_rmi, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_rmi, 			\
+    linux_x64_2.6-product-c2-jdk_rmi, 				\
+    ${jprt.my.windows.i586}-product-c1-jdk_rmi, 		\
+    windows_x64_5.2-product-c2-jdk_rmi, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_security2, 		\
+    solaris_sparcv9_5.10-product-c2-jdk_security2, 		\
+    solaris_i586_5.10-product-c1-jdk_security2, 		\
+    solaris_x64_5.10-product-c2-jdk_security2, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_security2, 		\
+    linux_x64_2.6-product-c2-jdk_security2, 			\
+    ${jprt.my.windows.i586}-product-c1-jdk_security2, 		\
+    windows_x64_5.2-product-c2-jdk_security2, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_security3, 		\
+    solaris_sparcv9_5.10-product-c2-jdk_security3, 		\
+    solaris_i586_5.10-product-c1-jdk_security3, 		\
+    solaris_x64_5.10-product-c2-jdk_security3, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_security3, 		\
+    linux_x64_2.6-product-c2-jdk_security3, 			\
+    ${jprt.my.windows.i586}-product-c1-jdk_security3, 		\
+    windows_x64_5.2-product-c2-jdk_security3, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_swing, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_swing, 			\
+    solaris_i586_5.10-product-c1-jdk_swing, 			\
+    solaris_x64_5.10-product-c2-jdk_swing, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_swing, 			\
+    linux_x64_2.6-product-c2-jdk_swing, 			\
+    ${jprt.my.windows.i586}-product-c1-jdk_swing, 		\
+    windows_x64_5.2-product-c2-jdk_swing, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_tools2, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_tools2, 		\
+    solaris_i586_5.10-product-c1-jdk_tools2, 			\
+    solaris_x64_5.10-product-c2-jdk_tools2, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_tools2, 			\
+    linux_x64_2.6-product-c2-jdk_tools2, 			\
+    ${jprt.my.windows.i586}-product-c1-jdk_tools2, 		\
+    windows_x64_5.2-product-c2-jdk_tools2
+
+# Select list to use (allow for testset to be empty too)
+jprt.make.rule..test.targets=${jprt.make.rule.default.test.targets} 
+jprt.make.rule.test.targets=${jprt.make.rule.${jprt.my.test.set}.test.targets} 
 
 # Directories to be excluded from the source bundles
 jprt.bundle.exclude.src.dirs=build dist webrev
--- a/jdk/make/mkdemo/Makefile	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/make/mkdemo/Makefile	Wed Jul 05 17:24:21 2017 +0200
@@ -31,7 +31,7 @@
 PRODUCT = demos
 include $(BUILDDIR)/common/Defs.gmk
 
-SUBDIRS            = jni
+SUBDIRS            = jni nio
 SUBDIRS_desktop    = applets jfc
 SUBDIRS_management = management
 SUBDIRS_misc       = scripting
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/mkdemo/nio/Makefile	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+#
+# Makefile for building the jfc demos
+#
+
+BUILDDIR = ../..
+PRODUCT = demos
+include $(BUILDDIR)/common/Defs.gmk
+
+SUBDIRS = zipfs
+include $(BUILDDIR)/common/Subdirs.gmk
+
+all build clean clobber::
+	$(SUBDIRS-loop)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/mkdemo/nio/zipfs/Makefile	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 1997, 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.
+#
+
+#
+# Makefile to build the ZipFileSystem demo.
+#
+
+BUILDDIR = ../../..
+PRODUCT = demo/zipfs
+DEMONAME = zipfs
+include $(BUILDDIR)/common/Defs.gmk
+
+DEMO_ROOT       = $(SHARE_SRC)/demo/nio/$(DEMONAME)
+DEMO_TOPFILES   = ./README.txt
+DEMO_SRCDIR     = $(DEMO_ROOT)
+DEMO_DESTDIR    = $(DEMODIR)/nio/$(DEMONAME)
+
+#
+# Demo jar building rules.
+#
+include $(BUILDDIR)/common/Demo.gmk
+
--- a/jdk/make/sun/cmm/lcms/Makefile	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/make/sun/cmm/lcms/Makefile	Wed Jul 05 17:24:21 2017 +0200
@@ -80,7 +80,12 @@
 vpath %.c   $(SHARE_SRC)/native/sun/java2d
 
 ifeq ($(PLATFORM), windows)
-OTHER_CFLAGS += -DCMS_IS_WINDOWS_ -Dsqrtf=sqrt
+OTHER_CFLAGS += -DCMS_IS_WINDOWS_
+
+ifeq ($(COMPILER_VERSION), VS2003)
+OTHER_CFLAGS += -Dsqrtf=sqrt
+endif
+
 OTHER_LDLIBS = $(OBJDIR)/../../../sun.awt/awt/$(OBJDIRNAME)/awt.lib
 OTHER_INCLUDES += -I$(SHARE_SRC)/native/sun/java2d \
                   -I$(SHARE_SRC)/native/sun/awt/debug
--- a/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java	Wed Jul 05 17:24:21 2017 +0200
@@ -525,7 +525,7 @@
 
         iMatchColumns = new Vector(10);
         for(int i = 0; i < 10 ; i++) {
-           iMatchColumns.add(i,new Integer(-1));
+           iMatchColumns.add(i,Integer.valueOf(-1));
         }
 
         strMatchColumns = new Vector(10);
@@ -889,7 +889,12 @@
                     success = false;
                 } else {
                     tWriter = (TransactionalWriter)rowSetWriter;
-                    ((CachedRowSetWriter)tWriter).commit(this, updateOnInsert);
+                    if (tWriter instanceof CachedRowSetWriter) {
+                        ((CachedRowSetWriter)tWriter).commit(this, updateOnInsert);
+                    } else {
+                        tWriter.commit();
+                    }
+
                     success = true;
                 }
             }
@@ -1294,7 +1299,7 @@
         tMap = new TreeMap();
 
         for (int i = 0; i<numRows; i++) {
-            tMap.put(new Integer(i), rvh.get(i));
+            tMap.put(Integer.valueOf(i), rvh.get(i));
         }
 
         return (tMap.values());
@@ -1806,7 +1811,7 @@
             return (byte)0;
         }
         try {
-            return ((new Byte(value.toString())).byteValue());
+            return ((Byte.valueOf(value.toString())).byteValue());
         } catch (NumberFormatException ex) {
             throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.bytefail").toString(),
                   new Object[] {value.toString().trim(), columnIndex}));
@@ -1850,7 +1855,7 @@
         }
 
         try {
-            return ((new Short(value.toString().trim())).shortValue());
+            return ((Short.valueOf(value.toString().trim())).shortValue());
         } catch (NumberFormatException ex) {
             throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.shortfail").toString(),
                   new Object[] {value.toString().trim(), columnIndex}));
@@ -1893,7 +1898,7 @@
         }
 
         try {
-            return ((new Integer(value.toString().trim())).intValue());
+            return ((Integer.valueOf(value.toString().trim())).intValue());
         } catch (NumberFormatException ex) {
             throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.intfail").toString(),
                   new Object[] {value.toString().trim(), columnIndex}));
@@ -1936,7 +1941,7 @@
             return (long)0;
         }
         try {
-            return ((new Long(value.toString().trim())).longValue());
+            return ((Long.valueOf(value.toString().trim())).longValue());
         } catch (NumberFormatException ex) {
             throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.longfail").toString(),
                   new Object[] {value.toString().trim(), columnIndex}));
@@ -4014,18 +4019,18 @@
         try {
             switch (trgType) {
                 case java.sql.Types.BIT:
-                    Integer i = new Integer(srcObj.toString().trim());
-                    return i.equals(new Integer((int)0)) ?
-                    new Boolean(false) :
-                        new Boolean(true);
+                    Integer i = Integer.valueOf(srcObj.toString().trim());
+                    return i.equals(Integer.valueOf((int)0)) ?
+                    Boolean.valueOf(false) :
+                        Boolean.valueOf(true);
                 case java.sql.Types.TINYINT:
-                    return new Byte(srcObj.toString().trim());
+                    return Byte.valueOf(srcObj.toString().trim());
                 case java.sql.Types.SMALLINT:
-                    return new Short(srcObj.toString().trim());
+                    return Short.valueOf(srcObj.toString().trim());
                 case java.sql.Types.INTEGER:
-                    return new Integer(srcObj.toString().trim());
+                    return Integer.valueOf(srcObj.toString().trim());
                 case java.sql.Types.BIGINT:
-                    return new Long(srcObj.toString().trim());
+                    return Long.valueOf(srcObj.toString().trim());
                 case java.sql.Types.NUMERIC:
                 case java.sql.Types.DECIMAL:
                     return new BigDecimal(srcObj.toString().trim());
@@ -4037,7 +4042,7 @@
                 case java.sql.Types.CHAR:
                 case java.sql.Types.VARCHAR:
                 case java.sql.Types.LONGVARCHAR:
-                    return new String(srcObj.toString());
+                    return srcObj.toString();
                 default:
                     throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()+ trgType);
             }
@@ -4134,7 +4139,7 @@
                 case java.sql.Types.CHAR:
                 case java.sql.Types.VARCHAR:
                 case java.sql.Types.LONGVARCHAR:
-                    return new String(srcObj.toString());
+                    return srcObj.toString();
                 default:
                     throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());
             }
@@ -4181,12 +4186,12 @@
         try {
             switch (trgType) {
                 case java.sql.Types.BIT:
-                    Integer i = new Integer(srcObj.toString().trim());
-                    return i.equals(new Integer((int)0)) ?
-                    new Boolean(false) :
-                        new Boolean(true);
+                    Integer i = Integer.valueOf(srcObj.toString().trim());
+                    return i.equals(Integer.valueOf((int)0)) ?
+                    Boolean.valueOf(false) :
+                        Boolean.valueOf(true);
                 case java.sql.Types.BOOLEAN:
-                    return new Boolean(srcObj.toString().trim());
+                    return Boolean.valueOf(srcObj.toString().trim());
                 default:
                     throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()+ trgType);
             }
@@ -4260,7 +4265,7 @@
         checkIndex(columnIndex);
         // make sure the cursor is on a valid row
         checkCursor();
-        Object obj = convertBoolean(new Boolean(x),
+        Object obj = convertBoolean(Boolean.valueOf(x),
         java.sql.Types.BIT,
         RowSetMD.getColumnType(columnIndex));
 
@@ -4296,7 +4301,7 @@
         // make sure the cursor is on a valid row
         checkCursor();
 
-        Object obj = convertNumeric(new Byte(x),
+        Object obj = convertNumeric(Byte.valueOf(x),
         java.sql.Types.TINYINT,
         RowSetMD.getColumnType(columnIndex));
 
@@ -4332,7 +4337,7 @@
         // make sure the cursor is on a valid row
         checkCursor();
 
-        Object obj = convertNumeric(new Short(x),
+        Object obj = convertNumeric(Short.valueOf(x),
         java.sql.Types.SMALLINT,
         RowSetMD.getColumnType(columnIndex));
 
@@ -4367,7 +4372,7 @@
         checkIndex(columnIndex);
         // make sure the cursor is on a valid row
         checkCursor();
-        Object obj = convertNumeric(new Integer(x),
+        Object obj = convertNumeric(Integer.valueOf(x),
         java.sql.Types.INTEGER,
         RowSetMD.getColumnType(columnIndex));
 
@@ -4403,7 +4408,7 @@
         // make sure the cursor is on a valid row
         checkCursor();
 
-        Object obj = convertNumeric(new Long(x),
+        Object obj = convertNumeric(Long.valueOf(x),
         java.sql.Types.BIGINT,
         RowSetMD.getColumnType(columnIndex));
 
@@ -6429,7 +6434,7 @@
         if (tabName == null)
             throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.tablename").toString());
         else
-            tableName = new String(tabName);
+            tableName = tabName;
     }
 
     /**
@@ -6940,7 +6945,7 @@
          }
 
          for( int i = 0;i < columnIdxes.length ;i++) {
-            iMatchColumns.set(i,new Integer(-1));
+            iMatchColumns.set(i,Integer.valueOf(-1));
          }
     }
 
@@ -7049,7 +7054,7 @@
            }
         }
         for(int i = 0 ;i < columnIdxes.length; i++) {
-           iMatchColumns.add(i,new Integer(columnIdxes[i]));
+           iMatchColumns.add(i,Integer.valueOf(columnIdxes[i]));
         }
     }
 
@@ -7104,7 +7109,7 @@
             throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols1").toString());
         } else {
             // set iMatchColumn
-            iMatchColumns.set(0, new Integer(columnIdx));
+            iMatchColumns.set(0, Integer.valueOf(columnIdx));
             //strMatchColumn = null;
         }
     }
@@ -7126,7 +7131,7 @@
      */
     public void setMatchColumn(String columnName) throws SQLException {
         // validate, if col is ok to be set
-        if(columnName.equals(null) || ((columnName = columnName.trim()) == "" )) {
+        if(columnName == null || (columnName= columnName.trim()).equals("") ) {
             throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols2").toString());
         } else {
             // set strMatchColumn
@@ -7151,13 +7156,13 @@
      */
     public void unsetMatchColumn(int columnIdx) throws SQLException {
         // check if we are unsetting the SAME column
-        if(! iMatchColumns.get(0).equals(new Integer(columnIdx) )  ) {
+        if(! iMatchColumns.get(0).equals(Integer.valueOf(columnIdx) )  ) {
             throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch").toString());
         } else if(strMatchColumns.get(0) != null) {
             throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch1").toString());
         } else {
                 // that is, we are unsetting it.
-               iMatchColumns.set(0, new Integer(-1));
+               iMatchColumns.set(0, Integer.valueOf(-1));
         }
     }
 
--- a/jdk/src/share/classes/com/sun/rowset/FilteredRowSetImpl.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/com/sun/rowset/FilteredRowSetImpl.java	Wed Jul 05 17:24:21 2017 +0200
@@ -499,7 +499,7 @@
 
      if(onInsertRow) {
         if(p != null) {
-           bool = p.evaluate(new Integer(x),columnIndex);
+           bool = p.evaluate(Integer.valueOf(x),columnIndex);
 
            if(!bool) {
               throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString());
@@ -566,7 +566,7 @@
 
       if(onInsertRow) {
          if(p != null) {
-            bool = p.evaluate(new Boolean(x) , columnIndex);
+            bool = p.evaluate(Boolean.valueOf(x) , columnIndex);
 
             if(!bool) {
                throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString());
@@ -634,7 +634,7 @@
 
       if(onInsertRow) {
          if(p != null) {
-            bool = p.evaluate(new Byte(x),columnIndex);
+            bool = p.evaluate(Byte.valueOf(x),columnIndex);
 
             if(!bool) {
                 throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString());
@@ -703,7 +703,7 @@
 
       if(onInsertRow) {
          if(p != null) {
-            bool = p.evaluate(new Short(x), columnIndex);
+            bool = p.evaluate(Short.valueOf(x), columnIndex);
 
             if(!bool) {
                throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString());
@@ -771,7 +771,7 @@
 
       if(onInsertRow) {
          if(p != null) {
-            bool = p.evaluate(new Long(x), columnIndex);
+            bool = p.evaluate(Long.valueOf(x), columnIndex);
 
             if(!bool) {
                throw new SQLException(resBundle.handleGetObject("filteredrowsetimpl.notallowed").toString());
@@ -1106,12 +1106,12 @@
    public void updateBytes(int columnIndex , byte []x) throws SQLException {
 
       boolean bool;
-      String val = new String();
+      String val = "";
 
       Byte [] obj_arr = new Byte[x.length];
 
       for(int i = 0; i < x.length; i++) {
-         obj_arr[i] = new Byte(x[i]);
+         obj_arr[i] = Byte.valueOf(x[i]);
          val = val.concat(obj_arr[i].toString());
      }
 
--- a/jdk/src/share/classes/com/sun/rowset/JdbcRowSetImpl.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/com/sun/rowset/JdbcRowSetImpl.java	Wed Jul 05 17:24:21 2017 +0200
@@ -215,7 +215,7 @@
 
         iMatchColumns = new Vector(10);
         for(int i = 0; i < 10 ; i++) {
-           iMatchColumns.add(i,new Integer(-1));
+           iMatchColumns.add(i,Integer.valueOf(-1));
         }
 
         strMatchColumns = new Vector(10);
@@ -288,7 +288,7 @@
 
         iMatchColumns = new Vector(10);
         for(int i = 0; i < 10 ; i++) {
-           iMatchColumns.add(i,new Integer(-1));
+           iMatchColumns.add(i,Integer.valueOf(-1));
         }
 
         strMatchColumns = new Vector(10);
@@ -375,7 +375,7 @@
 
         iMatchColumns = new Vector(10);
         for(int i = 0; i < 10 ; i++) {
-           iMatchColumns.add(i,new Integer(-1));
+           iMatchColumns.add(i,Integer.valueOf(-1));
         }
 
         strMatchColumns = new Vector(10);
@@ -465,7 +465,7 @@
 
         iMatchColumns = new Vector(10);
         for(int i = 0; i < 10 ; i++) {
-           iMatchColumns.add(i,new Integer(-1));
+           iMatchColumns.add(i,Integer.valueOf(-1));
         }
 
         strMatchColumns = new Vector(10);
@@ -3754,7 +3754,7 @@
          }
 
          for( int i = 0;i < columnIdxes.length ;i++) {
-            iMatchColumns.set(i,new Integer(-1));
+            iMatchColumns.set(i,Integer.valueOf(-1));
          }
     }
 
@@ -3863,7 +3863,7 @@
            }
         }
         for(int i = 0 ;i < columnIdxes.length; i++) {
-           iMatchColumns.add(i,new Integer(columnIdxes[i]));
+           iMatchColumns.add(i,Integer.valueOf(columnIdxes[i]));
         }
     }
 
@@ -3918,7 +3918,7 @@
             throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.matchcols1").toString());
         } else {
             // set iMatchColumn
-            iMatchColumns.set(0, new Integer(columnIdx));
+            iMatchColumns.set(0, Integer.valueOf(columnIdx));
             //strMatchColumn = null;
         }
     }
@@ -3940,7 +3940,7 @@
      */
     public void setMatchColumn(String columnName) throws SQLException {
         // validate, if col is ok to be set
-        if(columnName.equals(null) || ((columnName = columnName.trim()) == "" )) {
+        if(columnName == null || (columnName= columnName.trim()).equals("")) {
             throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.matchcols2").toString());
         } else {
             // set strMatchColumn
@@ -3965,13 +3965,13 @@
      */
     public void unsetMatchColumn(int columnIdx) throws SQLException {
         // check if we are unsetting the SAME column
-        if(! iMatchColumns.get(0).equals(new Integer(columnIdx) )  ) {
+        if(! iMatchColumns.get(0).equals(Integer.valueOf(columnIdx) )  ) {
             throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.unsetmatch").toString());
         } else if(strMatchColumns.get(0) != null) {
             throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.usecolname").toString());
         } else {
                 // that is, we are unsetting it.
-               iMatchColumns.set(0, new Integer(-1));
+               iMatchColumns.set(0, Integer.valueOf(-1));
         }
     }
 
--- a/jdk/src/share/classes/com/sun/rowset/JoinRowSetImpl.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/com/sun/rowset/JoinRowSetImpl.java	Wed Jul 05 17:24:21 2017 +0200
@@ -33,6 +33,8 @@
 import java.util.*;
 
 import javax.sql.rowset.*;
+import javax.sql.rowset.spi.SyncProvider;
+import javax.sql.rowset.spi.SyncProviderException;
 
 /**
  * The standard implementation of the <code>JoinRowSet</code>
@@ -550,7 +552,7 @@
                // This 'if' will be removed after all joins are implemented.
                throw new SQLException(resBundle.handleGetObject("joinrowsetimpl.notsupported").toString());
            } else {
-              Integer Intgr = new Integer(JoinRowSet.INNER_JOIN);
+              Integer Intgr = Integer.valueOf(JoinRowSet.INNER_JOIN);
               vecJoinType.add(Intgr);
            }
        } else {
@@ -874,8 +876,8 @@
 
        String strWhereClause = "Select ";
        String whereClause;
-       String tabName= null;
-       String strTabName = null;
+       String tabName= "";
+       String strTabName = "";
        int sz,cols;
        int j;
        CachedRowSetImpl crs;
@@ -889,8 +891,6 @@
        // tableNameX.(rowsetX.getMatchColumnName()) ==
        // tableNameZ.(rowsetZ.getMatchColumnName()));
 
-       tabName = new String();
-       strTabName  = new String();
        sz = vecRowSetsInJOIN.size();
        for(int i=0;i<sz; i++) {
           crs = (CachedRowSetImpl)vecRowSetsInJOIN.get(i);
@@ -4311,6 +4311,27 @@
          return crsInternal.createCopySchema();
      }
 
+     /**
+      * {@inheritDoc}
+      */
+     public void setSyncProvider(String providerStr) throws SQLException {
+         crsInternal.setSyncProvider(providerStr);
+     }
+
+     /**
+      * {@inheritDoc}
+      */
+     public void acceptChanges() throws SyncProviderException {
+         crsInternal.acceptChanges();
+     }
+
+     /**
+      * {@inheritDoc}
+      */
+     public SyncProvider getSyncProvider() throws SQLException {
+        return crsInternal.getSyncProvider();
+     }
+
     /**
      * This method re populates the resBundle
      * during the deserialization process
--- a/jdk/src/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java	Wed Jul 05 17:24:21 2017 +0200
@@ -338,11 +338,11 @@
             if (crs.rowDeleted()) {
                 // The row has been deleted.
                 if (conflict = (deleteOriginalRow(crs, this.crsResolve)) == true) {
-                       status.add(rows, new Integer(SyncResolver.DELETE_ROW_CONFLICT));
+                       status.add(rows, Integer.valueOf(SyncResolver.DELETE_ROW_CONFLICT));
                 } else {
                       // delete happened without any occurrence of conflicts
                       // so update status accordingly
-                       status.add(rows, new Integer(SyncResolver.NO_ROW_CONFLICT));
+                       status.add(rows, Integer.valueOf(SyncResolver.NO_ROW_CONFLICT));
                 }
 
            } else if (crs.rowInserted()) {
@@ -350,20 +350,20 @@
 
                 pstmtIns = con.prepareStatement(insertCmd);
                 if ( (conflict = insertNewRow(crs, pstmtIns, this.crsResolve)) == true) {
-                          status.add(rows, new Integer(SyncResolver.INSERT_ROW_CONFLICT));
+                          status.add(rows, Integer.valueOf(SyncResolver.INSERT_ROW_CONFLICT));
                 } else {
                       // insert happened without any occurrence of conflicts
                       // so update status accordingly
-                       status.add(rows, new Integer(SyncResolver.NO_ROW_CONFLICT));
+                       status.add(rows, Integer.valueOf(SyncResolver.NO_ROW_CONFLICT));
                 }
             } else  if (crs.rowUpdated()) {
                   // The row has been updated.
                        if ( conflict = (updateOriginalRow(crs)) == true) {
-                             status.add(rows, new Integer(SyncResolver.UPDATE_ROW_CONFLICT));
+                             status.add(rows, Integer.valueOf(SyncResolver.UPDATE_ROW_CONFLICT));
                } else {
                       // update happened without any occurrence of conflicts
                       // so update status accordingly
-                      status.add(rows, new Integer(SyncResolver.NO_ROW_CONFLICT));
+                      status.add(rows, Integer.valueOf(SyncResolver.NO_ROW_CONFLICT));
                }
 
             } else {
@@ -375,7 +375,7 @@
                 *  that is fine.
                 **/
                 int icolCount = crs.getMetaData().getColumnCount();
-                status.add(rows, new Integer(SyncResolver.NO_ROW_CONFLICT));
+                status.add(rows, Integer.valueOf(SyncResolver.NO_ROW_CONFLICT));
 
                 this.crsResolve.moveToInsertRow();
                 for(int cols=0;cols<iColCount;cols++) {
@@ -398,7 +398,7 @@
       boolean boolConf = false;
       for (int j=1;j<status.size();j++){
           // ignore status for index = 0 which is set to null
-          if(! ((status.get(j)).equals(new Integer(SyncResolver.NO_ROW_CONFLICT)))) {
+          if(! ((status.get(j)).equals(Integer.valueOf(SyncResolver.NO_ROW_CONFLICT)))) {
               // there is at least one conflict which needs to be resolved
               boolConf = true;
              break;
@@ -541,7 +541,7 @@
                 // how many fields need to be updated
                 int colsNotChanged = 0;
                 Vector cols = new Vector();
-                String updateExec = new String(updateCmd);
+                String updateExec = updateCmd;
                 Object orig;
                 Object curr;
                 Object rsval;
@@ -652,7 +652,7 @@
                           updateExec += ", ";
                          }
                         updateExec += crs.getMetaData().getColumnName(i);
-                        cols.add(new Integer(i));
+                        cols.add(Integer.valueOf(i));
                         updateExec += " = ? ";
                         first = false;
 
@@ -698,7 +698,7 @@
                                     updateExec += ", ";
                                  }
                                 updateExec += crs.getMetaData().getColumnName(i);
-                                cols.add(new Integer(i));
+                                cols.add(Integer.valueOf(i));
                                 updateExec += " = ? ";
                                 flag = false;
                              } else {
@@ -1184,7 +1184,7 @@
        // trim all the leading and trailing whitespaces,
        // white spaces can never be catalog, schema or a table name.
 
-        String cmd = new String();
+        String cmd = "";
 
         catalog = catalog.trim();
         schema = schema.trim();
--- a/jdk/src/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java	Wed Jul 05 17:24:21 2017 +0200
@@ -248,7 +248,7 @@
             String strProvider = strProviderInstance.substring(0, (caller.getSyncProvider()).toString().indexOf("@"));
 
             propString("sync-provider-name", strProvider);
-            propString("sync-provider-vendor", "Sun Microsystems Inc.");
+            propString("sync-provider-vendor", "Oracle Corporation");
             propString("sync-provider-version", "1.0");
             propInteger("sync-provider-grade", caller.getSyncProvider().getProviderGrade());
             propInteger("data-source-lock", caller.getSyncProvider().getDataSourceLock());
@@ -387,7 +387,7 @@
                     if (caller.wasNull())
                         writeNull();
                     else
-                        writeInteger(caller.getInt(idx));
+                        writeInteger(i);
                     break;
                 case java.sql.Types.BIGINT:
                     long l = caller.getLong(idx);
@@ -574,7 +574,7 @@
     }
 
     private void writeBoolean(boolean b) throws java.io.IOException {
-        writer.write(new Boolean(b).toString());
+        writer.write(Boolean.valueOf(b).toString());
     }
 
     private void writeFloat(float f) throws java.io.IOException {
@@ -641,7 +641,7 @@
             return null;
         }
         char []charStr = s.toCharArray();
-        String specialStr = new String();
+        String specialStr = "";
 
         for(int i = 0; i < charStr.length; i++) {
             if(charStr[i] == '&') {
--- a/jdk/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java	Wed Jul 05 17:24:21 2017 +0200
@@ -441,9 +441,9 @@
         updates = new Vector();
 
         // start out with the empty string
-        columnValue = new String("");
-        propertyValue = new String("");
-        metaDataValue = new String("");
+        columnValue = "";
+        propertyValue = "";
+        metaDataValue = "";
 
         nullVal = false;
         idx = 0;
@@ -481,21 +481,21 @@
         items = properties.length;
 
         for (i=0;i<items;i++) {
-            propMap.put(properties[i], new Integer(i));
+            propMap.put(properties[i], Integer.valueOf(i));
         }
 
         colDefMap = new HashMap();
         items = colDef.length;
 
         for (i=0;i<items;i++) {
-            colDefMap.put(colDef[i], new Integer(i));
+            colDefMap.put(colDef[i], Integer.valueOf(i));
         }
 
         dataMap = new HashMap();
         items = data.length;
 
         for (i=0;i<items;i++) {
-            dataMap.put(data[i], new Integer(i));
+            dataMap.put(data[i], Integer.valueOf(i));
         }
 
         //Initialize connection map here
@@ -686,7 +686,7 @@
             }
 
             // propertyValue need to be reset to an empty string
-            propertyValue = new String("");
+            propertyValue = "";
             setTag(-1);
             break;
         case METADATA:
@@ -710,7 +710,7 @@
 
                 }
                 // metaDataValue needs to be reset to an empty string
-                metaDataValue = new String("");
+                metaDataValue = "";
             }
             setTag(-1);
             break;
@@ -736,7 +736,7 @@
                         insertValue(tempStr);
                     }
                     // columnValue now need to be reset to the empty string
-                    columnValue = new String("");
+                    columnValue = "";
                 } catch (SQLException ex) {
                     throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errinsert").toString(), ex.getMessage()));
                 }
@@ -981,7 +981,7 @@
 
     private boolean getBooleanValue(String s) {
 
-        return new Boolean(s).booleanValue();
+        return Boolean.valueOf(s).booleanValue();
     }
 
     private java.math.BigDecimal getBigDecimalValue(String s) {
@@ -1316,7 +1316,7 @@
               **/
 
             tempUpdate = tempUpdate.concat(new String(ch,start,len));
-            upd[0] = new Integer(idx);
+            upd[0] = Integer.valueOf(idx);
             upd[1] = tempUpdate;
             //updates.add(upd);
 
--- a/jdk/src/share/classes/com/sun/rowset/providers/RIOptimisticProvider.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/com/sun/rowset/providers/RIOptimisticProvider.java	Wed Jul 05 17:24:21 2017 +0200
@@ -93,14 +93,14 @@
     private CachedRowSetWriter writer;
 
     /**
-     * The unique provider indentifier.
+     * The unique provider identifier.
      */
     private String providerID = "com.sun.rowset.providers.RIOptimisticProvider";
 
     /**
      * The vendor name of this SyncProvider implementation
      */
-    private String vendorName = "Sun Microsystems Inc.";
+    private String vendorName = "Oracle Corporation";
 
     /**
      * The version number of this SyncProvider implementation
@@ -236,8 +236,8 @@
     }
 
     /**
-     * Returns the vendor name of the Reference Implemntation Optimistic
-     * Syncchronication Provider
+     * Returns the vendor name of the Reference Implementation Optimistic
+     * Synchronization Provider
      *
      * @return the <code>String</code> detailing the vendor name of this
      *      SyncProvider
--- a/jdk/src/share/classes/com/sun/rowset/providers/RIXMLProvider.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/com/sun/rowset/providers/RIXMLProvider.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -85,7 +85,7 @@
     /**
      * The vendor name of this SyncProvider implementation.
      */
-    private String vendorName = "Sun Microsystems Inc.";
+    private String vendorName = "Oracle Corporation";
 
     /**
      * The version number of this SyncProvider implementation.
--- a/jdk/src/share/classes/com/sun/servicetag/Installer.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/com/sun/servicetag/Installer.java	Wed Jul 05 17:24:21 2017 +0200
@@ -43,7 +43,8 @@
         "servicetag.dir.path";
     private static String SVCTAG_ENABLE_REGISTRATION =
         "servicetag.registration.enabled";
-    private final static String SUN_VENDOR = "Sun Microsystems";
+    private final static String ORACLE = "Oracle";
+    private final static String SUN = "Sun Microsystems";
     private final static String REGISTRATION_XML = "registration.xml";
     private final static String SERVICE_TAG_FILE = "servicetag";
     private final static String REGISTRATION_HTML_NAME = "register";
@@ -84,9 +85,10 @@
 
     // Implementation of ServiceTag.getJavaServiceTag(String) method
     static ServiceTag getJavaServiceTag(String source) throws IOException {
-        if (!System.getProperty("java.vendor").startsWith(SUN_VENDOR)) {
+        String vendor = System.getProperty("java.vendor", "");
+        if (!vendor.startsWith(SUN) && !vendor.startsWith(ORACLE)) {
             // Products bundling this implementation may run on
-            // Mac OS which is not a Sun JDK
+            // Mac OS which is not a Sun/Oracle JDK
             return null;
         }
         boolean cleanup = false;
@@ -365,7 +367,7 @@
                                       props.getProperty("servicetag.parent.name"),
                                       props.getProperty("servicetag.parent.urn"),
                                       getProductDefinedId(),
-                                      SUN_VENDOR,
+                                      System.getProperty("java.vendor"),
                                       System.getProperty("os.arch"),
                                       getZoneName(),
                                       svcTagSource);
--- a/jdk/src/share/classes/com/sun/servicetag/RegistrationData.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/com/sun/servicetag/RegistrationData.java	Wed Jul 05 17:24:21 2017 +0200
@@ -80,12 +80,12 @@
  *       <tr>
  *          <td><tt>systemManufacturer</tt></td>
  *          <td>System manufacturer</td>
- *          <td> e.g. Sun Microsystems</td>
+ *          <td> e.g. Oracle Corporation</td>
  *       </tr>
  *       <tr>
  *          <td><tt>cpuManufacturer</tt></td>
  *          <td>CPU manufacturer</td>
- *          <td> e.g. Sun Microsystems</td>
+ *          <td> e.g. Oracle Corporation</td>
  *       </tr>
  *       <tr>
  *          <td><tt>serialNumber</tt></td>
--- a/jdk/src/share/classes/com/sun/servicetag/Registry.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/com/sun/servicetag/Registry.java	Wed Jul 05 17:24:21 2017 +0200
@@ -90,7 +90,7 @@
                 stclient = getWindowsStClientFile();
             } else {
                 if (isVerbose()) {
-                    System.out.println("Running on non-Sun JDK");
+                    System.out.println("Running on unsupported platform");
                 }
             }
             initialized = true;
--- a/jdk/src/share/classes/com/sun/servicetag/SolarisSystemEnvironment.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/com/sun/servicetag/SolarisSystemEnvironment.java	Wed Jul 05 17:24:21 2017 +0200
@@ -44,6 +44,7 @@
  * Solaris implementation of the SystemEnvironment class.
  */
 class SolarisSystemEnvironment extends SystemEnvironment {
+    private static final String ORACLE = "Oracle Corporation";
     SolarisSystemEnvironment() {
         setHostId(getCommandOutput("/usr/bin/hostid"));
         setSystemModel(getCommandOutput("/usr/bin/uname", "-i"));
@@ -59,7 +60,7 @@
     private String getSolarisCpuManufacturer() {
         // not fully accurate, this could be another manufacturer (fujitsu for example)
         if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) {
-            return "Sun Microsystems, Inc";
+            return ORACLE;
         }
 
         // if we're here, then we'll try smbios (type 4)
@@ -73,7 +74,7 @@
     private String getSolarisSystemManufacturer() {
         // not fully accurate, this could be another manufacturer (fujitsu for example)
         if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) {
-            return "Sun Microsystems, Inc";
+            return ORACLE;
         }
 
         // if we're here, then we'll try smbios (type 1)
@@ -117,7 +118,7 @@
     // ID    SIZE TYPE
     // 1     150  SMB_TYPE_SYSTEM (system information)
     //
-    //   Manufacturer: Sun Microsystems
+    //   Manufacturer: Oracle Corporation
     //   Product: Sun Fire X4600
     //   Version: To Be Filled By O.E.M.
     //   Serial Number: 00:14:4F:45:0C:2A
--- a/jdk/src/share/classes/java/awt/Dialog.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/java/awt/Dialog.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1068,7 +1068,7 @@
                     modalityPushed();
                     try {
                         EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
-                        secondaryLoop = eventQueue.createSecondaryLoop(cond, modalFilter, 5000);
+                        secondaryLoop = eventQueue.createSecondaryLoop(cond, modalFilter, 0);
                         if (!secondaryLoop.enter()) {
                             secondaryLoop = null;
                         }
--- a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java	Wed Jul 05 17:24:21 2017 +0200
@@ -142,6 +142,9 @@
                 public void removeLastFocusRequest(Component heavyweight) {
                     KeyboardFocusManager.removeLastFocusRequest(heavyweight);
                 }
+                public void setMostRecentFocusOwner(Window window, Component component) {
+                    KeyboardFocusManager.setMostRecentFocusOwner(window, component);
+                }
             }
         );
     }
--- a/jdk/src/share/classes/java/awt/event/ActionEvent.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/java/awt/event/ActionEvent.java	Wed Jul 05 17:24:21 2017 +0200
@@ -51,7 +51,7 @@
  * in the range from {@code ACTION_FIRST} to {@code ACTION_LAST}.
  *
  * @see ActionListener
- * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/eventmodel.html">Tutorial: Java 1.1 Event Model</a>
+ * @see <a href="http://java.sun.com/docs/books/tutorial/uiswing/events/actionlistener.html">Tutorial: How to Write an Action Listener</a>
  *
  * @author Carl Quinn
  * @since 1.1
--- a/jdk/src/share/classes/java/awt/image/SampleModel.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/java/awt/image/SampleModel.java	Wed Jul 05 17:24:21 2017 +0200
@@ -937,14 +937,22 @@
                             int iArray[], DataBuffer data) {
         int pixels[];
         int Offset=0;
+        int x1 = x + w;
+        int y1 = y + h;
+
+        if (x < 0 || x1 < x || x1 > width ||
+            y < 0 || y1 < y || y1 > height)
+        {
+            throw new ArrayIndexOutOfBoundsException("Invalid coordinates.");
+        }
 
         if (iArray != null)
             pixels = iArray;
         else
             pixels = new int[w * h];
 
-        for(int i=y; i<(h+y); i++) {
-            for (int j=x; j<(w+x); j++) {
+        for(int i=y; i<y1; i++) {
+            for (int j=x; j<x1; j++) {
                 pixels[Offset++] = getSample(j, i, b, data);
             }
         }
@@ -978,14 +986,22 @@
                               DataBuffer data) {
         float pixels[];
         int   Offset=0;
+        int x1 = x + w;
+        int y1 = y + h;
+
+        if (x < 0 || x1 < x || x1 > width ||
+            y < 0 || y1 < y || y1 > height)
+        {
+            throw new ArrayIndexOutOfBoundsException("Invalid coordinates");
+        }
 
         if (fArray != null)
             pixels = fArray;
         else
             pixels = new float[w * h];
 
-        for (int i=y; i<(h+y); i++) {
-            for (int j=x; j<(w+x); j++) {
+        for (int i=y; i<y1; i++) {
+            for (int j=x; j<x1; j++) {
                 pixels[Offset++] = getSampleFloat(j, i, b, data);
             }
         }
@@ -1019,14 +1035,22 @@
                                DataBuffer data) {
         double pixels[];
         int    Offset=0;
+        int x1 = x + w;
+        int y1 = y + h;
+
+        if (x < 0 || x1 < x || x1 > width ||
+            y < 0 || y1 < y || y1 > height)
+        {
+            throw new ArrayIndexOutOfBoundsException("Invalid coordinates");
+        }
 
         if (dArray != null)
             pixels = dArray;
         else
             pixels = new double[w * h];
 
-        for (int i=y; i<(y+h); i++) {
-            for (int j=x; j<(x+w); j++) {
+        for (int i=y; i<y1; i++) {
+            for (int j=x; j<x1; j++) {
                 pixels[Offset++] = getSampleDouble(j, i, b, data);
             }
         }
--- a/jdk/src/share/classes/java/beans/EventSetDescriptor.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/java/beans/EventSetDescriptor.java	Wed Jul 05 17:24:21 2017 +0200
@@ -176,8 +176,9 @@
         setRemoveListenerMethod(getMethod(sourceClass, removeListenerMethodName, 1));
 
         // Be more forgiving of not finding the getListener method.
-        if (getListenerMethodName != null) {
-            setGetListenerMethod(Introspector.findInstanceMethod(sourceClass, getListenerMethodName));
+        Method method = Introspector.findMethod(sourceClass, getListenerMethodName, 0);
+        if (method != null) {
+            setGetListenerMethod(method);
         }
     }
 
--- a/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java	Wed Jul 05 17:24:21 2017 +0200
@@ -189,11 +189,13 @@
                     indexedReadMethodName = Introspector.GET_PREFIX + getBaseName();
                 }
             }
-            indexedReadMethod = Introspector.findInstanceMethod(cls, indexedReadMethodName, int.class);
+
+            Class[] args = { int.class };
+            indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args);
             if (indexedReadMethod == null) {
                 // no "is" method, so look for a "get" method.
                 indexedReadMethodName = Introspector.GET_PREFIX + getBaseName();
-                indexedReadMethod = Introspector.findInstanceMethod(cls, indexedReadMethodName, int.class);
+                indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args);
             }
             setIndexedReadMethod0(indexedReadMethod);
         }
@@ -265,7 +267,9 @@
             if (indexedWriteMethodName == null) {
                 indexedWriteMethodName = Introspector.SET_PREFIX + getBaseName();
             }
-            indexedWriteMethod = Introspector.findInstanceMethod(cls, indexedWriteMethodName, int.class, type);
+
+            Class[] args = (type == null) ? null : new Class[] { int.class, type };
+            indexedWriteMethod = Introspector.findMethod(cls, indexedWriteMethodName, 2, args);
             if (indexedWriteMethod != null) {
                 if (!indexedWriteMethod.getReturnType().equals(void.class)) {
                     indexedWriteMethod = null;
--- a/jdk/src/share/classes/java/beans/Introspector.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/java/beans/Introspector.java	Wed Jul 05 17:24:21 2017 +0200
@@ -28,7 +28,6 @@
 import com.sun.beans.WeakCache;
 import com.sun.beans.finder.BeanInfoFinder;
 import com.sun.beans.finder.ClassFinder;
-import com.sun.beans.finder.MethodFinder;
 
 import java.lang.ref.Reference;
 import java.lang.ref.SoftReference;
@@ -843,8 +842,8 @@
                 Method read = result.getReadMethod();
 
                 if (read == null && write != null) {
-                    read = findInstanceMethod(result.getClass0(),
-                                              GET_PREFIX + NameGenerator.capitalize(result.getName()));
+                    read = findMethod(result.getClass0(),
+                                      GET_PREFIX + NameGenerator.capitalize(result.getName()), 0);
                     if (read != null) {
                         try {
                             result.setReadMethod(read);
@@ -854,9 +853,9 @@
                     }
                 }
                 if (write == null && read != null) {
-                    write = findInstanceMethod(result.getClass0(),
-                                               SET_PREFIX + NameGenerator.capitalize(result.getName()),
-                                               FeatureDescriptor.getReturnType(result.getClass0(), read));
+                    write = findMethod(result.getClass0(),
+                                       SET_PREFIX + NameGenerator.capitalize(result.getName()), 1,
+                                       new Class[] { FeatureDescriptor.getReturnType(result.getClass0(), read) });
                     if (write != null) {
                         try {
                             result.setWriteMethod(write);
@@ -1280,27 +1279,90 @@
     // Package private support methods.
     //======================================================================
 
-    static Method findMethod(Class<?> type, String name, int args) {
-        for (Method method : type.getMethods()) {
-            if (method.getName().equals(name) && (args == method.getParameterTypes().length)) {
-                try {
-                    return MethodFinder.findAccessibleMethod(method);
+    /**
+     * Internal support for finding a target methodName with a given
+     * parameter list on a given class.
+     */
+    private static Method internalFindMethod(Class start, String methodName,
+                                                 int argCount, Class args[]) {
+        // For overriden methods we need to find the most derived version.
+        // So we start with the given class and walk up the superclass chain.
+
+        Method method = null;
+
+        for (Class cl = start; cl != null; cl = cl.getSuperclass()) {
+            Method methods[] = getPublicDeclaredMethods(cl);
+            for (int i = 0; i < methods.length; i++) {
+                method = methods[i];
+                if (method == null) {
+                    continue;
                 }
-                catch (NoSuchMethodException exception) {
-                    // continue search for a method with the specified count of parameters
+
+                // make sure method signature matches.
+                Class params[] = FeatureDescriptor.getParameterTypes(start, method);
+                if (method.getName().equals(methodName) &&
+                    params.length == argCount) {
+                    if (args != null) {
+                        boolean different = false;
+                        if (argCount > 0) {
+                            for (int j = 0; j < argCount; j++) {
+                                if (params[j] != args[j]) {
+                                    different = true;
+                                    continue;
+                                }
+                            }
+                            if (different) {
+                                continue;
+                            }
+                        }
+                    }
+                    return method;
                 }
             }
         }
-        return null;
+        method = null;
+
+        // Now check any inherited interfaces.  This is necessary both when
+        // the argument class is itself an interface, and when the argument
+        // class is an abstract class.
+        Class ifcs[] = start.getInterfaces();
+        for (int i = 0 ; i < ifcs.length; i++) {
+            // Note: The original implementation had both methods calling
+            // the 3 arg method. This is preserved but perhaps it should
+            // pass the args array instead of null.
+            method = internalFindMethod(ifcs[i], methodName, argCount, null);
+            if (method != null) {
+                break;
+            }
+        }
+        return method;
     }
 
-    static Method findInstanceMethod(Class<?> type, String name, Class<?>... args) {
-        try {
-            return MethodFinder.findInstanceMethod(type, name, args);
-        }
-        catch (NoSuchMethodException exception) {
+    /**
+     * Find a target methodName on a given class.
+     */
+    static Method findMethod(Class cls, String methodName, int argCount) {
+        return findMethod(cls, methodName, argCount, null);
+    }
+
+    /**
+     * Find a target methodName with specific parameter list on a given class.
+     * <p>
+     * Used in the contructors of the EventSetDescriptor,
+     * PropertyDescriptor and the IndexedPropertyDescriptor.
+     * <p>
+     * @param cls The Class object on which to retrieve the method.
+     * @param methodName Name of the method.
+     * @param argCount Number of arguments for the desired method.
+     * @param args Array of argument types for the method.
+     * @return the method or null if not found
+     */
+    static Method findMethod(Class cls, String methodName, int argCount,
+                             Class args[]) {
+        if (methodName == null) {
             return null;
         }
+        return internalFindMethod(cls, methodName, argCount, args);
     }
 
     /**
--- a/jdk/src/share/classes/java/beans/MethodDescriptor.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/java/beans/MethodDescriptor.java	Wed Jul 05 17:24:21 2017 +0200
@@ -90,13 +90,13 @@
                         // Find methods for up to 2 params. We are guessing here.
                         // This block should never execute unless the classloader
                         // that loaded the argument classes disappears.
-                        method = Introspector.findMethod(cls, name, i);
+                        method = Introspector.findMethod(cls, name, i, null);
                         if (method != null) {
                             break;
                         }
                     }
                 } else {
-                    method = Statement.getMethod(cls, name, params);
+                    method = Introspector.findMethod(cls, name, params.length, params);
                 }
                 setMethod(method);
             }
--- a/jdk/src/share/classes/java/beans/PropertyDescriptor.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/java/beans/PropertyDescriptor.java	Wed Jul 05 17:24:21 2017 +0200
@@ -112,7 +112,8 @@
         // If this class or one of its base classes allow PropertyChangeListener,
         // then we assume that any properties we discover are "bound".
         // See Introspector.getTargetPropertyInfo() method.
-        this.bound = null != Introspector.findInstanceMethod(beanClass, "addPropertyChangeListener", PropertyChangeListener.class);
+        Class[] args = { PropertyChangeListener.class };
+        this.bound = null != Introspector.findMethod(beanClass, "addPropertyChangeListener", args.length, args);
     }
 
     /**
@@ -223,10 +224,10 @@
             // property type is.  For booleans, there can be "is" and "get"
             // methods.  If an "is" method exists, this is the official
             // reader method so look for this one first.
-            readMethod = Introspector.findInstanceMethod(cls, readMethodName);
+            readMethod = Introspector.findMethod(cls, readMethodName, 0);
             if (readMethod == null) {
                 readMethodName = Introspector.GET_PREFIX + getBaseName();
-                readMethod = Introspector.findInstanceMethod(cls, readMethodName);
+                readMethod = Introspector.findMethod(cls, readMethodName, 0);
             }
             try {
                 setReadMethod(readMethod);
@@ -291,7 +292,8 @@
                 writeMethodName = Introspector.SET_PREFIX + getBaseName();
             }
 
-            writeMethod = Introspector.findInstanceMethod(cls, writeMethodName, type);
+            Class[] args = (type == null) ? null : new Class[] { type };
+            writeMethod = Introspector.findMethod(cls, writeMethodName, 1, args);
             if (writeMethod != null) {
                 if (!writeMethod.getReturnType().equals(void.class)) {
                     writeMethod = null;
--- a/jdk/src/share/classes/java/lang/System.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/java/lang/System.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1101,22 +1101,12 @@
         lineSeparator = props.getProperty("line.separator");
         sun.misc.Version.init();
 
-        // Workaround until DownloadManager initialization is revisited.
-        // Make JavaLangAccess available early enough for internal
-        // Shutdown hooks to be registered
-        setJavaLangAccess();
-
         // Gets and removes system properties that configure the Integer
         // cache used to support the object identity semantics of autoboxing.
         // At this time, the size of the cache may be controlled by the
         // vm option -XX:AutoBoxCacheMax=<size>.
         Integer.getAndRemoveCacheProperties();
 
-        // Load the zip library now in order to keep java.util.zip.ZipFile
-        // from trying to use itself to load this library later.
-        loadLibrary("zip");
-
-
         FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
         FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
         FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
@@ -1124,6 +1114,10 @@
         setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
         setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true));
 
+        // Load the zip library now in order to keep java.util.zip.ZipFile
+        // from trying to use itself to load this library later.
+        loadLibrary("zip");
+
         // Setup Java signal handlers for HUP, TERM, and INT (where available).
         Terminator.setup();
 
@@ -1153,6 +1147,9 @@
         // way as other threads; we must do it ourselves here.
         Thread current = Thread.currentThread();
         current.getThreadGroup().add(current);
+
+        // register shared secrets
+        setJavaLangAccess();
     }
 
     private static void setJavaLangAccess() {
--- a/jdk/src/share/classes/java/net/InetAddress.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/java/net/InetAddress.java	Wed Jul 05 17:24:21 2017 +0200
@@ -677,19 +677,20 @@
 
     static InetAddressImpl  impl;
 
-    private static HashMap          lookupTable = new HashMap();
+    private static HashMap<String, InetAddress[]> lookupTable
+        = new HashMap<String, InetAddress[]>();
 
     /**
      * Represents a cache entry
      */
     static final class CacheEntry {
 
-        CacheEntry(Object address, long expiration) {
-            this.address = address;
+        CacheEntry(InetAddress[] addresses, long expiration) {
+            this.addresses = addresses;
             this.expiration = expiration;
         }
 
-        Object address;
+        InetAddress[] addresses;
         long expiration;
     }
 
@@ -698,7 +699,7 @@
      * at creation time.
      */
     static final class Cache {
-        private LinkedHashMap cache;
+        private LinkedHashMap<String, CacheEntry> cache;
         private Type type;
 
         enum Type {Positive, Negative};
@@ -708,7 +709,7 @@
          */
         public Cache(Type type) {
             this.type = type;
-            cache = new LinkedHashMap();
+            cache = new LinkedHashMap<String, CacheEntry>();
         }
 
         private int getPolicy() {
@@ -724,7 +725,7 @@
          * entry then for this host then the entry will be
          * replaced.
          */
-        public Cache put(String host, Object address) {
+        public Cache put(String host, InetAddress[] addresses) {
             int policy = getPolicy();
             if (policy == InetAddressCachePolicy.NEVER) {
                 return this;
@@ -736,12 +737,10 @@
 
                 // As we iterate in insertion order we can
                 // terminate when a non-expired entry is found.
-                LinkedList expired = new LinkedList();
-                Iterator i = cache.keySet().iterator();
+                LinkedList<String> expired = new LinkedList<String>();
                 long now = System.currentTimeMillis();
-                while (i.hasNext()) {
-                    String key = (String)i.next();
-                    CacheEntry entry = (CacheEntry)cache.get(key);
+                for (String key : cache.keySet()) {
+                    CacheEntry entry = cache.get(key);
 
                     if (entry.expiration >= 0 && entry.expiration < now) {
                         expired.add(key);
@@ -750,9 +749,8 @@
                     }
                 }
 
-                i = expired.iterator();
-                while (i.hasNext()) {
-                    cache.remove(i.next());
+                for (String key : expired) {
+                    cache.remove(key);
                 }
             }
 
@@ -766,7 +764,7 @@
             } else {
                 expiration = System.currentTimeMillis() + (policy * 1000);
             }
-            CacheEntry entry = new CacheEntry(address, expiration);
+            CacheEntry entry = new CacheEntry(addresses, expiration);
             cache.put(host, entry);
             return this;
         }
@@ -780,7 +778,7 @@
             if (policy == InetAddressCachePolicy.NEVER) {
                 return null;
             }
-            CacheEntry entry = (CacheEntry)cache.get(host);
+            CacheEntry entry = cache.get(host);
 
             // check if entry has expired
             if (entry != null && policy != InetAddressCachePolicy.FOREVER) {
@@ -814,42 +812,41 @@
     }
 
     /*
-     * Cache the given hostname and address.
+     * Cache the given hostname and addresses.
      */
-    private static void cacheAddress(String hostname, Object address,
-                                     boolean success) {
+    private static void cacheAddresses(String hostname,
+                                       InetAddress[] addresses,
+                                       boolean success) {
         hostname = hostname.toLowerCase();
         synchronized (addressCache) {
             cacheInitIfNeeded();
             if (success) {
-                addressCache.put(hostname, address);
+                addressCache.put(hostname, addresses);
             } else {
-                negativeCache.put(hostname, address);
+                negativeCache.put(hostname, addresses);
             }
         }
     }
 
     /*
      * Lookup hostname in cache (positive & negative cache). If
-     * found return address, null if not found.
+     * found return addresses, null if not found.
      */
-    private static Object getCachedAddress(String hostname) {
+    private static InetAddress[] getCachedAddresses(String hostname) {
         hostname = hostname.toLowerCase();
 
         // search both positive & negative caches
 
         synchronized (addressCache) {
-            CacheEntry entry;
-
             cacheInitIfNeeded();
 
-            entry = addressCache.get(hostname);
+            CacheEntry entry = addressCache.get(hostname);
             if (entry == null) {
                 entry = negativeCache.get(hostname);
             }
 
             if (entry != null) {
-                return entry.address;
+                return entry.addresses;
             }
         }
 
@@ -911,7 +908,7 @@
 
     static {
         // create the impl
-        impl = (new InetAddressImplFactory()).create();
+        impl = InetAddressImplFactory.create();
 
         // get name service if provided and requested
         String provider = null;;
@@ -931,7 +928,7 @@
         }
 
         // if not designate any name services provider,
-        // creat a default one
+        // create a default one
         if (nameServices.size() == 0) {
             NameService ns = createNSProvider("default");
             nameServices.add(ns);
@@ -939,7 +936,7 @@
     }
 
     /**
-     * Create an InetAddress based on the provided host name and IP address
+     * Creates an InetAddress based on the provided host name and IP address.
      * No name service is checked for the validity of the address.
      *
      * <p> The host name can either be a machine name, such as
@@ -1067,13 +1064,13 @@
 
         boolean ipv6Expected = false;
         if (host.charAt(0) == '[') {
-            // This is supposed to be an IPv6 litteral
+            // This is supposed to be an IPv6 literal
             if (host.length() > 2 && host.charAt(host.length()-1) == ']') {
                 host = host.substring(1, host.length() -1);
                 ipv6Expected = true;
             } else {
                 // This was supposed to be a IPv6 address, but it's not!
-                throw new UnknownHostException(host);
+                throw new UnknownHostException(host + ": invalid IPv6 address");
             }
         }
 
@@ -1180,8 +1177,6 @@
         throws UnknownHostException  {
         /* If it gets here it is presumed to be a hostname */
         /* Cache.get can return: null, unknownAddress, or InetAddress[] */
-        Object obj = null;
-        Object objcopy = null;
 
         /* make sure the connection to the host is allowed, before we
          * give out a hostname
@@ -1193,26 +1188,23 @@
             }
         }
 
-        obj = getCachedAddress(host);
+        InetAddress[] addresses = getCachedAddresses(host);
 
         /* If no entry in cache, then do the host lookup */
-        if (obj == null) {
-            obj = getAddressFromNameService(host);
+        if (addresses == null) {
+            addresses = getAddressesFromNameService(host);
         }
 
-        if (obj == unknown_array)
+        if (addresses == unknown_array)
             throw new UnknownHostException(host);
 
-        /* Make a copy of the InetAddress array */
-        objcopy = ((InetAddress [])obj).clone();
-
-        return (InetAddress [])objcopy;
+        return addresses.clone();
     }
 
-    private static Object getAddressFromNameService(String host)
+    private static InetAddress[] getAddressesFromNameService(String host)
         throws UnknownHostException
     {
-        Object obj = null;
+        InetAddress[] addresses = null;
         boolean success = false;
         UnknownHostException ex = null;
 
@@ -1226,16 +1218,16 @@
         //    would be blocked until the host is removed
         //    from the lookupTable. Then this thread
         //    should try to look up the addressCache.
-        //     i) if it found the address in the
+        //     i) if it found the addresses in the
         //        addressCache, checkLookupTable()  would
-        //        return the address.
-        //     ii) if it didn't find the address in the
+        //        return the addresses.
+        //     ii) if it didn't find the addresses in the
         //         addressCache for any reason,
         //         it should add the host in the
         //         lookupTable and return null so the
         //         following code would do  a lookup itself.
-        if ((obj = checkLookupTable(host)) == null) {
-            // This is the first thread which looks up the address
+        if ((addresses = checkLookupTable(host)) == null) {
+            // This is the first thread which looks up the addresses
             // this host or the cache entry for this host has been
             // expired so this thread should do the lookup.
             for (NameService nameService : nameServices) {
@@ -1246,26 +1238,26 @@
                      * allocating space when the lookup fails.
                      */
 
-                    obj = nameService.lookupAllHostAddr(host);
+                    addresses = nameService.lookupAllHostAddr(host);
                     success = true;
                     break;
                 } catch (UnknownHostException uhe) {
                     if (host.equalsIgnoreCase("localhost")) {
                         InetAddress[] local = new InetAddress[] { impl.loopbackAddress() };
-                        obj = local;
+                        addresses = local;
                         success = true;
                         break;
                     }
                     else {
-                        obj  = unknown_array;
+                        addresses = unknown_array;
                         success = false;
                         ex = uhe;
                     }
                 }
             }
 
-            // Cache the address.
-            cacheAddress(host, obj, success);
+            // Cache the addresses.
+            cacheAddresses(host, addresses, success);
             // Delete the host from the lookupTable, and
             // notify all threads waiting for the monitor
             // for lookupTable.
@@ -1274,13 +1266,13 @@
                 throw ex;
         }
 
-        return obj;
+        return addresses;
     }
 
 
-    private static Object checkLookupTable(String host) {
-        // make sure obj  is null.
-        Object obj = null;
+    private static InetAddress[] checkLookupTable(String host) {
+        // make sure addresses is null.
+        InetAddress[] addresses = null;
 
         synchronized (lookupTable) {
             // If the host isn't in the lookupTable, add it in the
@@ -1288,11 +1280,11 @@
             // the lookup.
             if (lookupTable.containsKey(host) == false) {
                 lookupTable.put(host, null);
-                return obj;
+                return addresses;
             }
 
             // If the host is in the lookupTable, it means that another
-            // thread is trying to look up the address of this host.
+            // thread is trying to look up the addresses of this host.
             // This thread should wait.
             while (lookupTable.containsKey(host)) {
                 try {
@@ -1302,18 +1294,18 @@
             }
         }
 
-        // The other thread has finished looking up the address of
-        // the host. This thread should retry to get the address
-        // from the addressCache. If it doesn't get the address from
-        // the cache,  it will try to look up the address itself.
-        obj = getCachedAddress(host);
-        if (obj == null) {
+        // The other thread has finished looking up the addresses of
+        // the host. This thread should retry to get the addresses
+        // from the addressCache. If it doesn't get the addresses from
+        // the cache, it will try to look up the addresses itself.
+        addresses = getCachedAddresses(host);
+        if (addresses == null) {
             synchronized (lookupTable) {
                 lookupTable.put(host, null);
             }
         }
 
-        return obj;
+        return addresses;
     }
 
     private static void updateLookupTable(String host) {
@@ -1396,15 +1388,20 @@
                         cachedLocalHost = null;
                 }
 
-                // we are calling getAddressFromNameService directly
+                // we are calling getAddressesFromNameService directly
                 // to avoid getting localHost from cache
                 if (ret == null) {
                     InetAddress[] localAddrs;
                     try {
                         localAddrs =
-                            (InetAddress[]) InetAddress.getAddressFromNameService(local);
+                            InetAddress.getAddressesFromNameService(local);
                     } catch (UnknownHostException uhe) {
-                        throw new UnknownHostException(local + ": " + uhe.getMessage());
+                        // Rethrow with a more informative error message.
+                        UnknownHostException uhe2 =
+                            new UnknownHostException(local + ": " +
+                                                     uhe.getMessage());
+                        uhe2.initCause(uhe);
+                        throw uhe2;
                     }
                     cachedLocalHost = localAddrs[0];
                     cacheTime = now;
@@ -1434,8 +1431,8 @@
     /*
      * Load and instantiate an underlying impl class
      */
-    static Object loadImpl(String implName) {
-        Object impl;
+    static InetAddressImpl loadImpl(String implName) {
+        Object impl = null;
 
         /*
          * Property "impl.prefix" will be prepended to the classname
@@ -1446,7 +1443,6 @@
          */
         String prefix = AccessController.doPrivileged(
                       new GetPropertyAction("impl.prefix", ""));
-        impl = null;
         try {
             impl = Class.forName("java.net." + prefix + implName).newInstance();
         } catch (ClassNotFoundException e) {
@@ -1471,7 +1467,7 @@
             }
         }
 
-        return impl;
+        return (InetAddressImpl) impl;
     }
 
     private void readObjectNoData (ObjectInputStream s) throws
@@ -1498,13 +1494,8 @@
 class InetAddressImplFactory {
 
     static InetAddressImpl create() {
-        Object o;
-        if (isIPv6Supported()) {
-            o = InetAddress.loadImpl("Inet6AddressImpl");
-        } else {
-            o = InetAddress.loadImpl("Inet4AddressImpl");
-        }
-        return (InetAddressImpl)o;
+        return InetAddress.loadImpl(isIPv6Supported() ?
+                                    "Inet6AddressImpl" : "Inet4AddressImpl");
     }
 
     static native boolean isIPv6Supported();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/nio/file/FileSystemLoopException.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Checked exception thrown when a file system loop, or cycle, is encountered.
+ *
+ * @since 1.7
+ * @see Files#walkFileTree
+ */
+
+public class FileSystemLoopException
+    extends FileSystemException
+{
+    private static final long serialVersionUID = 4843039591949217617L;
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   file
+     *          a string identifying the file causing the cycle or {@code null} if
+     *          not known
+     */
+    public FileSystemLoopException(String file) {
+        super(file);
+    }
+}
--- a/jdk/src/share/classes/java/nio/file/FileTreeWalker.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/java/nio/file/FileTreeWalker.java	Wed Jul 05 17:24:21 2017 +0200
@@ -38,7 +38,6 @@
 
 class FileTreeWalker {
     private final boolean followLinks;
-    private final boolean detectCycles;
     private final LinkOption[] linkOptions;
     private final FileVisitor<? super Path> visitor;
     private final int maxDepth;
@@ -48,17 +47,15 @@
                    int maxDepth)
     {
         boolean fl = false;
-        boolean dc = false;
         for (FileVisitOption option: options) {
+            // will throw NPE if options contains null
             switch (option) {
-                case FOLLOW_LINKS  : fl = true; break;
-                case DETECT_CYCLES : dc = true; break;
+                case FOLLOW_LINKS : fl = true; break;
                 default:
                     throw new AssertionError("Should not get here");
             }
         }
         this.followLinks = fl;
-        this.detectCycles = fl | dc;
         this.linkOptions = (fl) ? new LinkOption[0] :
             new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
         this.visitor = visitor;
@@ -68,13 +65,11 @@
     /**
      * Walk file tree starting at the given file
      */
-    void walk(Path start) {
+    void walk(Path start) throws IOException {
         FileVisitResult result = walk(start,
                                       0,
                                       new ArrayList<AncestorDirectory>());
-        if (result == null) {
-            throw new NullPointerException("Visitor returned 'null'");
-        }
+        Objects.nonNull(result, "FileVisitor returned null");
     }
 
     /**
@@ -88,11 +83,8 @@
     private FileVisitResult walk(Path file,
                                  int depth,
                                  List<AncestorDirectory> ancestors)
+        throws IOException
     {
-        // depth check
-        if (depth > maxDepth)
-            return FileVisitResult.CONTINUE;
-
         // if attributes are cached then use them if possible
         BasicFileAttributes attrs = null;
         if ((depth > 0) &&
@@ -137,13 +129,13 @@
             return visitor.visitFileFailed(file, exc);
         }
 
-        // file is not a directory so invoke visitFile method
-        if (!attrs.isDirectory()) {
+        // at maximum depth or file is not a directory
+        if (depth >= maxDepth || !attrs.isDirectory()) {
             return visitor.visitFile(file, attrs);
         }
 
-        // check for cycles
-        if (detectCycles) {
+        // check for cycles when following links
+        if (followLinks) {
             Object key = attrs.fileKey();
 
             // if this directory and ancestor has a file key then we compare
@@ -153,19 +145,23 @@
                 if (key != null && ancestorKey != null) {
                     if (key.equals(ancestorKey)) {
                         // cycle detected
-                        return visitor.visitFile(file, attrs);
+                        return visitor.visitFileFailed(file,
+                            new FileSystemLoopException(file.toString()));
                     }
                 } else {
+                    boolean isSameFile = false;
                     try {
-                        if (file.isSameFile(ancestor.file())) {
-                            // cycle detected
-                            return visitor.visitFile(file, attrs);
-                        }
+                        isSameFile = file.isSameFile(ancestor.file());
                     } catch (IOException x) {
                         // ignore
                     } catch (SecurityException x) {
                         // ignore
                     }
+                    if (isSameFile) {
+                        // cycle detected
+                        return visitor.visitFileFailed(file,
+                            new FileSystemLoopException(file.toString()));
+                    }
                 }
             }
 
@@ -181,7 +177,7 @@
             try {
                 stream = file.newDirectoryStream();
             } catch (IOException x) {
-                return visitor.preVisitDirectoryFailed(file, x);
+                return visitor.visitFileFailed(file, x);
             } catch (SecurityException x) {
                 // ignore, as per spec
                 return FileVisitResult.CONTINUE;
@@ -192,20 +188,14 @@
 
             // invoke preVisitDirectory and then visit each entry
             try {
-                result = visitor.preVisitDirectory(file);
+                result = visitor.preVisitDirectory(file, attrs);
                 if (result != FileVisitResult.CONTINUE) {
                     return result;
                 }
 
-                // if an I/O occurs during iteration then a CME is thrown. We
-                // need to distinguish this from a CME thrown by the visitor.
-                boolean inAction = false;
-
                 try {
                     for (Path entry: stream) {
-                        inAction = true;
                         result = walk(entry, depth+1, ancestors);
-                        inAction = false;
 
                         // returning null will cause NPE to be thrown
                         if (result == null || result == FileVisitResult.TERMINATE)
@@ -215,17 +205,9 @@
                         if (result == FileVisitResult.SKIP_SIBLINGS)
                             break;
                     }
-                } catch (ConcurrentModificationException x) {
-                    // if CME thrown because the iteration failed then remember
-                    // the IOException so that it is notified to postVisitDirectory
-                    if (!inAction) {
-                        // iteration failed
-                        Throwable t = x.getCause();
-                        if (t instanceof IOException)
-                            ioe = (IOException)t;
-                    }
-                    if (ioe == null)
-                        throw x;
+                } catch (DirectoryIteratorException e) {
+                    // IOException will be notified to postVisitDirectory
+                    ioe = e.getCause();
                 }
             } finally {
                 try {
@@ -238,7 +220,7 @@
 
         } finally {
             // remove key from trail if doing cycle detection
-            if (detectCycles) {
+            if (followLinks) {
                 ancestors.remove(ancestors.size()-1);
             }
         }
--- a/jdk/src/share/classes/java/nio/file/FileVisitOption.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/java/nio/file/FileVisitOption.java	Wed Jul 05 17:24:21 2017 +0200
@@ -37,9 +37,5 @@
     /**
      * Follow symbolic links.
      */
-    FOLLOW_LINKS,
-    /**
-     * Detect cycles in the file tree.
-     */
-    DETECT_CYCLES;
+    FOLLOW_LINKS;
 }
--- a/jdk/src/share/classes/java/nio/file/FileVisitor.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/java/nio/file/FileVisitor.java	Wed Jul 05 17:24:21 2017 +0200
@@ -40,33 +40,28 @@
  *     Path start = ...
  *     Files.walkFileTree(start, new SimpleFileVisitor&lt;Path&gt;() {
  *         &#64;Override
- *         public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
- *             try {
- *                 file.delete();
- *             } catch (IOException exc) {
- *                 // failed to delete, do error handling here
- *             }
+ *         public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+ *             throws IOException
+ *         {
+ *             file.delete();
  *             return FileVisitResult.CONTINUE;
  *         }
  *         &#64;Override
- *         public FileVisitResult postVisitDirectory(Path dir, IOException e) {
- *             if (e == null) {
- *                 try {
- *                     dir.delete();
- *                 } catch (IOException exc) {
- *                     // failed to delete, do error handling here
- *                 }
- *             } else {
+ *         public FileVisitResult postVisitDirectory(Path dir, IOException e)
+ *             throws IOException
+ *         {
+ *             if (e != null) {
  *                 // directory iteration failed
+ *                 throw e;
  *             }
+ *             dir.delete();
  *             return FileVisitResult.CONTINUE;
  *         }
  *     });
  * </pre>
- * <p> Furthermore, suppose we want to copy a file tree rooted at a source
- * directory to a target location. In that case, symbolic links should be
- * followed and the target directory should be created before the entries in
- * the directory are copied.
+ * <p> Furthermore, suppose we want to copy a file tree to a target location.
+ * In that case, symbolic links should be followed and the target directory
+ * should be created before the entries in the directory are copied.
  * <pre>
  *     final Path source = ...
  *     final Path target = ...
@@ -74,25 +69,21 @@
  *     Files.walkFileTree(source, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
  *         new SimpleFileVisitor&lt;Path&gt;() {
  *             &#64;Override
- *             public FileVisitResult preVisitDirectory(Path dir) {
+ *             public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
+ *                 throws IOException
+ *             {
  *                 try {
  *                     dir.copyTo(target.resolve(source.relativize(dir)));
  *                 } catch (FileAlreadyExistsException e) {
  *                      // ignore
- *                 } catch (IOException e) {
- *                     // copy failed, do error handling here
- *                     // skip rest of directory and descendants
- *                     return SKIP_SUBTREE;
  *                 }
  *                 return CONTINUE;
  *             }
  *             &#64;Override
- *             public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
- *                 try {
- *                     file.copyTo(target.resolve(source.relativize(file)));
- *                 } catch (IOException e) {
- *                     // copy failed, do error handling here
- *                 }
+ *             public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+ *                 throws IOException
+ *             {
+ *                 file.copyTo(target.resolve(source.relativize(file)));
  *                 return CONTINUE;
  *             }
  *         });
@@ -114,22 +105,16 @@
      *
      * @param   dir
      *          a reference to the directory
+     * @param   attrs
+     *          the directory's basic attributes
      *
      * @return  the visit result
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
      */
-    FileVisitResult preVisitDirectory(T dir);
-
-    /**
-     * Invoked for a directory that could not be opened.
-     *
-     * @param   dir
-     *          a reference to the directory
-     * @param   exc
-     *          the I/O exception thrown from the attempt to open the directory
-     *
-     * @return  the visit result
-     */
-    FileVisitResult preVisitDirectoryFailed(T dir, IOException exc);
+    FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
+        throws IOException;
 
     /**
      * Invoked for a file in a directory.
@@ -140,21 +125,30 @@
      *          the file's basic attributes
      *
      * @return  the visit result
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
      */
-    FileVisitResult visitFile(T file, BasicFileAttributes attrs);
+    FileVisitResult visitFile(T file, BasicFileAttributes attrs)
+        throws IOException;
 
     /**
-     * Invoked for a file when its basic file attributes could not be read.
+     * Invoked for a file that could not be visited. This method is invoked
+     * if the file's attributes could not be read, the file is a directory
+     * that could not be opened, and other reasons.
      *
      * @param   file
      *          a reference to the file
      * @param   exc
-     *          the I/O exception thrown from the attempt to read the file
-     *          attributes
+     *          the I/O exception that prevented the file from being visited
      *
      * @return  the visit result
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
      */
-    FileVisitResult visitFileFailed(T file, IOException exc);
+    FileVisitResult visitFileFailed(T file, IOException exc)
+        throws IOException;
 
     /**
      * Invoked for a directory after entries in the directory, and all of their
@@ -171,6 +165,10 @@
      *          of the directory to complete prematurely
      *
      * @return  the visit result
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
      */
-    FileVisitResult postVisitDirectory(T dir, IOException exc);
+    FileVisitResult postVisitDirectory(T dir, IOException exc)
+        throws IOException;
 }
--- a/jdk/src/share/classes/java/nio/file/Files.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/java/nio/file/Files.java	Wed Jul 05 17:24:21 2017 +0200
@@ -135,9 +135,9 @@
      * FileVisitor} invoked for each file encountered. File tree traversal
      * completes when all accessible files in the tree have been visited, or a
      * visit method returns a result of {@link FileVisitResult#TERMINATE
-     * TERMINATE}. Where a visit method terminates due an uncaught error or
-     * runtime exception then the traversal is terminated and the error or
-     * exception is propagated to the caller of this method.
+     * TERMINATE}. Where a visit method terminates due an {@code IOException},
+     * an uncaught error, or runtime exception, then the traversal is terminated
+     * and the error or exception is propagated to the caller of this method.
      *
      * <p> For each file encountered this method attempts to gets its {@link
      * java.nio.file.attribute.BasicFileAttributes}. If the file is not a
@@ -146,12 +146,10 @@
      * due to an I/O exception, then the {@link FileVisitor#visitFileFailed
      * visitFileFailed} method is invoked with the I/O exception.
      *
-     * <p> Where the file is a directory, this method attempts to open it by
-     * invoking its {@link Path#newDirectoryStream newDirectoryStream} method.
-     * Where the directory could not be opened, due to an {@code IOException},
-     * then the {@link FileVisitor#preVisitDirectoryFailed preVisitDirectoryFailed}
-     * method is invoked with the I/O exception, after which, the file tree walk
-     * continues, by default, at the next <em>sibling</em> of the directory.
+     * <p> Where the file is a directory, and the directory could not be opened,
+     * then the {@code visitFileFailed} method is invoked with the I/O exception,
+     * after which, the file tree walk continues, by default, at the next
+     * <em>sibling</em> of the directory.
      *
      * <p> Where the directory is opened successfully, then the entries in the
      * directory, and their <em>descendants</em> are visited. When all entries
@@ -171,26 +169,25 @@
      * method is invoked as specified above).
      *
      * <p> If the {@code options} parameter contains the {@link
-     * FileVisitOption#DETECT_CYCLES DETECT_CYCLES} or {@link
-     * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} options then this method keeps
+     * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then this method keeps
      * track of directories visited so that cycles can be detected. A cycle
      * arises when there is an entry in a directory that is an ancestor of the
      * directory. Cycle detection is done by recording the {@link
      * java.nio.file.attribute.BasicFileAttributes#fileKey file-key} of directories,
      * or if file keys are not available, by invoking the {@link Path#isSameFile
      * isSameFile} method to test if a directory is the same file as an
-     * ancestor. When a cycle is detected the {@link FileVisitor#visitFile
-     * visitFile} is invoked with the attributes of the directory. The {@link
-     * java.nio.file.attribute.BasicFileAttributes#isDirectory isDirectory}
-     * method may be used to test if the file is a directory and that a cycle is
-     * detected. The {@code preVisitDirectory} and {@code postVisitDirectory}
-     * methods are not invoked.
+     * ancestor. When a cycle is detected it is treated as an I/O error, and the
+     * {@link FileVisitor#visitFileFailed visitFileFailed} method is invoked with
+     * an instance of {@link FileSystemLoopException}.
      *
      * <p> The {@code maxDepth} parameter is the maximum number of levels of
      * directories to visit. A value of {@code 0} means that only the starting
      * file is visited, unless denied by the security manager. A value of
      * {@link Integer#MAX_VALUE MAX_VALUE} may be used to indicate that all
-     * levels should be visited.
+     * levels should be visited. The {@code visitFile} method is invoked for all
+     * files, including directories, encountered at {@code maxDepth}, unless the
+     * basic file attributes cannot be read, in which case the {@code
+     * visitFileFailed} method is invoked.
      *
      * <p> If a visitor returns a result of {@code null} then {@code
      * NullPointerException} is thrown.
@@ -215,11 +212,14 @@
      *          In the case of the default provider, the {@link
      *          SecurityManager#checkRead(String) checkRead} method is invoked
      *          to check read access to the directory.
+     * @throws  IOException
+     *          If an I/O error is thrown by a visitor method
      */
     public static void walkFileTree(Path start,
                                     Set<FileVisitOption> options,
                                     int maxDepth,
                                     FileVisitor<? super Path> visitor)
+        throws IOException
     {
         if (maxDepth < 0)
             throw new IllegalArgumentException("'maxDepth' is negative");
@@ -245,8 +245,12 @@
      *          In the case of the default provider, the {@link
      *          SecurityManager#checkRead(String) checkRead} method is invoked
      *          to check read access to the directory.
+     * @throws  IOException
+     *          If an I/O error is thrown by a visitor method
      */
-    public static void walkFileTree(Path start, FileVisitor<? super Path> visitor) {
+    public static void walkFileTree(Path start, FileVisitor<? super Path> visitor)
+        throws IOException
+    {
         walkFileTree(start,
                      EnumSet.noneOf(FileVisitOption.class),
                      Integer.MAX_VALUE,
--- a/jdk/src/share/classes/java/nio/file/SimpleFileVisitor.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/java/nio/file/SimpleFileVisitor.java	Wed Jul 05 17:24:21 2017 +0200
@@ -27,7 +27,7 @@
 
 import java.nio.file.attribute.BasicFileAttributes;
 import java.io.IOException;
-import java.io.IOError;
+import java.util.Objects;
 
 /**
  * A simple visitor of files with default behavior to visit all files and to
@@ -48,70 +48,47 @@
     }
 
     /**
-     * Throws NullPointerException if obj is null.
-     */
-    private static void checkNotNull(Object obj) {
-        if (obj == null)
-            throw new NullPointerException();
-    }
-
-    /**
      * Invoked for a directory before entries in the directory are visited.
      *
      * <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE
      * CONTINUE}.
      */
     @Override
-    public FileVisitResult preVisitDirectory(T dir) {
-        checkNotNull(dir);
+    public FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
+        throws IOException
+    {
+        Objects.nonNull(dir);
+        Objects.nonNull(attrs);
         return FileVisitResult.CONTINUE;
     }
 
     /**
-     * Invoked for a directory that could not be opened.
-     *
-     * <p> Unless overridden, this method throws {@link IOError} with the I/O
-     * exception as cause.
-     *
-     * @throws  IOError
-     *          with the I/O exception thrown when the attempt to open the
-     *          directory failed
-     */
-    @Override
-    public FileVisitResult preVisitDirectoryFailed(T dir, IOException exc) {
-        checkNotNull(dir);
-        checkNotNull(exc);
-        throw new IOError(exc);
-    }
-
-    /**
      * Invoked for a file in a directory.
      *
      * <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE
      * CONTINUE}.
      */
     @Override
-    public FileVisitResult visitFile(T file, BasicFileAttributes attrs) {
-        checkNotNull(file);
-        checkNotNull(attrs);
+    public FileVisitResult visitFile(T file, BasicFileAttributes attrs)
+        throws IOException
+    {
+        Objects.nonNull(file);
+        Objects.nonNull(attrs);
         return FileVisitResult.CONTINUE;
     }
 
     /**
-     * Invoked for a file when its basic file attributes could not be read.
+     * Invoked for a file that could not be visited.
      *
-     * <p> Unless overridden, this method throws {@link IOError} with the I/O
-     * exception as cause.
-     *
-     * @throws  IOError
-     *          with the I/O exception thrown when the attempt to read the file
-     *          attributes failed
+     * <p> Unless overridden, this method re-throws the I/O exception that prevented
+     * the file from being visited.
      */
     @Override
-    public FileVisitResult visitFileFailed(T file, IOException exc) {
-        checkNotNull(file);
-        checkNotNull(exc);
-        throw new IOError(exc);
+    public FileVisitResult visitFileFailed(T file, IOException exc)
+        throws IOException
+    {
+        Objects.nonNull(file);
+        throw exc;
     }
 
     /**
@@ -120,18 +97,16 @@
      *
      * <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE
      * CONTINUE} if the directory iteration completes without an I/O exception;
-     * otherwise this method throws {@link IOError} with the I/O exception as
-     * cause.
-     *
-     * @throws  IOError
-     *          with the I/O exception thrown when iteration of the directory
-     *          completed prematurely due to an I/O error
+     * otherwise this method re-throws the I/O exception that caused the iteration
+     * of the directory to terminate prematurely.
      */
     @Override
-    public FileVisitResult postVisitDirectory(T dir, IOException exc) {
-        checkNotNull(dir);
+    public FileVisitResult postVisitDirectory(T dir, IOException exc)
+        throws IOException
+    {
+        Objects.nonNull(dir);
         if (exc != null)
-            throw new IOError(exc);
+            throw exc;
         return FileVisitResult.CONTINUE;
     }
 }
--- a/jdk/src/share/classes/java/sql/DatabaseMetaData.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/java/sql/DatabaseMetaData.java	Wed Jul 05 17:24:21 2017 +0200
@@ -3643,7 +3643,7 @@
 
     /**
      * Retrieves whether a generated key will always be returned if the column
-     * name(s) or indexe(s) specified for the auto generated key column(s)
+     * name(s) or index(es) specified for the auto generated key column(s)
      * are valid and the statement succeeds.  The key that is returned may or
      * may not be based on the column(s) for the auto generated key.
      * Consult your JDBC driver documentation for additional details.
--- a/jdk/src/share/classes/java/sql/Statement.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/java/sql/Statement.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1051,9 +1051,9 @@
 
     /**
      * Returns a value indicating whether this {@code Statement} will be
-     * closed when all dependent objects such as resultsets are closed.
+     * closed when all its dependent result sets are closed.
      * @return {@code true} if the {@code Statement} will be closed when all
-     * of its dependent objects are closed; {@code false} otherwise
+     * of its dependent result sets are closed; {@code false} otherwise
      * @throws SQLException if this method is called on a closed
      * {@code Statement}
      * @since 1.7
--- a/jdk/src/share/classes/java/util/Locale.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/java/util/Locale.java	Wed Jul 05 17:24:21 2017 +0200
@@ -569,6 +569,9 @@
      * @exception NullPointerException thrown if any argument is null.
      */
     public Locale(String language, String country, String variant) {
+        if (language== null || country == null || variant == null) {
+            throw new NullPointerException();
+        }
         _baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), "", country, variant);
         _extensions = getCompatibilityExtensions(language, "", country, variant);
     }
--- a/jdk/src/share/classes/java/util/ResourceBundle.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/java/util/ResourceBundle.java	Wed Jul 05 17:24:21 2017 +0200
@@ -293,16 +293,6 @@
         = new ConcurrentHashMap<CacheKey, BundleReference>(INITIAL_CACHE_SIZE);
 
     /**
-     * This ConcurrentMap is used to keep multiple threads from loading the
-     * same bundle concurrently.  The table entries are <CacheKey, Thread>
-     * where CacheKey is the key for the bundle that is under construction
-     * and Thread is the thread that is constructing the bundle.
-     * This list is manipulated in findBundleInCache and putBundleInCache.
-     */
-    private static final ConcurrentMap<CacheKey, Thread> underConstruction
-        = new ConcurrentHashMap<CacheKey, Thread>();
-
-    /**
      * Queue for reference objects referring to class loaders or bundles.
      */
     private static final ReferenceQueue referenceQueue = new ReferenceQueue();
@@ -1381,7 +1371,7 @@
         boolean expiredBundle = false;
 
         // First, look up the cache to see if it's in the cache, without
-        // declaring beginLoading.
+        // attempting to load bundle.
         cacheKey.setLocale(targetLocale);
         ResourceBundle bundle = findBundleInCache(cacheKey, control);
         if (isValidBundle(bundle)) {
@@ -1408,56 +1398,25 @@
             CacheKey constKey = (CacheKey) cacheKey.clone();
 
             try {
-                // Try declaring loading. If beginLoading() returns true,
-                // then we can proceed. Otherwise, we need to take a look
-                // at the cache again to see if someone else has loaded
-                // the bundle and put it in the cache while we've been
-                // waiting for other loading work to complete.
-                while (!beginLoading(constKey)) {
-                    bundle = findBundleInCache(cacheKey, control);
-                    if (bundle == null) {
-                        continue;
+                bundle = loadBundle(cacheKey, formats, control, expiredBundle);
+                if (bundle != null) {
+                    if (bundle.parent == null) {
+                        bundle.setParent(parent);
                     }
-                    if (bundle == NONEXISTENT_BUNDLE) {
-                        // If the bundle is NONEXISTENT_BUNDLE, the bundle doesn't exist.
-                        return parent;
-                    }
-                    expiredBundle = bundle.expired;
-                    if (!expiredBundle) {
-                        if (bundle.parent == parent) {
-                            return bundle;
-                        }
-                        BundleReference bundleRef = cacheList.get(cacheKey);
-                        if (bundleRef != null && bundleRef.get() == bundle) {
-                            cacheList.remove(cacheKey, bundleRef);
-                        }
-                    }
+                    bundle.locale = targetLocale;
+                    bundle = putBundleInCache(cacheKey, bundle, control);
+                    return bundle;
                 }
 
-                try {
-                    bundle = loadBundle(cacheKey, formats, control, expiredBundle);
-                    if (bundle != null) {
-                        if (bundle.parent == null) {
-                            bundle.setParent(parent);
-                        }
-                        bundle.locale = targetLocale;
-                        bundle = putBundleInCache(cacheKey, bundle, control);
-                        return bundle;
-                    }
-
-                    // Put NONEXISTENT_BUNDLE in the cache as a mark that there's no bundle
-                    // instance for the locale.
-                    putBundleInCache(cacheKey, NONEXISTENT_BUNDLE, control);
-                } finally {
-                    endLoading(constKey);
-                }
+                // Put NONEXISTENT_BUNDLE in the cache as a mark that there's no bundle
+                // instance for the locale.
+                putBundleInCache(cacheKey, NONEXISTENT_BUNDLE, control);
             } finally {
                 if (constKey.getCause() instanceof InterruptedException) {
                     Thread.currentThread().interrupt();
                 }
             }
         }
-        assert underConstruction.get(cacheKey) != Thread.currentThread();
         return parent;
     }
 
@@ -1465,7 +1424,6 @@
                                                    List<String> formats,
                                                    Control control,
                                                    boolean reload) {
-        assert underConstruction.get(cacheKey) == Thread.currentThread();
 
         // Here we actually load the bundle in the order of formats
         // specified by the getFormats() value.
@@ -1498,7 +1456,6 @@
                 break;
             }
         }
-        assert underConstruction.get(cacheKey) == Thread.currentThread();
 
         return bundle;
     }
@@ -1530,57 +1487,6 @@
     }
 
     /**
-     * Declares the beginning of actual resource bundle loading. This method
-     * returns true if the declaration is successful and the current thread has
-     * been put in underConstruction. If someone else has already begun
-     * loading, this method waits until that loading work is complete and
-     * returns false.
-     */
-    private static final boolean beginLoading(CacheKey constKey) {
-        Thread me = Thread.currentThread();
-        Thread worker;
-        // We need to declare by putting the current Thread (me) to
-        // underConstruction that we are working on loading the specified
-        // resource bundle. If we are already working the loading, it means
-        // that the resource loading requires a recursive call. In that case,
-        // we have to proceed. (4300693)
-        if (((worker = underConstruction.putIfAbsent(constKey, me)) == null)
-            || worker == me) {
-            return true;
-        }
-
-        // If someone else is working on the loading, wait until
-        // the Thread finishes the bundle loading.
-        synchronized (worker) {
-            while (underConstruction.get(constKey) == worker) {
-                try {
-                    worker.wait();
-                } catch (InterruptedException e) {
-                    // record the interruption
-                    constKey.setCause(e);
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Declares the end of the bundle loading. This method calls notifyAll
-     * for those who are waiting for this completion.
-     */
-    private static final void endLoading(CacheKey constKey) {
-        // Remove this Thread from the underConstruction map and wake up
-        // those who have been waiting for me to complete this bundle
-        // loading.
-        Thread me = Thread.currentThread();
-        assert (underConstruction.get(constKey) == me);
-        underConstruction.remove(constKey);
-        synchronized (me) {
-            me.notifyAll();
-        }
-    }
-
-    /**
      * Throw a MissingResourceException with proper message
      */
     private static final void throwMissingResourceException(String baseName,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,1445 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea and Martin Buchholz with assistance from members of
+ * JCP JSR-166 Expert Group and released to the public domain, as explained
+ * at http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+
+import java.util.AbstractCollection;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.Deque;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+
+/**
+ * An unbounded concurrent {@linkplain Deque deque} based on linked nodes.
+ * Concurrent insertion, removal, and access operations execute safely
+ * across multiple threads.
+ * A {@code ConcurrentLinkedDeque} is an appropriate choice when
+ * many threads will share access to a common collection.
+ * Like most other concurrent collection implementations, this class
+ * does not permit the use of {@code null} elements.
+ *
+ * <p>Iterators are <i>weakly consistent</i>, returning elements
+ * reflecting the state of the deque at some point at or since the
+ * creation of the iterator.  They do <em>not</em> throw {@link
+ * java.util.ConcurrentModificationException
+ * ConcurrentModificationException}, and may proceed concurrently with
+ * other operations.
+ *
+ * <p>Beware that, unlike in most collections, the {@code size}
+ * method is <em>NOT</em> a constant-time operation. Because of the
+ * asynchronous nature of these deques, determining the current number
+ * of elements requires a traversal of the elements.
+ *
+ * <p>This class and its iterator implement all of the <em>optional</em>
+ * methods of the {@link Deque} and {@link Iterator} interfaces.
+ *
+ * <p>Memory consistency effects: As with other concurrent collections,
+ * actions in a thread prior to placing an object into a
+ * {@code ConcurrentLinkedDeque}
+ * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
+ * actions subsequent to the access or removal of that element from
+ * the {@code ConcurrentLinkedDeque} in another thread.
+ *
+ * <p>This class is a member of the
+ * <a href="{@docRoot}/../technotes/guides/collections/index.html">
+ * Java Collections Framework</a>.
+ *
+ * @since 1.7
+ * @author Doug Lea
+ * @author Martin Buchholz
+ * @param <E> the type of elements held in this collection
+ */
+
+public class ConcurrentLinkedDeque<E>
+    extends AbstractCollection<E>
+    implements Deque<E>, java.io.Serializable {
+
+    /*
+     * This is an implementation of a concurrent lock-free deque
+     * supporting interior removes but not interior insertions, as
+     * required to support the entire Deque interface.
+     *
+     * We extend the techniques developed for ConcurrentLinkedQueue and
+     * LinkedTransferQueue (see the internal docs for those classes).
+     * Understanding the ConcurrentLinkedQueue implementation is a
+     * prerequisite for understanding the implementation of this class.
+     *
+     * The data structure is a symmetrical doubly-linked "GC-robust"
+     * linked list of nodes.  We minimize the number of volatile writes
+     * using two techniques: advancing multiple hops with a single CAS
+     * and mixing volatile and non-volatile writes of the same memory
+     * locations.
+     *
+     * A node contains the expected E ("item") and links to predecessor
+     * ("prev") and successor ("next") nodes:
+     *
+     * class Node<E> { volatile Node<E> prev, next; volatile E item; }
+     *
+     * A node p is considered "live" if it contains a non-null item
+     * (p.item != null).  When an item is CASed to null, the item is
+     * atomically logically deleted from the collection.
+     *
+     * At any time, there is precisely one "first" node with a null
+     * prev reference that terminates any chain of prev references
+     * starting at a live node.  Similarly there is precisely one
+     * "last" node terminating any chain of next references starting at
+     * a live node.  The "first" and "last" nodes may or may not be live.
+     * The "first" and "last" nodes are always mutually reachable.
+     *
+     * A new element is added atomically by CASing the null prev or
+     * next reference in the first or last node to a fresh node
+     * containing the element.  The element's node atomically becomes
+     * "live" at that point.
+     *
+     * A node is considered "active" if it is a live node, or the
+     * first or last node.  Active nodes cannot be unlinked.
+     *
+     * A "self-link" is a next or prev reference that is the same node:
+     *   p.prev == p  or  p.next == p
+     * Self-links are used in the node unlinking process.  Active nodes
+     * never have self-links.
+     *
+     * A node p is active if and only if:
+     *
+     * p.item != null ||
+     * (p.prev == null && p.next != p) ||
+     * (p.next == null && p.prev != p)
+     *
+     * The deque object has two node references, "head" and "tail".
+     * The head and tail are only approximations to the first and last
+     * nodes of the deque.  The first node can always be found by
+     * following prev pointers from head; likewise for tail.  However,
+     * it is permissible for head and tail to be referring to deleted
+     * nodes that have been unlinked and so may not be reachable from
+     * any live node.
+     *
+     * There are 3 stages of node deletion;
+     * "logical deletion", "unlinking", and "gc-unlinking".
+     *
+     * 1. "logical deletion" by CASing item to null atomically removes
+     * the element from the collection, and makes the containing node
+     * eligible for unlinking.
+     *
+     * 2. "unlinking" makes a deleted node unreachable from active
+     * nodes, and thus eventually reclaimable by GC.  Unlinked nodes
+     * may remain reachable indefinitely from an iterator.
+     *
+     * Physical node unlinking is merely an optimization (albeit a
+     * critical one), and so can be performed at our convenience.  At
+     * any time, the set of live nodes maintained by prev and next
+     * links are identical, that is, the live nodes found via next
+     * links from the first node is equal to the elements found via
+     * prev links from the last node.  However, this is not true for
+     * nodes that have already been logically deleted - such nodes may
+     * be reachable in one direction only.
+     *
+     * 3. "gc-unlinking" takes unlinking further by making active
+     * nodes unreachable from deleted nodes, making it easier for the
+     * GC to reclaim future deleted nodes.  This step makes the data
+     * structure "gc-robust", as first described in detail by Boehm
+     * (http://portal.acm.org/citation.cfm?doid=503272.503282).
+     *
+     * GC-unlinked nodes may remain reachable indefinitely from an
+     * iterator, but unlike unlinked nodes, are never reachable from
+     * head or tail.
+     *
+     * Making the data structure GC-robust will eliminate the risk of
+     * unbounded memory retention with conservative GCs and is likely
+     * to improve performance with generational GCs.
+     *
+     * When a node is dequeued at either end, e.g. via poll(), we would
+     * like to break any references from the node to active nodes.  We
+     * develop further the use of self-links that was very effective in
+     * other concurrent collection classes.  The idea is to replace
+     * prev and next pointers with special values that are interpreted
+     * to mean off-the-list-at-one-end.  These are approximations, but
+     * good enough to preserve the properties we want in our
+     * traversals, e.g. we guarantee that a traversal will never visit
+     * the same element twice, but we don't guarantee whether a
+     * traversal that runs out of elements will be able to see more
+     * elements later after enqueues at that end.  Doing gc-unlinking
+     * safely is particularly tricky, since any node can be in use
+     * indefinitely (for example by an iterator).  We must ensure that
+     * the nodes pointed at by head/tail never get gc-unlinked, since
+     * head/tail are needed to get "back on track" by other nodes that
+     * are gc-unlinked.  gc-unlinking accounts for much of the
+     * implementation complexity.
+     *
+     * Since neither unlinking nor gc-unlinking are necessary for
+     * correctness, there are many implementation choices regarding
+     * frequency (eagerness) of these operations.  Since volatile
+     * reads are likely to be much cheaper than CASes, saving CASes by
+     * unlinking multiple adjacent nodes at a time may be a win.
+     * gc-unlinking can be performed rarely and still be effective,
+     * since it is most important that long chains of deleted nodes
+     * are occasionally broken.
+     *
+     * The actual representation we use is that p.next == p means to
+     * goto the first node (which in turn is reached by following prev
+     * pointers from head), and p.next == null && p.prev == p means
+     * that the iteration is at an end and that p is a (final static)
+     * dummy node, NEXT_TERMINATOR, and not the last active node.
+     * Finishing the iteration when encountering such a TERMINATOR is
+     * good enough for read-only traversals, so such traversals can use
+     * p.next == null as the termination condition.  When we need to
+     * find the last (active) node, for enqueueing a new node, we need
+     * to check whether we have reached a TERMINATOR node; if so,
+     * restart traversal from tail.
+     *
+     * The implementation is completely directionally symmetrical,
+     * except that most public methods that iterate through the list
+     * follow next pointers ("forward" direction).
+     *
+     * We believe (without full proof) that all single-element deque
+     * operations (e.g., addFirst, peekLast, pollLast) are linearizable
+     * (see Herlihy and Shavit's book).  However, some combinations of
+     * operations are known not to be linearizable.  In particular,
+     * when an addFirst(A) is racing with pollFirst() removing B, it is
+     * possible for an observer iterating over the elements to observe
+     * A B C and subsequently observe A C, even though no interior
+     * removes are ever performed.  Nevertheless, iterators behave
+     * reasonably, providing the "weakly consistent" guarantees.
+     *
+     * Empirically, microbenchmarks suggest that this class adds about
+     * 40% overhead relative to ConcurrentLinkedQueue, which feels as
+     * good as we can hope for.
+     */
+
+    private static final long serialVersionUID = 876323262645176354L;
+
+    /**
+     * A node from which the first node on list (that is, the unique node p
+     * with p.prev == null && p.next != p) can be reached in O(1) time.
+     * Invariants:
+     * - the first node is always O(1) reachable from head via prev links
+     * - all live nodes are reachable from the first node via succ()
+     * - head != null
+     * - (tmp = head).next != tmp || tmp != head
+     * - head is never gc-unlinked (but may be unlinked)
+     * Non-invariants:
+     * - head.item may or may not be null
+     * - head may not be reachable from the first or last node, or from tail
+     */
+    private transient volatile Node<E> head;
+
+    /**
+     * A node from which the last node on list (that is, the unique node p
+     * with p.next == null && p.prev != p) can be reached in O(1) time.
+     * Invariants:
+     * - the last node is always O(1) reachable from tail via next links
+     * - all live nodes are reachable from the last node via pred()
+     * - tail != null
+     * - tail is never gc-unlinked (but may be unlinked)
+     * Non-invariants:
+     * - tail.item may or may not be null
+     * - tail may not be reachable from the first or last node, or from head
+     */
+    private transient volatile Node<E> tail;
+
+    private final static Node<Object> PREV_TERMINATOR, NEXT_TERMINATOR;
+
+    static {
+        PREV_TERMINATOR = new Node<Object>(null);
+        PREV_TERMINATOR.next = PREV_TERMINATOR;
+        NEXT_TERMINATOR = new Node<Object>(null);
+        NEXT_TERMINATOR.prev = NEXT_TERMINATOR;
+    }
+
+    @SuppressWarnings("unchecked")
+    Node<E> prevTerminator() {
+        return (Node<E>) PREV_TERMINATOR;
+    }
+
+    @SuppressWarnings("unchecked")
+    Node<E> nextTerminator() {
+        return (Node<E>) NEXT_TERMINATOR;
+    }
+
+    static final class Node<E> {
+        volatile Node<E> prev;
+        volatile E item;
+        volatile Node<E> next;
+
+        /**
+         * Constructs a new node.  Uses relaxed write because item can
+         * only be seen after publication via casNext or casPrev.
+         */
+        Node(E item) {
+            UNSAFE.putObject(this, itemOffset, item);
+        }
+
+        boolean casItem(E cmp, E val) {
+            return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
+        }
+
+        void lazySetNext(Node<E> val) {
+            UNSAFE.putOrderedObject(this, nextOffset, val);
+        }
+
+        boolean casNext(Node<E> cmp, Node<E> val) {
+            return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
+        }
+
+        void lazySetPrev(Node<E> val) {
+            UNSAFE.putOrderedObject(this, prevOffset, val);
+        }
+
+        boolean casPrev(Node<E> cmp, Node<E> val) {
+            return UNSAFE.compareAndSwapObject(this, prevOffset, cmp, val);
+        }
+
+        // Unsafe mechanics
+
+        private static final sun.misc.Unsafe UNSAFE =
+            sun.misc.Unsafe.getUnsafe();
+        private static final long prevOffset =
+            objectFieldOffset(UNSAFE, "prev", Node.class);
+        private static final long itemOffset =
+            objectFieldOffset(UNSAFE, "item", Node.class);
+        private static final long nextOffset =
+            objectFieldOffset(UNSAFE, "next", Node.class);
+    }
+
+    /**
+     * Links e as first element.
+     */
+    private void linkFirst(E e) {
+        checkNotNull(e);
+        final Node<E> newNode = new Node<E>(e);
+
+        restartFromHead:
+        for (;;)
+            for (Node<E> h = head, p = h, q;;) {
+                if ((q = p.prev) != null &&
+                    (q = (p = q).prev) != null)
+                    // Check for head updates every other hop.
+                    // If p == q, we are sure to follow head instead.
+                    p = (h != (h = head)) ? h : q;
+                else if (p.next == p) // PREV_TERMINATOR
+                    continue restartFromHead;
+                else {
+                    // p is first node
+                    newNode.lazySetNext(p); // CAS piggyback
+                    if (p.casPrev(null, newNode)) {
+                        // Successful CAS is the linearization point
+                        // for e to become an element of this deque,
+                        // and for newNode to become "live".
+                        if (p != h) // hop two nodes at a time
+                            casHead(h, newNode);  // Failure is OK.
+                        return;
+                    }
+                    // Lost CAS race to another thread; re-read prev
+                }
+            }
+    }
+
+    /**
+     * Links e as last element.
+     */
+    private void linkLast(E e) {
+        checkNotNull(e);
+        final Node<E> newNode = new Node<E>(e);
+
+        restartFromTail:
+        for (;;)
+            for (Node<E> t = tail, p = t, q;;) {
+                if ((q = p.next) != null &&
+                    (q = (p = q).next) != null)
+                    // Check for tail updates every other hop.
+                    // If p == q, we are sure to follow tail instead.
+                    p = (t != (t = tail)) ? t : q;
+                else if (p.prev == p) // NEXT_TERMINATOR
+                    continue restartFromTail;
+                else {
+                    // p is last node
+                    newNode.lazySetPrev(p); // CAS piggyback
+                    if (p.casNext(null, newNode)) {
+                        // Successful CAS is the linearization point
+                        // for e to become an element of this deque,
+                        // and for newNode to become "live".
+                        if (p != t) // hop two nodes at a time
+                            casTail(t, newNode);  // Failure is OK.
+                        return;
+                    }
+                    // Lost CAS race to another thread; re-read next
+                }
+            }
+    }
+
+    private final static int HOPS = 2;
+
+    /**
+     * Unlinks non-null node x.
+     */
+    void unlink(Node<E> x) {
+        // assert x != null;
+        // assert x.item == null;
+        // assert x != PREV_TERMINATOR;
+        // assert x != NEXT_TERMINATOR;
+
+        final Node<E> prev = x.prev;
+        final Node<E> next = x.next;
+        if (prev == null) {
+            unlinkFirst(x, next);
+        } else if (next == null) {
+            unlinkLast(x, prev);
+        } else {
+            // Unlink interior node.
+            //
+            // This is the common case, since a series of polls at the
+            // same end will be "interior" removes, except perhaps for
+            // the first one, since end nodes cannot be unlinked.
+            //
+            // At any time, all active nodes are mutually reachable by
+            // following a sequence of either next or prev pointers.
+            //
+            // Our strategy is to find the unique active predecessor
+            // and successor of x.  Try to fix up their links so that
+            // they point to each other, leaving x unreachable from
+            // active nodes.  If successful, and if x has no live
+            // predecessor/successor, we additionally try to gc-unlink,
+            // leaving active nodes unreachable from x, by rechecking
+            // that the status of predecessor and successor are
+            // unchanged and ensuring that x is not reachable from
+            // tail/head, before setting x's prev/next links to their
+            // logical approximate replacements, self/TERMINATOR.
+            Node<E> activePred, activeSucc;
+            boolean isFirst, isLast;
+            int hops = 1;
+
+            // Find active predecessor
+            for (Node<E> p = prev; ; ++hops) {
+                if (p.item != null) {
+                    activePred = p;
+                    isFirst = false;
+                    break;
+                }
+                Node<E> q = p.prev;
+                if (q == null) {
+                    if (p.next == p)
+                        return;
+                    activePred = p;
+                    isFirst = true;
+                    break;
+                }
+                else if (p == q)
+                    return;
+                else
+                    p = q;
+            }
+
+            // Find active successor
+            for (Node<E> p = next; ; ++hops) {
+                if (p.item != null) {
+                    activeSucc = p;
+                    isLast = false;
+                    break;
+                }
+                Node<E> q = p.next;
+                if (q == null) {
+                    if (p.prev == p)
+                        return;
+                    activeSucc = p;
+                    isLast = true;
+                    break;
+                }
+                else if (p == q)
+                    return;
+                else
+                    p = q;
+            }
+
+            // TODO: better HOP heuristics
+            if (hops < HOPS
+                // always squeeze out interior deleted nodes
+                && (isFirst | isLast))
+                return;
+
+            // Squeeze out deleted nodes between activePred and
+            // activeSucc, including x.
+            skipDeletedSuccessors(activePred);
+            skipDeletedPredecessors(activeSucc);
+
+            // Try to gc-unlink, if possible
+            if ((isFirst | isLast) &&
+
+                // Recheck expected state of predecessor and successor
+                (activePred.next == activeSucc) &&
+                (activeSucc.prev == activePred) &&
+                (isFirst ? activePred.prev == null : activePred.item != null) &&
+                (isLast  ? activeSucc.next == null : activeSucc.item != null)) {
+
+                updateHead(); // Ensure x is not reachable from head
+                updateTail(); // Ensure x is not reachable from tail
+
+                // Finally, actually gc-unlink
+                x.lazySetPrev(isFirst ? prevTerminator() : x);
+                x.lazySetNext(isLast  ? nextTerminator() : x);
+            }
+        }
+    }
+
+    /**
+     * Unlinks non-null first node.
+     */
+    private void unlinkFirst(Node<E> first, Node<E> next) {
+        // assert first != null;
+        // assert next != null;
+        // assert first.item == null;
+        for (Node<E> o = null, p = next, q;;) {
+            if (p.item != null || (q = p.next) == null) {
+                if (o != null && p.prev != p && first.casNext(next, p)) {
+                    skipDeletedPredecessors(p);
+                    if (first.prev == null &&
+                        (p.next == null || p.item != null) &&
+                        p.prev == first) {
+
+                        updateHead(); // Ensure o is not reachable from head
+                        updateTail(); // Ensure o is not reachable from tail
+
+                        // Finally, actually gc-unlink
+                        o.lazySetNext(o);
+                        o.lazySetPrev(prevTerminator());
+                    }
+                }
+                return;
+            }
+            else if (p == q)
+                return;
+            else {
+                o = p;
+                p = q;
+            }
+        }
+    }
+
+    /**
+     * Unlinks non-null last node.
+     */
+    private void unlinkLast(Node<E> last, Node<E> prev) {
+        // assert last != null;
+        // assert prev != null;
+        // assert last.item == null;
+        for (Node<E> o = null, p = prev, q;;) {
+            if (p.item != null || (q = p.prev) == null) {
+                if (o != null && p.next != p && last.casPrev(prev, p)) {
+                    skipDeletedSuccessors(p);
+                    if (last.next == null &&
+                        (p.prev == null || p.item != null) &&
+                        p.next == last) {
+
+                        updateHead(); // Ensure o is not reachable from head
+                        updateTail(); // Ensure o is not reachable from tail
+
+                        // Finally, actually gc-unlink
+                        o.lazySetPrev(o);
+                        o.lazySetNext(nextTerminator());
+                    }
+                }
+                return;
+            }
+            else if (p == q)
+                return;
+            else {
+                o = p;
+                p = q;
+            }
+        }
+    }
+
+    /**
+     * Guarantees that any node which was unlinked before a call to
+     * this method will be unreachable from head after it returns.
+     * Does not guarantee to eliminate slack, only that head will
+     * point to a node that was active while this method was running.
+     */
+    private final void updateHead() {
+        // Either head already points to an active node, or we keep
+        // trying to cas it to the first node until it does.
+        Node<E> h, p, q;
+        restartFromHead:
+        while ((h = head).item == null && (p = h.prev) != null) {
+            for (;;) {
+                if ((q = p.prev) == null ||
+                    (q = (p = q).prev) == null) {
+                    // It is possible that p is PREV_TERMINATOR,
+                    // but if so, the CAS is guaranteed to fail.
+                    if (casHead(h, p))
+                        return;
+                    else
+                        continue restartFromHead;
+                }
+                else if (h != head)
+                    continue restartFromHead;
+                else
+                    p = q;
+            }
+        }
+    }
+
+    /**
+     * Guarantees that any node which was unlinked before a call to
+     * this method will be unreachable from tail after it returns.
+     * Does not guarantee to eliminate slack, only that tail will
+     * point to a node that was active while this method was running.
+     */
+    private final void updateTail() {
+        // Either tail already points to an active node, or we keep
+        // trying to cas it to the last node until it does.
+        Node<E> t, p, q;
+        restartFromTail:
+        while ((t = tail).item == null && (p = t.next) != null) {
+            for (;;) {
+                if ((q = p.next) == null ||
+                    (q = (p = q).next) == null) {
+                    // It is possible that p is NEXT_TERMINATOR,
+                    // but if so, the CAS is guaranteed to fail.
+                    if (casTail(t, p))
+                        return;
+                    else
+                        continue restartFromTail;
+                }
+                else if (t != tail)
+                    continue restartFromTail;
+                else
+                    p = q;
+            }
+        }
+    }
+
+    private void skipDeletedPredecessors(Node<E> x) {
+        whileActive:
+        do {
+            Node<E> prev = x.prev;
+            // assert prev != null;
+            // assert x != NEXT_TERMINATOR;
+            // assert x != PREV_TERMINATOR;
+            Node<E> p = prev;
+            findActive:
+            for (;;) {
+                if (p.item != null)
+                    break findActive;
+                Node<E> q = p.prev;
+                if (q == null) {
+                    if (p.next == p)
+                        continue whileActive;
+                    break findActive;
+                }
+                else if (p == q)
+                    continue whileActive;
+                else
+                    p = q;
+            }
+
+            // found active CAS target
+            if (prev == p || x.casPrev(prev, p))
+                return;
+
+        } while (x.item != null || x.next == null);
+    }
+
+    private void skipDeletedSuccessors(Node<E> x) {
+        whileActive:
+        do {
+            Node<E> next = x.next;
+            // assert next != null;
+            // assert x != NEXT_TERMINATOR;
+            // assert x != PREV_TERMINATOR;
+            Node<E> p = next;
+            findActive:
+            for (;;) {
+                if (p.item != null)
+                    break findActive;
+                Node<E> q = p.next;
+                if (q == null) {
+                    if (p.prev == p)
+                        continue whileActive;
+                    break findActive;
+                }
+                else if (p == q)
+                    continue whileActive;
+                else
+                    p = q;
+            }
+
+            // found active CAS target
+            if (next == p || x.casNext(next, p))
+                return;
+
+        } while (x.item != null || x.prev == null);
+    }
+
+    /**
+     * Returns the successor of p, or the first node if p.next has been
+     * linked to self, which will only be true if traversing with a
+     * stale pointer that is now off the list.
+     */
+    final Node<E> succ(Node<E> p) {
+        // TODO: should we skip deleted nodes here?
+        Node<E> q = p.next;
+        return (p == q) ? first() : q;
+    }
+
+    /**
+     * Returns the predecessor of p, or the last node if p.prev has been
+     * linked to self, which will only be true if traversing with a
+     * stale pointer that is now off the list.
+     */
+    final Node<E> pred(Node<E> p) {
+        Node<E> q = p.prev;
+        return (p == q) ? last() : q;
+    }
+
+    /**
+     * Returns the first node, the unique node p for which:
+     *     p.prev == null && p.next != p
+     * The returned node may or may not be logically deleted.
+     * Guarantees that head is set to the returned node.
+     */
+    Node<E> first() {
+        restartFromHead:
+        for (;;)
+            for (Node<E> h = head, p = h, q;;) {
+                if ((q = p.prev) != null &&
+                    (q = (p = q).prev) != null)
+                    // Check for head updates every other hop.
+                    // If p == q, we are sure to follow head instead.
+                    p = (h != (h = head)) ? h : q;
+                else if (p == h
+                         // It is possible that p is PREV_TERMINATOR,
+                         // but if so, the CAS is guaranteed to fail.
+                         || casHead(h, p))
+                    return p;
+                else
+                    continue restartFromHead;
+            }
+    }
+
+    /**
+     * Returns the last node, the unique node p for which:
+     *     p.next == null && p.prev != p
+     * The returned node may or may not be logically deleted.
+     * Guarantees that tail is set to the returned node.
+     */
+    Node<E> last() {
+        restartFromTail:
+        for (;;)
+            for (Node<E> t = tail, p = t, q;;) {
+                if ((q = p.next) != null &&
+                    (q = (p = q).next) != null)
+                    // Check for tail updates every other hop.
+                    // If p == q, we are sure to follow tail instead.
+                    p = (t != (t = tail)) ? t : q;
+                else if (p == t
+                         // It is possible that p is NEXT_TERMINATOR,
+                         // but if so, the CAS is guaranteed to fail.
+                         || casTail(t, p))
+                    return p;
+                else
+                    continue restartFromTail;
+            }
+    }
+
+    // Minor convenience utilities
+
+    /**
+     * Throws NullPointerException if argument is null.
+     *
+     * @param v the element
+     */
+    private static void checkNotNull(Object v) {
+        if (v == null)
+            throw new NullPointerException();
+    }
+
+    /**
+     * Returns element unless it is null, in which case throws
+     * NoSuchElementException.
+     *
+     * @param v the element
+     * @return the element
+     */
+    private E screenNullResult(E v) {
+        if (v == null)
+            throw new NoSuchElementException();
+        return v;
+    }
+
+    /**
+     * Creates an array list and fills it with elements of this list.
+     * Used by toArray.
+     *
+     * @return the arrayList
+     */
+    private ArrayList<E> toArrayList() {
+        ArrayList<E> list = new ArrayList<E>();
+        for (Node<E> p = first(); p != null; p = succ(p)) {
+            E item = p.item;
+            if (item != null)
+                list.add(item);
+        }
+        return list;
+    }
+
+    /**
+     * Constructs an empty deque.
+     */
+    public ConcurrentLinkedDeque() {
+        head = tail = new Node<E>(null);
+    }
+
+    /**
+     * Constructs a deque initially containing the elements of
+     * the given collection, added in traversal order of the
+     * collection's iterator.
+     *
+     * @param c the collection of elements to initially contain
+     * @throws NullPointerException if the specified collection or any
+     *         of its elements are null
+     */
+    public ConcurrentLinkedDeque(Collection<? extends E> c) {
+        // Copy c into a private chain of Nodes
+        Node<E> h = null, t = null;
+        for (E e : c) {
+            checkNotNull(e);
+            Node<E> newNode = new Node<E>(e);
+            if (h == null)
+                h = t = newNode;
+            else {
+                t.lazySetNext(newNode);
+                newNode.lazySetPrev(t);
+                t = newNode;
+            }
+        }
+        initHeadTail(h, t);
+    }
+
+    /**
+     * Initializes head and tail, ensuring invariants hold.
+     */
+    private void initHeadTail(Node<E> h, Node<E> t) {
+        if (h == t) {
+            if (h == null)
+                h = t = new Node<E>(null);
+            else {
+                // Avoid edge case of a single Node with non-null item.
+                Node<E> newNode = new Node<E>(null);
+                t.lazySetNext(newNode);
+                newNode.lazySetPrev(t);
+                t = newNode;
+            }
+        }
+        head = h;
+        tail = t;
+    }
+
+    /**
+     * Inserts the specified element at the front of this deque.
+     *
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public void addFirst(E e) {
+        linkFirst(e);
+    }
+
+    /**
+     * Inserts the specified element at the end of this deque.
+     *
+     * <p>This method is equivalent to {@link #add}.
+     *
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public void addLast(E e) {
+        linkLast(e);
+    }
+
+    /**
+     * Inserts the specified element at the front of this deque.
+     *
+     * @return {@code true} always
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean offerFirst(E e) {
+        linkFirst(e);
+        return true;
+    }
+
+    /**
+     * Inserts the specified element at the end of this deque.
+     *
+     * <p>This method is equivalent to {@link #add}.
+     *
+     * @return {@code true} always
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean offerLast(E e) {
+        linkLast(e);
+        return true;
+    }
+
+    public E peekFirst() {
+        for (Node<E> p = first(); p != null; p = succ(p)) {
+            E item = p.item;
+            if (item != null)
+                return item;
+        }
+        return null;
+    }
+
+    public E peekLast() {
+        for (Node<E> p = last(); p != null; p = pred(p)) {
+            E item = p.item;
+            if (item != null)
+                return item;
+        }
+        return null;
+    }
+
+    /**
+     * @throws NoSuchElementException {@inheritDoc}
+     */
+    public E getFirst() {
+        return screenNullResult(peekFirst());
+    }
+
+    /**
+     * @throws NoSuchElementException {@inheritDoc}
+     */
+    public E getLast()  {
+        return screenNullResult(peekLast());
+    }
+
+    public E pollFirst() {
+        for (Node<E> p = first(); p != null; p = succ(p)) {
+            E item = p.item;
+            if (item != null && p.casItem(item, null)) {
+                unlink(p);
+                return item;
+            }
+        }
+        return null;
+    }
+
+    public E pollLast() {
+        for (Node<E> p = last(); p != null; p = pred(p)) {
+            E item = p.item;
+            if (item != null && p.casItem(item, null)) {
+                unlink(p);
+                return item;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @throws NoSuchElementException {@inheritDoc}
+     */
+    public E removeFirst() {
+        return screenNullResult(pollFirst());
+    }
+
+    /**
+     * @throws NoSuchElementException {@inheritDoc}
+     */
+    public E removeLast() {
+        return screenNullResult(pollLast());
+    }
+
+    // *** Queue and stack methods ***
+
+    /**
+     * Inserts the specified element at the tail of this deque.
+     *
+     * @return {@code true} (as specified by {@link Queue#offer})
+     * @throws NullPointerException if the specified element is null
+     */
+    public boolean offer(E e) {
+        return offerLast(e);
+    }
+
+    /**
+     * Inserts the specified element at the tail of this deque.
+     *
+     * @return {@code true} (as specified by {@link Collection#add})
+     * @throws NullPointerException if the specified element is null
+     */
+    public boolean add(E e) {
+        return offerLast(e);
+    }
+
+    public E poll()           { return pollFirst(); }
+    public E remove()         { return removeFirst(); }
+    public E peek()           { return peekFirst(); }
+    public E element()        { return getFirst(); }
+    public void push(E e)     { addFirst(e); }
+    public E pop()            { return removeFirst(); }
+
+    /**
+     * Removes the first element {@code e} such that
+     * {@code o.equals(e)}, if such an element exists in this deque.
+     * If the deque does not contain the element, it is unchanged.
+     *
+     * @param o element to be removed from this deque, if present
+     * @return {@code true} if the deque contained the specified element
+     * @throws NullPointerException if the specified element is {@code null}
+     */
+    public boolean removeFirstOccurrence(Object o) {
+        checkNotNull(o);
+        for (Node<E> p = first(); p != null; p = succ(p)) {
+            E item = p.item;
+            if (item != null && o.equals(item) && p.casItem(item, null)) {
+                unlink(p);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Removes the last element {@code e} such that
+     * {@code o.equals(e)}, if such an element exists in this deque.
+     * If the deque does not contain the element, it is unchanged.
+     *
+     * @param o element to be removed from this deque, if present
+     * @return {@code true} if the deque contained the specified element
+     * @throws NullPointerException if the specified element is {@code null}
+     */
+    public boolean removeLastOccurrence(Object o) {
+        checkNotNull(o);
+        for (Node<E> p = last(); p != null; p = pred(p)) {
+            E item = p.item;
+            if (item != null && o.equals(item) && p.casItem(item, null)) {
+                unlink(p);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns {@code true} if this deque contains at least one
+     * element {@code e} such that {@code o.equals(e)}.
+     *
+     * @param o element whose presence in this deque is to be tested
+     * @return {@code true} if this deque contains the specified element
+     */
+    public boolean contains(Object o) {
+        if (o == null) return false;
+        for (Node<E> p = first(); p != null; p = succ(p)) {
+            E item = p.item;
+            if (item != null && o.equals(item))
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * Returns {@code true} if this collection contains no elements.
+     *
+     * @return {@code true} if this collection contains no elements
+     */
+    public boolean isEmpty() {
+        return peekFirst() == null;
+    }
+
+    /**
+     * Returns the number of elements in this deque.  If this deque
+     * contains more than {@code Integer.MAX_VALUE} elements, it
+     * returns {@code Integer.MAX_VALUE}.
+     *
+     * <p>Beware that, unlike in most collections, this method is
+     * <em>NOT</em> a constant-time operation. Because of the
+     * asynchronous nature of these deques, determining the current
+     * number of elements requires traversing them all to count them.
+     * Additionally, it is possible for the size to change during
+     * execution of this method, in which case the returned result
+     * will be inaccurate. Thus, this method is typically not very
+     * useful in concurrent applications.
+     *
+     * @return the number of elements in this deque
+     */
+    public int size() {
+        int count = 0;
+        for (Node<E> p = first(); p != null; p = succ(p))
+            if (p.item != null)
+                // Collection.size() spec says to max out
+                if (++count == Integer.MAX_VALUE)
+                    break;
+        return count;
+    }
+
+    /**
+     * Removes the first element {@code e} such that
+     * {@code o.equals(e)}, if such an element exists in this deque.
+     * If the deque does not contain the element, it is unchanged.
+     *
+     * @param o element to be removed from this deque, if present
+     * @return {@code true} if the deque contained the specified element
+     * @throws NullPointerException if the specified element is {@code null}
+     */
+    public boolean remove(Object o) {
+        return removeFirstOccurrence(o);
+    }
+
+    /**
+     * Appends all of the elements in the specified collection to the end of
+     * this deque, in the order that they are returned by the specified
+     * collection's iterator.  Attempts to {@code addAll} of a deque to
+     * itself result in {@code IllegalArgumentException}.
+     *
+     * @param c the elements to be inserted into this deque
+     * @return {@code true} if this deque changed as a result of the call
+     * @throws NullPointerException if the specified collection or any
+     *         of its elements are null
+     * @throws IllegalArgumentException if the collection is this deque
+     */
+    public boolean addAll(Collection<? extends E> c) {
+        if (c == this)
+            // As historically specified in AbstractQueue#addAll
+            throw new IllegalArgumentException();
+
+        // Copy c into a private chain of Nodes
+        Node<E> beginningOfTheEnd = null, last = null;
+        for (E e : c) {
+            checkNotNull(e);
+            Node<E> newNode = new Node<E>(e);
+            if (beginningOfTheEnd == null)
+                beginningOfTheEnd = last = newNode;
+            else {
+                last.lazySetNext(newNode);
+                newNode.lazySetPrev(last);
+                last = newNode;
+            }
+        }
+        if (beginningOfTheEnd == null)
+            return false;
+
+        // Atomically append the chain at the tail of this collection
+        restartFromTail:
+        for (;;)
+            for (Node<E> t = tail, p = t, q;;) {
+                if ((q = p.next) != null &&
+                    (q = (p = q).next) != null)
+                    // Check for tail updates every other hop.
+                    // If p == q, we are sure to follow tail instead.
+                    p = (t != (t = tail)) ? t : q;
+                else if (p.prev == p) // NEXT_TERMINATOR
+                    continue restartFromTail;
+                else {
+                    // p is last node
+                    beginningOfTheEnd.lazySetPrev(p); // CAS piggyback
+                    if (p.casNext(null, beginningOfTheEnd)) {
+                        // Successful CAS is the linearization point
+                        // for all elements to be added to this queue.
+                        if (!casTail(t, last)) {
+                            // Try a little harder to update tail,
+                            // since we may be adding many elements.
+                            t = tail;
+                            if (last.next == null)
+                                casTail(t, last);
+                        }
+                        return true;
+                    }
+                    // Lost CAS race to another thread; re-read next
+                }
+            }
+    }
+
+    /**
+     * Removes all of the elements from this deque.
+     */
+    public void clear() {
+        while (pollFirst() != null)
+            ;
+    }
+
+    /**
+     * Returns an array containing all of the elements in this deque, in
+     * proper sequence (from first to last element).
+     *
+     * <p>The returned array will be "safe" in that no references to it are
+     * maintained by this deque.  (In other words, this method must allocate
+     * a new array).  The caller is thus free to modify the returned array.
+     *
+     * <p>This method acts as bridge between array-based and collection-based
+     * APIs.
+     *
+     * @return an array containing all of the elements in this deque
+     */
+    public Object[] toArray() {
+        return toArrayList().toArray();
+    }
+
+    /**
+     * Returns an array containing all of the elements in this deque,
+     * in proper sequence (from first to last element); the runtime
+     * type of the returned array is that of the specified array.  If
+     * the deque fits in the specified array, it is returned therein.
+     * Otherwise, a new array is allocated with the runtime type of
+     * the specified array and the size of this deque.
+     *
+     * <p>If this deque fits in the specified array with room to spare
+     * (i.e., the array has more elements than this deque), the element in
+     * the array immediately following the end of the deque is set to
+     * {@code null}.
+     *
+     * <p>Like the {@link #toArray()} method, this method acts as
+     * bridge between array-based and collection-based APIs.  Further,
+     * this method allows precise control over the runtime type of the
+     * output array, and may, under certain circumstances, be used to
+     * save allocation costs.
+     *
+     * <p>Suppose {@code x} is a deque known to contain only strings.
+     * The following code can be used to dump the deque into a newly
+     * allocated array of {@code String}:
+     *
+     * <pre>
+     *     String[] y = x.toArray(new String[0]);</pre>
+     *
+     * Note that {@code toArray(new Object[0])} is identical in function to
+     * {@code toArray()}.
+     *
+     * @param a the array into which the elements of the deque are to
+     *          be stored, if it is big enough; otherwise, a new array of the
+     *          same runtime type is allocated for this purpose
+     * @return an array containing all of the elements in this deque
+     * @throws ArrayStoreException if the runtime type of the specified array
+     *         is not a supertype of the runtime type of every element in
+     *         this deque
+     * @throws NullPointerException if the specified array is null
+     */
+    public <T> T[] toArray(T[] a) {
+        return toArrayList().toArray(a);
+    }
+
+    /**
+     * Returns an iterator over the elements in this deque in proper sequence.
+     * The elements will be returned in order from first (head) to last (tail).
+     *
+     * <p>The returned {@code Iterator} is a "weakly consistent" iterator that
+     * will never throw {@link java.util.ConcurrentModificationException
+     * ConcurrentModificationException},
+     * and guarantees to traverse elements as they existed upon
+     * construction of the iterator, and may (but is not guaranteed to)
+     * reflect any modifications subsequent to construction.
+     *
+     * @return an iterator over the elements in this deque in proper sequence
+     */
+    public Iterator<E> iterator() {
+        return new Itr();
+    }
+
+    /**
+     * Returns an iterator over the elements in this deque in reverse
+     * sequential order.  The elements will be returned in order from
+     * last (tail) to first (head).
+     *
+     * <p>The returned {@code Iterator} is a "weakly consistent" iterator that
+     * will never throw {@link java.util.ConcurrentModificationException
+     * ConcurrentModificationException},
+     * and guarantees to traverse elements as they existed upon
+     * construction of the iterator, and may (but is not guaranteed to)
+     * reflect any modifications subsequent to construction.
+     *
+     * @return an iterator over the elements in this deque in reverse order
+     */
+    public Iterator<E> descendingIterator() {
+        return new DescendingItr();
+    }
+
+    private abstract class AbstractItr implements Iterator<E> {
+        /**
+         * Next node to return item for.
+         */
+        private Node<E> nextNode;
+
+        /**
+         * nextItem holds on to item fields because once we claim
+         * that an element exists in hasNext(), we must return it in
+         * the following next() call even if it was in the process of
+         * being removed when hasNext() was called.
+         */
+        private E nextItem;
+
+        /**
+         * Node returned by most recent call to next. Needed by remove.
+         * Reset to null if this element is deleted by a call to remove.
+         */
+        private Node<E> lastRet;
+
+        abstract Node<E> startNode();
+        abstract Node<E> nextNode(Node<E> p);
+
+        AbstractItr() {
+            advance();
+        }
+
+        /**
+         * Sets nextNode and nextItem to next valid node, or to null
+         * if no such.
+         */
+        private void advance() {
+            lastRet = nextNode;
+
+            Node<E> p = (nextNode == null) ? startNode() : nextNode(nextNode);
+            for (;; p = nextNode(p)) {
+                if (p == null) {
+                    // p might be active end or TERMINATOR node; both are OK
+                    nextNode = null;
+                    nextItem = null;
+                    break;
+                }
+                E item = p.item;
+                if (item != null) {
+                    nextNode = p;
+                    nextItem = item;
+                    break;
+                }
+            }
+        }
+
+        public boolean hasNext() {
+            return nextItem != null;
+        }
+
+        public E next() {
+            E item = nextItem;
+            if (item == null) throw new NoSuchElementException();
+            advance();
+            return item;
+        }
+
+        public void remove() {
+            Node<E> l = lastRet;
+            if (l == null) throw new IllegalStateException();
+            l.item = null;
+            unlink(l);
+            lastRet = null;
+        }
+    }
+
+    /** Forward iterator */
+    private class Itr extends AbstractItr {
+        Node<E> startNode() { return first(); }
+        Node<E> nextNode(Node<E> p) { return succ(p); }
+    }
+
+    /** Descending iterator */
+    private class DescendingItr extends AbstractItr {
+        Node<E> startNode() { return last(); }
+        Node<E> nextNode(Node<E> p) { return pred(p); }
+    }
+
+    /**
+     * Saves the state to a stream (that is, serializes it).
+     *
+     * @serialData All of the elements (each an {@code E}) in
+     * the proper order, followed by a null
+     * @param s the stream
+     */
+    private void writeObject(java.io.ObjectOutputStream s)
+        throws java.io.IOException {
+
+        // Write out any hidden stuff
+        s.defaultWriteObject();
+
+        // Write out all elements in the proper order.
+        for (Node<E> p = first(); p != null; p = succ(p)) {
+            E item = p.item;
+            if (item != null)
+                s.writeObject(item);
+        }
+
+        // Use trailing null as sentinel
+        s.writeObject(null);
+    }
+
+    /**
+     * Reconstitutes the instance from a stream (that is, deserializes it).
+     * @param s the stream
+     */
+    private void readObject(java.io.ObjectInputStream s)
+        throws java.io.IOException, ClassNotFoundException {
+        s.defaultReadObject();
+
+        // Read in elements until trailing null sentinel found
+        Node<E> h = null, t = null;
+        Object item;
+        while ((item = s.readObject()) != null) {
+            @SuppressWarnings("unchecked")
+            Node<E> newNode = new Node<E>((E) item);
+            if (h == null)
+                h = t = newNode;
+            else {
+                t.lazySetNext(newNode);
+                newNode.lazySetPrev(t);
+                t = newNode;
+            }
+        }
+        initHeadTail(h, t);
+    }
+
+    // Unsafe mechanics
+
+    private static final sun.misc.Unsafe UNSAFE =
+        sun.misc.Unsafe.getUnsafe();
+    private static final long headOffset =
+        objectFieldOffset(UNSAFE, "head", ConcurrentLinkedDeque.class);
+    private static final long tailOffset =
+        objectFieldOffset(UNSAFE, "tail", ConcurrentLinkedDeque.class);
+
+    private boolean casHead(Node<E> cmp, Node<E> val) {
+        return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
+    }
+
+    private boolean casTail(Node<E> cmp, Node<E> val) {
+        return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val);
+    }
+
+    static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
+                                  String field, Class<?> klazz) {
+        try {
+            return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
+        } catch (NoSuchFieldException e) {
+            // Convert Exception to corresponding Error
+            NoSuchFieldError error = new NoSuchFieldError(field);
+            error.initCause(e);
+            throw error;
+        }
+    }
+}
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java	Wed Jul 05 17:24:21 2017 +0200
@@ -28,9 +28,9 @@
  * However, the following notice accompanied the original version of this
  * file:
  *
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * Written by Doug Lea and Martin Buchholz with assistance from members of
+ * JCP JSR-166 Expert Group and released to the public domain, as explained
+ * at http://creativecommons.org/licenses/publicdomain
  */
 
 package java.util.concurrent;
@@ -53,7 +53,8 @@
  * operations obtain elements at the head of the queue.
  * A {@code ConcurrentLinkedQueue} is an appropriate choice when
  * many threads will share access to a common collection.
- * This queue does not permit {@code null} elements.
+ * Like most other concurrent collection implementations, this class
+ * does not permit the use of {@code null} elements.
  *
  * <p>This implementation employs an efficient &quot;wait-free&quot;
  * algorithm based on one described in <a
@@ -61,14 +62,20 @@
  * Fast, and Practical Non-Blocking and Blocking Concurrent Queue
  * Algorithms</a> by Maged M. Michael and Michael L. Scott.
  *
+ * <p>Iterators are <i>weakly consistent</i>, returning elements
+ * reflecting the state of the queue at some point at or since the
+ * creation of the iterator.  They do <em>not</em> throw {@link
+ * ConcurrentModificationException}, and may proceed concurrently with
+ * other operations.  Elements contained in the queue since the creation
+ * of the iterator will be returned exactly once.
+ *
  * <p>Beware that, unlike in most collections, the {@code size} method
  * is <em>NOT</em> a constant-time operation. Because of the
  * asynchronous nature of these queues, determining the current number
  * of elements requires a traversal of the elements.
  *
- * <p>This class and its iterator implement all of the
- * <em>optional</em> methods of the {@link Collection} and {@link
- * Iterator} interfaces.
+ * <p>This class and its iterator implement all of the <em>optional</em>
+ * methods of the {@link Queue} and {@link Iterator} interfaces.
  *
  * <p>Memory consistency effects: As with other concurrent
  * collections, actions in a thread prior to placing an object into a
@@ -132,9 +139,10 @@
      *
      * Both head and tail are permitted to lag.  In fact, failing to
      * update them every time one could is a significant optimization
-     * (fewer CASes). This is controlled by local "hops" variables
-     * that only trigger helping-CASes after experiencing multiple
-     * lags.
+     * (fewer CASes). As with LinkedTransferQueue (see the internal
+     * documentation for that class), we use a slack threshold of two;
+     * that is, we update head/tail when the current pointer appears
+     * to be two or more steps away from the first/last node.
      *
      * Since head and tail are updated concurrently and independently,
      * it is possible for tail to lag behind head (why not)?
@@ -148,8 +156,8 @@
      * this is merely an optimization.
      *
      * When constructing a Node (before enqueuing it) we avoid paying
-     * for a volatile write to item by using lazySet instead of a
-     * normal write.  This allows the cost of enqueue to be
+     * for a volatile write to item by using Unsafe.putObject instead
+     * of a normal write.  This allows the cost of enqueue to be
      * "one-and-a-half" CASes.
      *
      * Both head and tail may or may not point to a Node with a
@@ -161,38 +169,25 @@
      */
 
     private static class Node<E> {
-        private volatile E item;
-        private volatile Node<E> next;
+        volatile E item;
+        volatile Node<E> next;
 
+        /**
+         * Constructs a new node.  Uses relaxed write because item can
+         * only be seen after publication via casNext.
+         */
         Node(E item) {
-            // Piggyback on imminent casNext()
-            lazySetItem(item);
-        }
-
-        E getItem() {
-            return item;
+            UNSAFE.putObject(this, itemOffset, item);
         }
 
         boolean casItem(E cmp, E val) {
             return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
         }
 
-        void setItem(E val) {
-            item = val;
-        }
-
-        void lazySetItem(E val) {
-            UNSAFE.putOrderedObject(this, itemOffset, val);
-        }
-
         void lazySetNext(Node<E> val) {
             UNSAFE.putOrderedObject(this, nextOffset, val);
         }
 
-        Node<E> getNext() {
-            return next;
-        }
-
         boolean casNext(Node<E> cmp, Node<E> val) {
             return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
         }
@@ -219,7 +214,7 @@
      * - it is permitted for tail to lag behind head, that is, for tail
      *   to not be reachable from head!
      */
-    private transient volatile Node<E> head = new Node<E>(null);
+    private transient volatile Node<E> head;
 
     /**
      * A node from which the last node on list (that is, the unique
@@ -233,25 +228,41 @@
      *   to not be reachable from head!
      * - tail.next may or may not be self-pointing to tail.
      */
-    private transient volatile Node<E> tail = head;
+    private transient volatile Node<E> tail;
 
 
     /**
      * Creates a {@code ConcurrentLinkedQueue} that is initially empty.
      */
-    public ConcurrentLinkedQueue() {}
+    public ConcurrentLinkedQueue() {
+        head = tail = new Node<E>(null);
+    }
 
     /**
      * Creates a {@code ConcurrentLinkedQueue}
      * initially containing the elements of the given collection,
      * added in traversal order of the collection's iterator.
+     *
      * @param c the collection of elements to initially contain
      * @throws NullPointerException if the specified collection or any
      *         of its elements are null
      */
     public ConcurrentLinkedQueue(Collection<? extends E> c) {
-        for (E e : c)
-            add(e);
+        Node<E> h = null, t = null;
+        for (E e : c) {
+            checkNotNull(e);
+            Node<E> newNode = new Node<E>(e);
+            if (h == null)
+                h = t = newNode;
+            else {
+                t.lazySetNext(newNode);
+                t = newNode;
+            }
+        }
+        if (h == null)
+            h = t = new Node<E>(null);
+        head = h;
+        tail = t;
     }
 
     // Have to override just to update the javadoc
@@ -267,13 +278,6 @@
     }
 
     /**
-     * We don't bother to update head or tail pointers if fewer than
-     * HOPS links from "true" location.  We assume that volatile
-     * writes are significantly more expensive than volatile reads.
-     */
-    private static final int HOPS = 1;
-
-    /**
      * Try to CAS head to p. If successful, repoint old head to itself
      * as sentinel for succ(), below.
      */
@@ -288,7 +292,7 @@
      * stale pointer that is now off the list.
      */
     final Node<E> succ(Node<E> p) {
-        Node<E> next = p.getNext();
+        Node<E> next = p.next;
         return (p == next) ? head : next;
     }
 
@@ -299,68 +303,75 @@
      * @throws NullPointerException if the specified element is null
      */
     public boolean offer(E e) {
-        if (e == null) throw new NullPointerException();
-        Node<E> n = new Node<E>(e);
-        retry:
-        for (;;) {
-            Node<E> t = tail;
-            Node<E> p = t;
-            for (int hops = 0; ; hops++) {
-                Node<E> next = succ(p);
-                if (next != null) {
-                    if (hops > HOPS && t != tail)
-                        continue retry;
-                    p = next;
-                } else if (p.casNext(null, n)) {
-                    if (hops >= HOPS)
-                        casTail(t, n);  // Failure is OK.
+        checkNotNull(e);
+        final Node<E> newNode = new Node<E>(e);
+
+        for (Node<E> t = tail, p = t;;) {
+            Node<E> q = p.next;
+            if (q == null) {
+                // p is last node
+                if (p.casNext(null, newNode)) {
+                    // Successful CAS is the linearization point
+                    // for e to become an element of this queue,
+                    // and for newNode to become "live".
+                    if (p != t) // hop two nodes at a time
+                        casTail(t, newNode);  // Failure is OK.
                     return true;
-                } else {
-                    p = succ(p);
                 }
+                // Lost CAS race to another thread; re-read next
             }
+            else if (p == q)
+                // We have fallen off list.  If tail is unchanged, it
+                // will also be off-list, in which case we need to
+                // jump to head, from which all live nodes are always
+                // reachable.  Else the new tail is a better bet.
+                p = (t != (t = tail)) ? t : head;
+            else
+                // Check for tail updates after two hops.
+                p = (p != t && t != (t = tail)) ? t : q;
         }
     }
 
     public E poll() {
-        Node<E> h = head;
-        Node<E> p = h;
-        for (int hops = 0; ; hops++) {
-            E item = p.getItem();
+        restartFromHead:
+        for (;;) {
+            for (Node<E> h = head, p = h, q;;) {
+                E item = p.item;
 
-            if (item != null && p.casItem(item, null)) {
-                if (hops >= HOPS) {
-                    Node<E> q = p.getNext();
-                    updateHead(h, (q != null) ? q : p);
+                if (item != null && p.casItem(item, null)) {
+                    // Successful CAS is the linearization point
+                    // for item to be removed from this queue.
+                    if (p != h) // hop two nodes at a time
+                        updateHead(h, ((q = p.next) != null) ? q : p);
+                    return item;
                 }
-                return item;
+                else if ((q = p.next) == null) {
+                    updateHead(h, p);
+                    return null;
+                }
+                else if (p == q)
+                    continue restartFromHead;
+                else
+                    p = q;
             }
-            Node<E> next = succ(p);
-            if (next == null) {
-                updateHead(h, p);
-                break;
-            }
-            p = next;
         }
-        return null;
     }
 
     public E peek() {
-        Node<E> h = head;
-        Node<E> p = h;
-        E item;
+        restartFromHead:
         for (;;) {
-            item = p.getItem();
-            if (item != null)
-                break;
-            Node<E> next = succ(p);
-            if (next == null) {
-                break;
+            for (Node<E> h = head, p = h, q;;) {
+                E item = p.item;
+                if (item != null || (q = p.next) == null) {
+                    updateHead(h, p);
+                    return item;
+                }
+                else if (p == q)
+                    continue restartFromHead;
+                else
+                    p = q;
             }
-            p = next;
         }
-        updateHead(h, p);
-        return item;
     }
 
     /**
@@ -372,24 +383,20 @@
      * of losing a race to a concurrent poll().
      */
     Node<E> first() {
-        Node<E> h = head;
-        Node<E> p = h;
-        Node<E> result;
+        restartFromHead:
         for (;;) {
-            E item = p.getItem();
-            if (item != null) {
-                result = p;
-                break;
+            for (Node<E> h = head, p = h, q;;) {
+                boolean hasItem = (p.item != null);
+                if (hasItem || (q = p.next) == null) {
+                    updateHead(h, p);
+                    return hasItem ? p : null;
+                }
+                else if (p == q)
+                    continue restartFromHead;
+                else
+                    p = q;
             }
-            Node<E> next = succ(p);
-            if (next == null) {
-                result = null;
-                break;
-            }
-            p = next;
         }
-        updateHead(h, p);
-        return result;
     }
 
     /**
@@ -410,18 +417,20 @@
      * <em>NOT</em> a constant-time operation. Because of the
      * asynchronous nature of these queues, determining the current
      * number of elements requires an O(n) traversal.
+     * Additionally, if elements are added or removed during execution
+     * of this method, the returned result may be inaccurate.  Thus,
+     * this method is typically not very useful in concurrent
+     * applications.
      *
      * @return the number of elements in this queue
      */
     public int size() {
         int count = 0;
-        for (Node<E> p = first(); p != null; p = succ(p)) {
-            if (p.getItem() != null) {
-                // Collections.size() spec says to max out
+        for (Node<E> p = first(); p != null; p = succ(p))
+            if (p.item != null)
+                // Collection.size() spec says to max out
                 if (++count == Integer.MAX_VALUE)
                     break;
-            }
-        }
         return count;
     }
 
@@ -436,9 +445,8 @@
     public boolean contains(Object o) {
         if (o == null) return false;
         for (Node<E> p = first(); p != null; p = succ(p)) {
-            E item = p.getItem();
-            if (item != null &&
-                o.equals(item))
+            E item = p.item;
+            if (item != null && o.equals(item))
                 return true;
         }
         return false;
@@ -459,7 +467,7 @@
         if (o == null) return false;
         Node<E> pred = null;
         for (Node<E> p = first(); p != null; p = succ(p)) {
-            E item = p.getItem();
+            E item = p.item;
             if (item != null &&
                 o.equals(item) &&
                 p.casItem(item, null)) {
@@ -474,6 +482,69 @@
     }
 
     /**
+     * Appends all of the elements in the specified collection to the end of
+     * this queue, in the order that they are returned by the specified
+     * collection's iterator.  Attempts to {@code addAll} of a queue to
+     * itself result in {@code IllegalArgumentException}.
+     *
+     * @param c the elements to be inserted into this queue
+     * @return {@code true} if this queue changed as a result of the call
+     * @throws NullPointerException if the specified collection or any
+     *         of its elements are null
+     * @throws IllegalArgumentException if the collection is this queue
+     */
+    public boolean addAll(Collection<? extends E> c) {
+        if (c == this)
+            // As historically specified in AbstractQueue#addAll
+            throw new IllegalArgumentException();
+
+        // Copy c into a private chain of Nodes
+        Node<E> beginningOfTheEnd = null, last = null;
+        for (E e : c) {
+            checkNotNull(e);
+            Node<E> newNode = new Node<E>(e);
+            if (beginningOfTheEnd == null)
+                beginningOfTheEnd = last = newNode;
+            else {
+                last.lazySetNext(newNode);
+                last = newNode;
+            }
+        }
+        if (beginningOfTheEnd == null)
+            return false;
+
+        // Atomically append the chain at the tail of this collection
+        for (Node<E> t = tail, p = t;;) {
+            Node<E> q = p.next;
+            if (q == null) {
+                // p is last node
+                if (p.casNext(null, beginningOfTheEnd)) {
+                    // Successful CAS is the linearization point
+                    // for all elements to be added to this queue.
+                    if (!casTail(t, last)) {
+                        // Try a little harder to update tail,
+                        // since we may be adding many elements.
+                        t = tail;
+                        if (last.next == null)
+                            casTail(t, last);
+                    }
+                    return true;
+                }
+                // Lost CAS race to another thread; re-read next
+            }
+            else if (p == q)
+                // We have fallen off list.  If tail is unchanged, it
+                // will also be off-list, in which case we need to
+                // jump to head, from which all live nodes are always
+                // reachable.  Else the new tail is a better bet.
+                p = (t != (t = tail)) ? t : head;
+            else
+                // Check for tail updates after two hops.
+                p = (p != t && t != (t = tail)) ? t : q;
+        }
+    }
+
+    /**
      * Returns an array containing all of the elements in this queue, in
      * proper sequence.
      *
@@ -490,7 +561,7 @@
         // Use ArrayList to deal with resizing.
         ArrayList<E> al = new ArrayList<E>();
         for (Node<E> p = first(); p != null; p = succ(p)) {
-            E item = p.getItem();
+            E item = p.item;
             if (item != null)
                 al.add(item);
         }
@@ -539,7 +610,7 @@
         int k = 0;
         Node<E> p;
         for (p = first(); p != null && k < a.length; p = succ(p)) {
-            E item = p.getItem();
+            E item = p.item;
             if (item != null)
                 a[k++] = (T)item;
         }
@@ -552,7 +623,7 @@
         // If won't fit, use ArrayList version
         ArrayList<E> al = new ArrayList<E>();
         for (Node<E> q = first(); q != null; q = succ(q)) {
-            E item = q.getItem();
+            E item = q.item;
             if (item != null)
                 al.add(item);
         }
@@ -561,7 +632,9 @@
 
     /**
      * Returns an iterator over the elements in this queue in proper sequence.
-     * The returned iterator is a "weakly consistent" iterator that
+     * The elements will be returned in order from first (head) to last (tail).
+     *
+     * <p>The returned {@code Iterator} is a "weakly consistent" iterator that
      * will never throw {@link java.util.ConcurrentModificationException
      * ConcurrentModificationException},
      * and guarantees to traverse elements as they existed upon
@@ -620,7 +693,7 @@
                     nextItem = null;
                     return x;
                 }
-                E item = p.getItem();
+                E item = p.item;
                 if (item != null) {
                     nextNode = p;
                     nextItem = item;
@@ -648,13 +721,13 @@
             Node<E> l = lastRet;
             if (l == null) throw new IllegalStateException();
             // rely on a future traversal to relink.
-            l.setItem(null);
+            l.item = null;
             lastRet = null;
         }
     }
 
     /**
-     * Save the state to a stream (that is, serialize it).
+     * Saves the state to a stream (that is, serializes it).
      *
      * @serialData All of the elements (each an {@code E}) in
      * the proper order, followed by a null
@@ -668,7 +741,7 @@
 
         // Write out all elements in the proper order.
         for (Node<E> p = first(); p != null; p = succ(p)) {
-            Object item = p.getItem();
+            Object item = p.item;
             if (item != null)
                 s.writeObject(item);
         }
@@ -678,25 +751,40 @@
     }
 
     /**
-     * Reconstitute the Queue instance from a stream (that is,
-     * deserialize it).
+     * Reconstitutes the instance from a stream (that is, deserializes it).
      * @param s the stream
      */
     private void readObject(java.io.ObjectInputStream s)
         throws java.io.IOException, ClassNotFoundException {
-        // Read in capacity, and any hidden stuff
         s.defaultReadObject();
-        head = new Node<E>(null);
-        tail = head;
-        // Read in all elements and place in queue
-        for (;;) {
+
+        // Read in elements until trailing null sentinel found
+        Node<E> h = null, t = null;
+        Object item;
+        while ((item = s.readObject()) != null) {
             @SuppressWarnings("unchecked")
-            E item = (E)s.readObject();
-            if (item == null)
-                break;
-            else
-                offer(item);
+            Node<E> newNode = new Node<E>((E) item);
+            if (h == null)
+                h = t = newNode;
+            else {
+                t.lazySetNext(newNode);
+                t = newNode;
+            }
         }
+        if (h == null)
+            h = t = new Node<E>(null);
+        head = h;
+        tail = t;
+    }
+
+    /**
+     * Throws NullPointerException if argument is null.
+     *
+     * @param v the element
+     */
+    private static void checkNotNull(Object v) {
+        if (v == null)
+            throw new NullPointerException();
     }
 
     // Unsafe mechanics
@@ -715,10 +803,6 @@
         return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
     }
 
-    private void lazySetHead(Node<E> val) {
-        UNSAFE.putOrderedObject(this, headOffset, val);
-    }
-
     static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
                                   String field, Class<?> klazz) {
         try {
--- a/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java	Wed Jul 05 17:24:21 2017 +0200
@@ -42,7 +42,6 @@
 import java.util.List;
 import java.util.concurrent.AbstractExecutorService;
 import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
 import java.util.concurrent.RejectedExecutionException;
@@ -823,15 +822,13 @@
                                    (workerCounts & RUNNING_COUNT_MASK) <= 1);
                 long startTime = untimed? 0 : System.nanoTime();
                 Thread.interrupted();         // clear/ignore interrupt
-                if (eventCount != ec || w.runState != 0 ||
-                    runState >= TERMINATING)  // recheck after clear
-                    break;
+                if (eventCount != ec || w.isTerminating())
+                    break;                    // recheck after clear
                 if (untimed)
                     LockSupport.park(w);
                 else {
                     LockSupport.parkNanos(w, SHRINK_RATE_NANOS);
-                    if (eventCount != ec || w.runState != 0 ||
-                        runState >= TERMINATING)
+                    if (eventCount != ec || w.isTerminating())
                         break;
                     if (System.nanoTime() - startTime >= SHRINK_RATE_NANOS)
                         tryShutdownUnusedWorker(ec);
@@ -899,16 +896,23 @@
                      UNSAFE.compareAndSwapInt(this, workerCountsOffset, wc,
                                               wc + (ONE_RUNNING|ONE_TOTAL))) {
                 ForkJoinWorkerThread w = null;
+                Throwable fail = null;
                 try {
                     w = factory.newThread(this);
-                } finally { // adjust on null or exceptional factory return
-                    if (w == null) {
-                        decrementWorkerCounts(ONE_RUNNING, ONE_TOTAL);
-                        tryTerminate(false); // handle failure during shutdown
-                    }
+                } catch (Throwable ex) {
+                    fail = ex;
                 }
-                if (w == null)
+                if (w == null) { // null or exceptional factory return
+                    decrementWorkerCounts(ONE_RUNNING, ONE_TOTAL);
+                    tryTerminate(false); // handle failure during shutdown
+                    // If originating from an external caller,
+                    // propagate exception, else ignore
+                    if (fail != null && runState < TERMINATING &&
+                        !(Thread.currentThread() instanceof
+                          ForkJoinWorkerThread))
+                        UNSAFE.throwException(fail);
                     break;
+                }
                 w.start(recordWorker(w), ueh);
                 if ((workerCounts >>> TOTAL_COUNT_SHIFT) >= pc) {
                     int c; // advance event count
@@ -997,8 +1001,12 @@
         boolean active = w.active;
         boolean inactivate = false;
         int pc = parallelism;
-        int rs;
-        while (w.runState == 0 && (rs = runState) < TERMINATING) {
+        while (w.runState == 0) {
+            int rs = runState;
+            if (rs >= TERMINATING) { // propagate shutdown
+                w.shutdown();
+                break;
+            }
             if ((inactivate || (active && (rs & ACTIVE_COUNT_MASK) >= pc)) &&
                 UNSAFE.compareAndSwapInt(this, runStateOffset, rs, rs - 1))
                 inactivate = active = w.active = false;
@@ -1126,6 +1134,7 @@
         return true;
     }
 
+
     /**
      * Actions on transition to TERMINATING
      *
@@ -1149,7 +1158,7 @@
                     if (passes > 0 && !w.isTerminated()) {
                         w.cancelTasks();
                         LockSupport.unpark(w);
-                        if (passes > 1) {
+                        if (passes > 1 && !w.isInterrupted()) {
                             try {
                                 w.interrupt();
                             } catch (SecurityException ignore) {
@@ -1726,6 +1735,13 @@
     }
 
     /**
+     * Returns true if terminating or terminated. Used by ForkJoinWorkerThread.
+     */
+    final boolean isAtLeastTerminating() {
+        return runState >= TERMINATING;
+    }
+
+    /**
      * Returns {@code true} if this pool has been shut down.
      *
      * @return {@code true} if this pool has been shut down
--- a/jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java	Wed Jul 05 17:24:21 2017 +0200
@@ -55,10 +55,10 @@
  * start other subtasks.  As indicated by the name of this class,
  * many programs using {@code ForkJoinTask} employ only methods
  * {@link #fork} and {@link #join}, or derivatives such as {@link
- * #invokeAll}.  However, this class also provides a number of other
- * methods that can come into play in advanced usages, as well as
- * extension mechanics that allow support of new forms of fork/join
- * processing.
+ * #invokeAll(ForkJoinTask...) invokeAll}.  However, this class also
+ * provides a number of other methods that can come into play in
+ * advanced usages, as well as extension mechanics that allow
+ * support of new forms of fork/join processing.
  *
  * <p>A {@code ForkJoinTask} is a lightweight form of {@link Future}.
  * The efficiency of {@code ForkJoinTask}s stems from a set of
@@ -250,7 +250,7 @@
         int s;         // the odd construction reduces lock bias effects
         while ((s = status) >= 0) {
             try {
-                synchronized(this) {
+                synchronized (this) {
                     if (UNSAFE.compareAndSwapInt(this, statusOffset, s,SIGNAL))
                         wait();
                 }
@@ -270,7 +270,7 @@
         int s;
         if ((s = status) >= 0) {
             try {
-                synchronized(this) {
+                synchronized (this) {
                     if (UNSAFE.compareAndSwapInt(this, statusOffset, s,SIGNAL))
                         wait(millis, 0);
                 }
@@ -288,7 +288,7 @@
     private void externalAwaitDone() {
         int s;
         while ((s = status) >= 0) {
-            synchronized(this) {
+            synchronized (this) {
                 if (UNSAFE.compareAndSwapInt(this, statusOffset, s, SIGNAL)){
                     boolean interrupted = false;
                     while (status >= 0) {
@@ -669,11 +669,34 @@
         setCompletion(NORMAL);
     }
 
+    /**
+     * Waits if necessary for the computation to complete, and then
+     * retrieves its result.
+     *
+     * @return the computed result
+     * @throws CancellationException if the computation was cancelled
+     * @throws ExecutionException if the computation threw an
+     * exception
+     * @throws InterruptedException if the current thread is not a
+     * member of a ForkJoinPool and was interrupted while waiting
+     */
     public final V get() throws InterruptedException, ExecutionException {
-        quietlyJoin();
-        if (Thread.interrupted())
-            throw new InterruptedException();
-        int s = status;
+        int s;
+        if (Thread.currentThread() instanceof ForkJoinWorkerThread) {
+            quietlyJoin();
+            s = status;
+        }
+        else {
+            while ((s = status) >= 0) {
+                synchronized (this) { // interruptible form of awaitDone
+                    if (UNSAFE.compareAndSwapInt(this, statusOffset,
+                                                 s, SIGNAL)) {
+                        while (status >= 0)
+                            wait();
+                    }
+                }
+            }
+        }
         if (s < NORMAL) {
             Throwable ex;
             if (s == CANCELLED)
@@ -684,6 +707,20 @@
         return getRawResult();
     }
 
+    /**
+     * Waits if necessary for at most the given time for the computation
+     * to complete, and then retrieves its result, if available.
+     *
+     * @param timeout the maximum time to wait
+     * @param unit the time unit of the timeout argument
+     * @return the computed result
+     * @throws CancellationException if the computation was cancelled
+     * @throws ExecutionException if the computation threw an
+     * exception
+     * @throws InterruptedException if the current thread is not a
+     * member of a ForkJoinPool and was interrupted while waiting
+     * @throws TimeoutException if the wait timed out
+     */
     public final V get(long timeout, TimeUnit unit)
         throws InterruptedException, ExecutionException, TimeoutException {
         Thread t = Thread.currentThread();
@@ -725,7 +762,7 @@
                         long ms = nt / 1000000;
                         int ns = (int) (nt % 1000000);
                         try {
-                            synchronized(this) {
+                            synchronized (this) {
                                 if (status >= 0)
                                     wait(ms, ns);
                             }
--- a/jdk/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java	Wed Jul 05 17:24:21 2017 +0200
@@ -778,11 +778,20 @@
 
     // status check methods used mainly by ForkJoinPool
     final boolean isRunning()     { return runState == 0; }
-    final boolean isTerminating() { return (runState & TERMINATING) != 0; }
     final boolean isTerminated()  { return (runState & TERMINATED) != 0; }
     final boolean isSuspended()   { return (runState & SUSPENDED) != 0; }
     final boolean isTrimmed()     { return (runState & TRIMMED) != 0; }
 
+    final boolean isTerminating() {
+        if ((runState & TERMINATING) != 0)
+            return true;
+        if (pool.isAtLeastTerminating()) { // propagate pool state
+            shutdown();
+            return true;
+        }
+        return false;
+    }
+
     /**
      * Sets state to TERMINATING. Does NOT unpark or interrupt
      * to wake up if currently blocked. Callers must do so if desired.
--- a/jdk/src/share/classes/java/util/concurrent/RecursiveAction.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/java/util/concurrent/RecursiveAction.java	Wed Jul 05 17:24:21 2017 +0200
@@ -138,7 +138,7 @@
  *        if (right.tryUnfork()) // directly calculate if not stolen
  *          sum += right.atLeaf(right.lo, right.hi);
  *       else {
- *          right.helpJoin();
+ *          right.join();
  *          sum += right.result;
  *        }
  *        right = right.next;
--- a/jdk/src/share/classes/java/util/logging/LogManager.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/LogManager.java	Wed Jul 05 17:24:21 2017 +0200
@@ -690,6 +690,11 @@
      * Note that since untrusted code may create loggers with
      * arbitrary names this method should not be relied on to
      * find Loggers for security sensitive logging.
+     * It is also important to note that the Logger associated with the
+     * String {@code name} may be garbage collected at any time if there
+     * is no strong reference to the Logger. The caller of this method
+     * must check the return value for null in order to properly handle
+     * the case where the Logger has been garbage collected.
      * <p>
      * @param name name of the logger
      * @return  matching logger or null if none is found
@@ -713,6 +718,14 @@
      * <p>
      * Note:  Loggers may be added dynamically as new classes are loaded.
      * This method only reports on the loggers that are currently registered.
+     * It is also important to note that this method only returns the name
+     * of a Logger, not a strong reference to the Logger itself.
+     * The returned String does nothing to prevent the Logger from being
+     * garbage collected. In particular, if the returned name is passed
+     * to {@code LogManager.getLogger()}, then the caller must check the
+     * return value from {@code LogManager.getLogger()} for null to properly
+     * handle the case where the Logger has been garbage collected in the
+     * time since its name was returned by this method.
      * <p>
      * @return  enumeration of logger name strings
      */
--- a/jdk/src/share/classes/java/util/logging/Logger.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/Logger.java	Wed Jul 05 17:24:21 2017 +0200
@@ -42,7 +42,10 @@
  * <p>
  * Logger objects may be obtained by calls on one of the getLogger
  * factory methods.  These will either create a new Logger or
- * return a suitable existing Logger.
+ * return a suitable existing Logger. It is important to note that
+ * the Logger returned by one of the {@code getLogger} factory methods
+ * may be garbage collected at any time if a strong reference to the
+ * Logger is not kept.
  * <p>
  * Logging messages will be forwarded to registered Handler
  * objects, which can forward the messages to a variety of
@@ -210,7 +213,9 @@
      * who are making serious use of the logging package (for example
      * in products) should create and use their own Logger objects,
      * with appropriate names, so that logging can be controlled on a
-     * suitable per-Logger granularity.
+     * suitable per-Logger granularity. Developers also need to keep a
+     * strong reference to their Logger objects to prevent them from
+     * being garbage collected.
      * <p>
      * @deprecated Initialization of this field is prone to deadlocks.
      * The field must be initialized by the Logger class initialization
@@ -287,6 +292,15 @@
      * based on the LogManager configuration and it will configured
      * to also send logging output to its parent's Handlers.  It will
      * be registered in the LogManager global namespace.
+     * <p>
+     * Note: The LogManager may only retain a weak reference to the newly
+     * created Logger. It is important to understand that a previously
+     * created Logger with the given name may be garbage collected at any
+     * time if there is no strong reference to the Logger. In particular,
+     * this means that two back-to-back calls like
+     * {@code getLogger("MyLogger").log(...)} may use different Logger
+     * objects named "MyLogger" if there is no strong reference to the
+     * Logger named "MyLogger" elsewhere in the program.
      *
      * @param   name            A name for the logger.  This should
      *                          be a dot-separated name and should normally
@@ -311,6 +325,15 @@
      * output to its parent's Handlers.  It will be registered in
      * the LogManager global namespace.
      * <p>
+     * Note: The LogManager may only retain a weak reference to the newly
+     * created Logger. It is important to understand that a previously
+     * created Logger with the given name may be garbage collected at any
+     * time if there is no strong reference to the Logger. In particular,
+     * this means that two back-to-back calls like
+     * {@code getLogger("MyLogger", ...).log(...)} may use different Logger
+     * objects named "MyLogger" if there is no strong reference to the
+     * Logger named "MyLogger" elsewhere in the program.
+     * <p>
      * If the named Logger already exists and does not yet have a
      * localization resource bundle then the given resource bundle
      * name is used.  If the named Logger already exists and has
--- a/jdk/src/share/classes/javax/sql/rowset/BaseRowSet.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/javax/sql/rowset/BaseRowSet.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -734,7 +734,7 @@
                  throw new SQLException("Set initParams() before setCommand");
             }
             params.clear();
-            command = new String(cmd);
+            command = cmd;
         }
 
     }
@@ -797,7 +797,7 @@
             throw new SQLException("Invalid url string detected. " +
             "Cannot be of length less than 1");
         } else {
-            URL = new String(url);
+            URL = url;
         }
 
         dataSource = null;
@@ -854,7 +854,7 @@
         } else if (name.equals("")) {
            throw new SQLException("DataSource name cannot be empty string");
         } else {
-           dataSource = new String(name);
+           dataSource = name;
         }
 
         URL = null;
@@ -889,7 +889,7 @@
         {
            username = null;
         } else {
-           username = new String(name);
+           username = name;
         }
     }
 
@@ -924,7 +924,7 @@
         {
            password = null;
         } else {
-           password = new String(pass);
+           password = pass;
         }
     }
 
@@ -1563,13 +1563,13 @@
 
         nullVal = new Object[2];
         nullVal[0] = null;
-        nullVal[1] = new Integer(sqlType);
+        nullVal[1] = Integer.valueOf(sqlType);
 
        if (params == null){
             throw new SQLException("Set initParams() before setNull");
        }
 
-        params.put(new Integer(parameterIndex - 1), nullVal);
+        params.put(Integer.valueOf(parameterIndex - 1), nullVal);
     }
 
     /**
@@ -1644,14 +1644,14 @@
 
         nullVal = new Object[3];
         nullVal[0] = null;
-        nullVal[1] = new Integer(sqlType);
-        nullVal[2] = new String(typeName);
+        nullVal[1] = Integer.valueOf(sqlType);
+        nullVal[2] = typeName;
 
        if(params == null){
             throw new SQLException("Set initParams() before setNull");
        }
 
-        params.put(new Integer(parameterIndex - 1), nullVal);
+        params.put(Integer.valueOf(parameterIndex - 1), nullVal);
     }
 
 
@@ -1686,7 +1686,7 @@
             throw new SQLException("Set initParams() before setNull");
        }
 
-        params.put(new Integer(parameterIndex - 1), new Boolean(x));
+        params.put(Integer.valueOf(parameterIndex - 1), Boolean.valueOf(x));
     }
 
     /**
@@ -1720,7 +1720,7 @@
             throw new SQLException("Set initParams() before setByte");
        }
 
-        params.put(new Integer(parameterIndex - 1), new Byte(x));
+        params.put(Integer.valueOf(parameterIndex - 1), Byte.valueOf(x));
     }
 
     /**
@@ -1754,7 +1754,7 @@
              throw new SQLException("Set initParams() before setShort");
         }
 
-        params.put(new Integer(parameterIndex - 1), new Short(x));
+        params.put(Integer.valueOf(parameterIndex - 1), Short.valueOf(x));
     }
 
     /**
@@ -1786,7 +1786,7 @@
         if(params == null){
              throw new SQLException("Set initParams() before setInt");
         }
-        params.put(new Integer(parameterIndex - 1), new Integer(x));
+        params.put(Integer.valueOf(parameterIndex - 1), Integer.valueOf(x));
     }
 
     /**
@@ -1818,7 +1818,7 @@
         if(params == null){
              throw new SQLException("Set initParams() before setLong");
         }
-        params.put(new Integer(parameterIndex - 1), new Long(x));
+        params.put(Integer.valueOf(parameterIndex - 1), Long.valueOf(x));
     }
 
     /**
@@ -1850,7 +1850,7 @@
         if(params == null){
              throw new SQLException("Set initParams() before setFloat");
         }
-        params.put(new Integer(parameterIndex - 1), new Float(x));
+        params.put(Integer.valueOf(parameterIndex - 1), new Float(x));
     }
 
     /**
@@ -1882,7 +1882,7 @@
         if(params == null){
              throw new SQLException("Set initParams() before setDouble");
         }
-        params.put(new Integer(parameterIndex - 1), new Double(x));
+        params.put(Integer.valueOf(parameterIndex - 1), new Double(x));
     }
 
     /**
@@ -1914,7 +1914,7 @@
         if(params == null){
              throw new SQLException("Set initParams() before setBigDecimal");
         }
-        params.put(new Integer(parameterIndex - 1), x);
+        params.put(Integer.valueOf(parameterIndex - 1), x);
     }
 
     /**
@@ -1948,7 +1948,7 @@
         if(params == null){
              throw new SQLException("Set initParams() before setString");
         }
-        params.put(new Integer(parameterIndex - 1), x);
+        params.put(Integer.valueOf(parameterIndex - 1), x);
     }
 
     /**
@@ -1982,7 +1982,7 @@
         if(params == null){
              throw new SQLException("Set initParams() before setBytes");
         }
-        params.put(new Integer(parameterIndex - 1), x);
+        params.put(Integer.valueOf(parameterIndex - 1), x);
     }
 
     /**
@@ -2024,7 +2024,7 @@
         if(params == null){
              throw new SQLException("Set initParams() before setDate");
         }
-        params.put(new Integer(parameterIndex - 1), x);
+        params.put(Integer.valueOf(parameterIndex - 1), x);
     }
 
     /**
@@ -2069,7 +2069,7 @@
              throw new SQLException("Set initParams() before setTime");
         }
 
-        params.put(new Integer(parameterIndex - 1), x);
+        params.put(Integer.valueOf(parameterIndex - 1), x);
     }
 
     /**
@@ -2112,7 +2112,7 @@
              throw new SQLException("Set initParams() before setTimestamp");
         }
 
-        params.put(new Integer(parameterIndex - 1), x);
+        params.put(Integer.valueOf(parameterIndex - 1), x);
     }
 
     /**
@@ -2185,14 +2185,14 @@
 
         asciiStream = new Object[3];
         asciiStream[0] = x;
-        asciiStream[1] = new Integer(length);
-        asciiStream[2] = new Integer(ASCII_STREAM_PARAM);
+        asciiStream[1] = Integer.valueOf(length);
+        asciiStream[2] = Integer.valueOf(ASCII_STREAM_PARAM);
 
         if(params == null){
              throw new SQLException("Set initParams() before setAsciiStream");
         }
 
-        params.put(new Integer(parameterIndex - 1), asciiStream);
+        params.put(Integer.valueOf(parameterIndex - 1), asciiStream);
     }
 
   /**
@@ -2290,13 +2290,13 @@
 
         binaryStream = new Object[3];
         binaryStream[0] = x;
-        binaryStream[1] = new Integer(length);
-        binaryStream[2] = new Integer(BINARY_STREAM_PARAM);
+        binaryStream[1] = Integer.valueOf(length);
+        binaryStream[2] = Integer.valueOf(BINARY_STREAM_PARAM);
         if(params == null){
              throw new SQLException("Set initParams() before setBinaryStream");
         }
 
-        params.put(new Integer(parameterIndex - 1), binaryStream);
+        params.put(Integer.valueOf(parameterIndex - 1), binaryStream);
     }
 
 
@@ -2396,12 +2396,12 @@
 
         unicodeStream = new Object[3];
         unicodeStream[0] = x;
-        unicodeStream[1] = new Integer(length);
-        unicodeStream[2] = new Integer(UNICODE_STREAM_PARAM);
+        unicodeStream[1] = Integer.valueOf(length);
+        unicodeStream[2] = Integer.valueOf(UNICODE_STREAM_PARAM);
         if(params == null){
              throw new SQLException("Set initParams() before setUnicodeStream");
         }
-        params.put(new Integer(parameterIndex - 1), unicodeStream);
+        params.put(Integer.valueOf(parameterIndex - 1), unicodeStream);
     }
 
     /**
@@ -2475,11 +2475,11 @@
 
         charStream = new Object[2];
         charStream[0] = reader;
-        charStream[1] = new Integer(length);
+        charStream[1] = Integer.valueOf(length);
         if(params == null){
              throw new SQLException("Set initParams() before setCharacterStream");
         }
-        params.put(new Integer(parameterIndex - 1), charStream);
+        params.put(Integer.valueOf(parameterIndex - 1), charStream);
     }
 
    /**
@@ -2591,12 +2591,12 @@
 
         obj = new Object[3];
         obj[0] = x;
-        obj[1] = new Integer(targetSqlType);
-        obj[2] = new Integer(scale);
+        obj[1] = Integer.valueOf(targetSqlType);
+        obj[2] = Integer.valueOf(scale);
         if(params == null){
              throw new SQLException("Set initParams() before setObject");
         }
-        params.put(new Integer(parameterIndex - 1), obj);
+        params.put(Integer.valueOf(parameterIndex - 1), obj);
     }
 
     /**
@@ -2654,11 +2654,11 @@
 
         obj = new Object[2];
         obj[0] = x;
-        obj[1] = new Integer(targetSqlType);
+        obj[1] = Integer.valueOf(targetSqlType);
         if (params == null){
              throw new SQLException("Set initParams() before setObject");
         }
-        params.put(new Integer(parameterIndex - 1), obj);
+        params.put(Integer.valueOf(parameterIndex - 1), obj);
     }
 
     /**
@@ -2726,7 +2726,7 @@
         if (params == null) {
              throw new SQLException("Set initParams() before setObject");
         }
-        params.put(new Integer(parameterIndex - 1), x);
+        params.put(Integer.valueOf(parameterIndex - 1), x);
     }
 
     /**
@@ -2773,7 +2773,7 @@
         if (params == null) {
              throw new SQLException("Set initParams() before setRef");
         }
-        params.put(new Integer(parameterIndex - 1), new SerialRef(ref));
+        params.put(Integer.valueOf(parameterIndex - 1), new SerialRef(ref));
     }
 
     /**
@@ -2817,7 +2817,7 @@
         if(params == null){
              throw new SQLException("Set initParams() before setBlob");
         }
-        params.put(new Integer(parameterIndex - 1), new SerialBlob(x));
+        params.put(Integer.valueOf(parameterIndex - 1), new SerialBlob(x));
     }
 
     /**
@@ -2862,7 +2862,7 @@
         if(params == null){
              throw new SQLException("Set initParams() before setClob");
         }
-        params.put(new Integer(parameterIndex - 1), new SerialClob(x));
+        params.put(Integer.valueOf(parameterIndex - 1), new SerialClob(x));
     }
 
     /**
@@ -2910,7 +2910,7 @@
         if (params == null){
              throw new SQLException("Set initParams() before setArray");
         }
-        params.put(new Integer(parameterIndex - 1), new SerialArray(array));
+        params.put(Integer.valueOf(parameterIndex - 1), new SerialArray(array));
     }
 
     /**
@@ -2975,7 +2975,7 @@
         if(params == null){
              throw new SQLException("Set initParams() before setDate");
         }
-        params.put(new Integer(parameterIndex - 1), date);
+        params.put(Integer.valueOf(parameterIndex - 1), date);
     }
 
     /**
@@ -3041,7 +3041,7 @@
         if(params == null){
              throw new SQLException("Set initParams() before setTime");
         }
-        params.put(new Integer(parameterIndex - 1), time);
+        params.put(Integer.valueOf(parameterIndex - 1), time);
     }
 
     /**
@@ -3107,7 +3107,7 @@
         if(params == null){
              throw new SQLException("Set initParams() before setTimestamp");
         }
-        params.put(new Integer(parameterIndex - 1), timestamp);
+        params.put(Integer.valueOf(parameterIndex - 1), timestamp);
     }
 
     /**
@@ -3181,7 +3181,7 @@
 
             Object[] paramsArray = new Object[params.size()];
             for (int i = 0; i < params.size(); i++) {
-               paramsArray[i] = params.get(new Integer(i));
+               paramsArray[i] = params.get(Integer.valueOf(i));
                if (paramsArray[i] == null) {
                  throw new SQLException("missing parameter: " + (i + 1));
                } //end if
--- a/jdk/src/share/classes/javax/sql/rowset/CachedRowSet.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/javax/sql/rowset/CachedRowSet.java	Wed Jul 05 17:24:21 2017 +0200
@@ -39,7 +39,7 @@
  * <code>CachedRowSet</code> must implement.
  * <P>
  * The reference implementation of the <code>CachedRowSet</code> interface provided
- * by Sun Microsystems is a standard implementation. Developers may use this implementation
+ * by Oracle Corporation is a standard implementation. Developers may use this implementation
  * just as it is, they may extend it, or they may choose to write their own implementations
  * of this interface.
  * <P>
@@ -1623,4 +1623,3 @@
     public boolean previousPage() throws SQLException;
 
 }
-
--- a/jdk/src/share/classes/javax/sql/rowset/RowSetMetaDataImpl.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/javax/sql/rowset/RowSetMetaDataImpl.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -306,9 +306,9 @@
     public void setColumnLabel(int columnIndex, String label) throws SQLException {
         checkColRange(columnIndex);
         if (label != null) {
-            colInfo[columnIndex].columnLabel = new String(label);
+            colInfo[columnIndex].columnLabel = label;
         } else {
-            colInfo[columnIndex].columnLabel = new String("");
+            colInfo[columnIndex].columnLabel = "";
         }
     }
 
@@ -326,9 +326,9 @@
     public void setColumnName(int columnIndex, String columnName) throws SQLException {
         checkColRange(columnIndex);
         if (columnName != null) {
-            colInfo[columnIndex].columnName = new String(columnName);
+            colInfo[columnIndex].columnName = columnName;
         } else {
-            colInfo[columnIndex].columnName = new String("");
+            colInfo[columnIndex].columnName = "";
         }
     }
 
@@ -348,9 +348,9 @@
     public void setSchemaName(int columnIndex, String schemaName) throws SQLException {
         checkColRange(columnIndex);
         if (schemaName != null ) {
-            colInfo[columnIndex].schemaName = new String(schemaName);
+            colInfo[columnIndex].schemaName = schemaName;
         } else {
-            colInfo[columnIndex].schemaName = new String("");
+            colInfo[columnIndex].schemaName = "";
         }
     }
 
@@ -411,9 +411,9 @@
     public void setTableName(int columnIndex, String tableName) throws SQLException {
         checkColRange(columnIndex);
         if (tableName != null) {
-            colInfo[columnIndex].tableName = new String(tableName);
+            colInfo[columnIndex].tableName = tableName;
         } else {
-            colInfo[columnIndex].tableName = new String("");
+            colInfo[columnIndex].tableName = "";
         }
     }
 
@@ -432,9 +432,9 @@
     public void setCatalogName(int columnIndex, String catalogName) throws SQLException {
         checkColRange(columnIndex);
         if (catalogName != null)
-            colInfo[columnIndex].catName = new String(catalogName);
+            colInfo[columnIndex].catName = catalogName;
         else
-            colInfo[columnIndex].catName = new String("");
+            colInfo[columnIndex].catName = "";
     }
 
     /**
@@ -474,9 +474,9 @@
         throws SQLException {
         checkColRange(columnIndex);
         if (typeName != null) {
-            colInfo[columnIndex].colTypeName = new String(typeName);
+            colInfo[columnIndex].colTypeName = typeName;
         } else {
-            colInfo[columnIndex].colTypeName = new String("");
+            colInfo[columnIndex].colTypeName = "";
         }
     }
 
@@ -827,7 +827,7 @@
      *         or the given column number is out of bounds
      */
     public String getColumnClassName(int columnIndex) throws SQLException {
-        String className = (new String()).getClass().getName();
+        String className = String.class.getName();
 
         int sqlType = getColumnType(columnIndex);
 
@@ -835,65 +835,62 @@
 
         case Types.NUMERIC:
         case Types.DECIMAL:
-            className = (new java.math.BigDecimal(0)).getClass().getName ();
+            className = java.math.BigDecimal.class.getName();
             break;
 
         case Types.BIT:
-            className = (new Boolean(false)).getClass().getName ();
+            className = java.lang.Boolean.class.getName();
             break;
 
         case Types.TINYINT:
-            className = (new Byte("0")).getClass().getName ();
+            className = java.lang.Byte.class.getName();
             break;
 
         case Types.SMALLINT:
-            className = (new Short("0")).getClass().getName ();
+            className = java.lang.Short.class.getName();
             break;
 
         case Types.INTEGER:
-            className = (new Integer(0)).getClass().getName ();
+            className = java.lang.Integer.class.getName();
             break;
 
         case Types.BIGINT:
-            className = (new Long(0)).getClass().getName ();
+            className = java.lang.Long.class.getName();
             break;
 
         case Types.REAL:
-            className = (new Float(0)).getClass().getName ();
+            className = java.lang.Float.class.getName();
             break;
 
         case Types.FLOAT:
         case Types.DOUBLE:
-            className = (new Double(0)).getClass().getName();
+            className = java.lang.Double.class.getName();
             break;
 
         case Types.BINARY:
         case Types.VARBINARY:
         case Types.LONGVARBINARY:
-            byte[] b = {};
-            className = (b.getClass()).getName();
+            className = "byte[]";
             break;
 
         case Types.DATE:
-            className = (new java.sql.Date(123456)).getClass().getName ();
+            className = java.sql.Date.class.getName();
             break;
 
         case Types.TIME:
-            className = (new java.sql.Time(123456)).getClass().getName ();
+            className = java.sql.Time.class.getName();
             break;
 
         case Types.TIMESTAMP:
-            className = (new java.sql.Timestamp(123456)).getClass().getName ();
+            className = java.sql.Timestamp.class.getName();
             break;
 
         case Types.BLOB:
-            byte[] blob = {};
-            className = (blob.getClass()).getName();
+            className = java.sql.Blob.class.getName();
             break;
 
         case Types.CLOB:
-            char[] c = {};
-            className = (c.getClass()).getName();
+            className = java.sql.Clob.class.getName();
             break;
         }
 
--- a/jdk/src/share/classes/javax/sql/rowset/RowSetProvider.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/javax/sql/rowset/RowSetProvider.java	Wed Jul 05 17:24:21 2017 +0200
@@ -29,7 +29,6 @@
 import java.security.PrivilegedAction;
 import java.sql.SQLException;
 import java.util.ServiceLoader;
-import javax.sql.rowset.RowSetFactory;
 
 /**
  * A factory API that enables applications to obtain a
@@ -82,15 +81,15 @@
      * the <code>RowSetFactory</code> implementation class to load:</p>
      * <ul>
      * <li>
-     * The System property {@code javax.sql.rowset.RowsetFactory}.  For example:
+     * The System property {@code javax.sql.rowset.RowSetFactory}.  For example:
      * <ul>
      * <li>
-     * -Djavax.sql.rowset.RowsetFactory=com.sun.rowset.RowSetFactoryImpl
+     * -Djavax.sql.rowset.RowSetFactory=com.sun.rowset.RowSetFactoryImpl
      * </li>
      * </ul>
      * <li>
-     * The ServiceLocator API. The ServiceLocator API will look
-     * for a classname in the file
+     * The {@link ServiceLoader} API. The {@code ServiceLoader} API will look
+     * for a class name in the file
      * {@code META-INF/services/javax.sql.rowset.RowSetFactory}
      * in jars available to the runtime. For example, to have the the RowSetFactory
      * implementation {@code com.sun.rowset.RowSetFactoryImpl } loaded, the
@@ -271,7 +270,7 @@
     /**
      * Returns the requested System Property.  If a {@code SecurityException}
      * occurs, just return NULL
-     * @param propName - System property to retreive
+     * @param propName - System property to retrieve
      * @return The System property value or NULL if the property does not exist
      * or a {@code SecurityException} occurs.
      */
--- a/jdk/src/share/classes/javax/sql/rowset/WebRowSet.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/javax/sql/rowset/WebRowSet.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -115,7 +115,7 @@
  *      &lt;<font color=red>url</font>&gt;jdbc:thin:oracle&lt;<font color=red>/url</font>&gt;
  *      &lt;<font color=red>sync-provider</font>&gt;
  *              &lt;<font color=red>sync-provider-name</font>&gt;.com.rowset.provider.RIOptimisticProvider&lt;<font color=red>/sync-provider-name</font>&gt;
- *              &lt;<font color=red>sync-provider-vendor</font>&gt;Sun Microsystems&lt;<font color=red>/sync-provider-vendor</font>&gt;
+ *              &lt;<font color=red>sync-provider-vendor</font>&gt;Oracle Corporation&lt;<font color=red>/sync-provider-vendor</font>&gt;
  *              &lt;<font color=red>sync-provider-version</font>&gt;1.0&lt;<font color=red>/sync-provider-name</font>&gt;
  *              &lt;<font color=red>sync-provider-grade</font>&gt;LOW&lt;<font color=red>/sync-provider-grade</font>&gt;
  *              &lt;<font color=red>data-source-lock</font>&gt;NONE&lt;<font color=red>/data-source-lock</font>&gt;
@@ -489,7 +489,7 @@
      * tags and their valid values for a <code>WebRowSet</code> implementation.
      */
     public static String PUBLIC_XML_SCHEMA =
-        "--//Sun Microsystems, Inc.//XSD Schema//EN";
+        "--//Oracle Corporation//XSD Schema//EN";
 
     /**
      * The URL for the XML Schema definition file that defines the XML tags and
--- a/jdk/src/share/classes/javax/sql/rowset/rowset.properties	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/javax/sql/rowset/rowset.properties	Wed Jul 05 17:24:21 2017 +0200
@@ -3,10 +3,10 @@
 
 # Optimistic synchonriztaion provider
 rowset.provider.classname.0=com.sun.rowset.providers.RIOptimisticProvider
-rowset.provider.vendor.0=Sun Microsystems Inc
+rowset.provider.vendor.0=Oracle Corporation
 rowset.provider.version.0=1.0
 
 # XML Provider using standard XML schema
 rowset.provider.classname.1=com.sun.rowset.providers.RIXMLProvider
-rowset.provider.vendor.1=Sun Microsystems Inc.
+rowset.provider.vendor.1=Oracle Corporation
 rowset.provider.version.1=1.0
--- a/jdk/src/share/classes/javax/sql/rowset/serial/SQLOutputImpl.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/javax/sql/rowset/serial/SQLOutputImpl.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -137,7 +137,7 @@
      *        values of a UDT to the database.
      */
     public void writeBoolean(boolean x) throws SQLException {
-        attribs.add(new Boolean(x));
+        attribs.add(Boolean.valueOf(x));
     }
 
     /**
@@ -151,7 +151,7 @@
      *        values of a UDT to the database.
      */
     public void writeByte(byte x) throws SQLException {
-        attribs.add(new Byte(x));
+        attribs.add(Byte.valueOf(x));
     }
 
     /**
@@ -165,7 +165,7 @@
      *        values of a UDT to the database.
      */
     public void writeShort(short x) throws SQLException {
-        attribs.add(new Short(x));
+        attribs.add(Short.valueOf(x));
     }
 
     /**
@@ -179,7 +179,7 @@
      *        values of a UDT to the database.
      */
     public void writeInt(int x) throws SQLException {
-        attribs.add(new Integer(x));
+        attribs.add(Integer.valueOf(x));
     }
 
     /**
@@ -193,7 +193,7 @@
      *        values of a UDT to the database.
      */
     public void writeLong(long x) throws SQLException {
-        attribs.add(new Long(x));
+        attribs.add(Long.valueOf(x));
     }
 
     /**
--- a/jdk/src/share/classes/javax/sql/rowset/serial/SerialRef.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/javax/sql/rowset/serial/SerialRef.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -77,7 +77,7 @@
             throw new SQLException("Cannot instantiate a SerialRef object " +
                 "that returns a null base type name");
         } else {
-            baseTypeName = new String(ref.getBaseTypeName());
+            baseTypeName = ref.getBaseTypeName();
         }
     }
 
@@ -110,7 +110,7 @@
         throws SerialException
     {
         map = new Hashtable(map);
-        if (!object.equals(null)) {
+        if (object != null) {
             return map.get(object);
         } else {
             throw new SerialException("The object is not set");
--- a/jdk/src/share/classes/javax/sql/rowset/serial/SerialStruct.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/javax/sql/rowset/serial/SerialStruct.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -94,7 +94,7 @@
         try {
 
         // get the type name
-        SQLTypeName = new String(in.getSQLTypeName());
+        SQLTypeName = in.getSQLTypeName();
         System.out.println("SQLTypeName: " + SQLTypeName);
 
         // get the attributes of the struct
@@ -137,7 +137,7 @@
         try {
 
         //set the type name
-        SQLTypeName = new String(in.getSQLTypeName());
+        SQLTypeName = in.getSQLTypeName();
 
         Vector tmp = new Vector();
         in.writeSQL(new SQLOutputImpl(tmp, map));
@@ -247,7 +247,7 @@
     }
 
     /**
-         * The identifier that assists in the serialization of this
+     * The identifier that assists in the serialization of this
      * <code>SerialStruct</code> object.
      */
     static final long serialVersionUID = -8322445504027483372L;
--- a/jdk/src/share/classes/javax/sql/rowset/spi/SyncFactory.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/javax/sql/rowset/spi/SyncFactory.java	Wed Jul 05 17:24:21 2017 +0200
@@ -125,12 +125,12 @@
  *
  *   # Optimistic synchronization provider
  *   rowset.provider.classname.0=com.sun.rowset.providers.RIOptimisticProvider
- *   rowset.provider.vendor.0=Sun Microsystems Inc
+ *   rowset.provider.vendor.0=Oracle Corporation
  *   rowset.provider.version.0=1.0
  *
  *   # XML Provider using standard XML schema
  *   rowset.provider.classname.1=com.sun.rowset.providers.RIXMLProvider
- *   rowset.provider.vendor.1=Sun Microsystems Inc.
+ *   rowset.provider.vendor.1=Oracle Corporation
  *   rowset.provider.version.1=1.0
  * </PRE>
  * The <code>SyncFactory</code> checks this file and registers the
@@ -369,7 +369,7 @@
             try {
 
                 // check if user is supplying his Synchronisation Provider
-                // Implementation  if not use Sun's implementation.
+                // Implementation if not using Oracle's implementation.
                 // properties.load(new FileInputStream(ROWSET_PROPERTIES));
 
                 // The rowset.properties needs to be in jdk/jre/lib when
--- a/jdk/src/share/classes/javax/sql/rowset/spi/SyncProvider.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/javax/sql/rowset/spi/SyncProvider.java	Wed Jul 05 17:24:21 2017 +0200
@@ -91,8 +91,8 @@
  * </pre>
  * <p>
  * A vendor can register a <code>SyncProvider</code> implementation class name
- * with Sun Microsystems, Inc. by sending email to jdbc@sun.com.
- * Sun will maintain a database listing the
+ * with Oracle Corporation by sending email to jdbc@sun.com.
+ * Oracle will maintain a database listing the
  * available <code>SyncProvider</code> implementations for use with compliant
  * <code>RowSet</code> implementations.  This database will be similar to the
  * one already maintained to list available JDBC drivers.
--- a/jdk/src/share/classes/javax/sql/rowset/spi/package.html	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/javax/sql/rowset/spi/package.html	Wed Jul 05 17:24:21 2017 +0200
@@ -8,7 +8,7 @@
   <meta name="GENERATOR"
  content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]">
 <!--
-Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 
 This code is free software; you can redistribute it and/or modify it
@@ -199,7 +199,7 @@
 Vendors may develop a <tt>SyncProvider</tt> implementation with any one of the possible
 levels of synchronization, thus giving <code>RowSet</code> objects a choice of
 synchronization mechanisms.  A vendor can make its implementation available by 
-registering the fully qualified class name with Sun Microsystems at 
+registering the fully qualified class name with Oracle Corporation at
 <code>jdbc@sun.com</code>. This process is discussed in further detail below. 
 <P>
 
--- a/jdk/src/share/classes/javax/swing/GroupLayout.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/javax/swing/GroupLayout.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1464,8 +1464,8 @@
      * &lt;= {@code pref} &lt;= {@code max}.
      * <p>
      * Similarly any methods that take a {@code Component} throw a
-     * {@code NullPointerException} if passed {@code null} and any methods
-     * that take a {@code Group} throw an {@code IllegalArgumentException} if
+     * {@code IllegalArgumentException} if passed {@code null} and any methods
+     * that take a {@code Group} throw an {@code NullPointerException} if
      * passed {@code null}.
      *
      * @see #createSequentialGroup
--- a/jdk/src/share/classes/javax/swing/JComponent.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/javax/swing/JComponent.java	Wed Jul 05 17:24:21 2017 +0200
@@ -4787,6 +4787,17 @@
      * @see RepaintManager#addDirtyRegion
      */
     public void repaint(long tm, int x, int y, int width, int height) {
+        Container p = this;
+        while ((p = p.getParent()) instanceof JComponent) {
+            JComponent jp = (JComponent) p;
+            if (jp.isPaintingOrigin()) {
+                Rectangle rectangle = SwingUtilities.convertRectangle(
+                        this, new Rectangle(x, y, width, height), jp);
+                jp.repaint(tm,
+                        rectangle.x, rectangle.y, rectangle.width, rectangle.height);
+                return;
+            }
+        }
         RepaintManager.currentManager(this).addDirtyRegion(this, x, y, width, height);
     }
 
--- a/jdk/src/share/classes/javax/swing/JDesktopPane.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/javax/swing/JDesktopPane.java	Wed Jul 05 17:24:21 2017 +0200
@@ -215,7 +215,8 @@
 
     /**
      * Sets the <code>DesktopManger</code> that will handle
-     * desktop-specific UI actions.
+     * desktop-specific UI actions. This may be overridden by
+     * {@code LookAndFeel}.
      *
      * @param d the <code>DesktopManager</code> to use
      *
--- a/jdk/src/share/classes/javax/swing/JLayer.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/javax/swing/JLayer.java	Wed Jul 05 17:24:21 2017 +0200
@@ -25,17 +25,17 @@
 
 package javax.swing;
 
+import sun.awt.AWTAccessor;
+
 import javax.swing.plaf.LayerUI;
+import javax.swing.border.Border;
 import java.awt.*;
 import java.awt.event.*;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.io.IOException;
 import java.io.ObjectInputStream;
-import java.io.Serializable;
-import java.lang.ref.WeakReference;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 
@@ -156,8 +156,6 @@
     private LayerUI<? super V> layerUI;
     private JPanel glassPane;
     private boolean isPainting;
-    private static final DefaultLayerLayout sharedLayoutInstance =
-            new DefaultLayerLayout();
     private long eventMask;
 
     private static final LayerEventController eventController =
@@ -165,7 +163,7 @@
 
     /**
      * Creates a new {@code JLayer} object with a {@code null} view component
-     * and {@code null} {@link javax.swing.plaf.LayerUI}.
+     * and default {@link javax.swing.plaf.LayerUI}.
      *
      * @see #setView
      * @see #setUI
@@ -176,14 +174,14 @@
 
     /**
      * Creates a new {@code JLayer} object
-     * with {@code null} {@link javax.swing.plaf.LayerUI}.
+     * with default {@link javax.swing.plaf.LayerUI}.
      *
      * @param view the component to be decorated by this {@code JLayer}
      *
      * @see #setUI
      */
     public JLayer(V view) {
-        this(view, null);
+        this(view, new LayerUI<V>());
     }
 
     /**
@@ -195,7 +193,6 @@
      * to be used by this {@code JLayer}
      */
     public JLayer(V view, LayerUI<V> ui) {
-        setLayout(sharedLayoutInstance);
         setGlassPane(createGlassPane());
         setView(view);
         setUI(ui);
@@ -279,10 +276,15 @@
      */
     public void setGlassPane(JPanel glassPane) {
         Component oldGlassPane = getGlassPane();
+        boolean isGlassPaneVisible = false;
         if (oldGlassPane != null) {
+            isGlassPaneVisible = oldGlassPane.isVisible();
             super.remove(oldGlassPane);
         }
         if (glassPane != null) {
+            AWTAccessor.getComponentAccessor().setMixingCutoutShape(glassPane,
+                    new Rectangle());
+            glassPane.setVisible(isGlassPaneVisible);
             super.addImpl(glassPane, null, 0);
         }
         this.glassPane = glassPane;
@@ -303,6 +305,40 @@
     }
 
     /**
+     * Sets the layout manager for this container.  This method is
+     * overridden to prevent the layout manager from being set.
+     * <p/>Note:  If {@code mgr} is non-{@code null}, this
+     * method will throw an exception as layout managers are not supported on
+     * a {@code JLayer}.
+     *
+     * @param mgr the specified layout manager
+     * @exception IllegalArgumentException this method is not supported
+     */
+    public void setLayout(LayoutManager mgr) {
+        if (mgr != null) {
+            throw new IllegalArgumentException("JLayer.setLayout() not supported");
+        }
+    }
+
+    /**
+     * A non-{@code null] border, or non-zero insets, isn't supported, to prevent the geometry
+     * of this component from becoming complex enough to inhibit
+     * subclassing of {@code LayerUI} class.  To create a {@code JLayer} with a border,
+     * add it to a {@code JPanel} that has a border.
+     * <p/>Note:  If {@code border} is non-{@code null}, this
+     * method will throw an exception as borders are not supported on
+     * a {@code JLayer}.
+     *
+     * @param border the {@code Border} to set
+     * @exception IllegalArgumentException this method is not supported
+     */
+    public void setBorder(Border border) {
+        if (border != null) {
+            throw new IllegalArgumentException("JLayer.setBorder() not supported");
+        }
+    }
+
+    /**
      * This method is not supported by {@code JLayer}
      * and always throws {@code UnsupportedOperationException}
      *
@@ -341,6 +377,32 @@
     }
 
     /**
+     * Always returns {@code true} to cause painting to originate from {@code JLayer},
+     * or one of its ancestors.
+     *
+     * @return true
+     * @see JComponent#isPaintingOrigin()
+     */
+    boolean isPaintingOrigin() {
+        return true;
+    }
+
+    /**
+     * Delegates repainting to {@link javax.swing.plaf.LayerUI#repaint} method.
+     *
+     * @param tm  this parameter is not used
+     * @param x  the x value of the dirty region
+     * @param y  the y value of the dirty region
+     * @param width  the width of the dirty region
+     * @param height  the height of the dirty region
+     */
+    public void repaint(long tm, int x, int y, int width, int height) {
+        if (getUI() != null) {
+            getUI().repaint(tm, x, y, width, height, this);
+        }
+    }
+
+    /**
      * Delegates all painting to the {@link javax.swing.plaf.LayerUI} object.
      *
      * @param g the {@code Graphics} to render to
@@ -364,14 +426,18 @@
     }
 
     /**
-     * To enable the correct painting of the {@code glassPane} and view component,
-     * the {@code JLayer} overrides the default implementation of
-     * this method to return {@code false} when the {@code glassPane} is visible.
+     * The {@code JLayer} overrides the default implementation of
+     * this method (in {@code JComponent}) to return {@code false}.
+     * This ensures
+     * that the drawing machinery will call the {@code JLayer}'s
+     * {@code paint}
+     * implementation rather than messaging the {@code JLayer}'s
+     * children directly.
      *
-     * @return false if {@code JLayer}'s {@code glassPane} is visible
+     * @return false
      */
     public boolean isOptimizedDrawingEnabled() {
-        return glassPane == null || !glassPane.isVisible();
+        return false;
     }
 
     /**
@@ -461,17 +527,16 @@
     /**
      * Returns the preferred size of the viewport for a view component.
      * <p/>
-     * If the ui delegate of this layer is not {@code null}, this method delegates its
-     * implementation to the {@code LayerUI.getPreferredScrollableViewportSize(JLayer)}
+     * If the view component of this layer implements {@link Scrollable}, this method delegates its
+     * implementation to the view component.
      *
      * @return the preferred size of the viewport for a view component
      *
      * @see Scrollable
-     * @see LayerUI#getPreferredScrollableViewportSize(JLayer)
      */
     public Dimension getPreferredScrollableViewportSize() {
-        if (getUI() != null) {
-            return getUI().getPreferredScrollableViewportSize(this);
+        if (getView() instanceof Scrollable) {
+            return ((Scrollable)getView()).getPreferredScrollableViewportSize();
         }
         return getPreferredSize();
     }
@@ -481,18 +546,17 @@
      * that display logical rows or columns in order to completely expose
      * one block of rows or columns, depending on the value of orientation.
      * <p/>
-     * If the ui delegate of this layer is not {@code null}, this method delegates its
-     * implementation to the {@code LayerUI.getScrollableBlockIncrement(JLayer,Rectangle,int,int)}
+     * If the view component of this layer implements {@link Scrollable}, this method delegates its
+     * implementation to the view component.
      *
      * @return the "block" increment for scrolling in the specified direction
      *
      * @see Scrollable
-     * @see LayerUI#getScrollableBlockIncrement(JLayer, Rectangle, int, int)
      */
     public int getScrollableBlockIncrement(Rectangle visibleRect,
                                            int orientation, int direction) {
-        if (getUI() != null) {
-            return getUI().getScrollableBlockIncrement(this, visibleRect,
+        if (getView() instanceof Scrollable) {
+            return ((Scrollable)getView()).getScrollableBlockIncrement(visibleRect,
                     orientation, direction);
         }
         return (orientation == SwingConstants.VERTICAL) ? visibleRect.height :
@@ -504,17 +568,16 @@
      * determine the height of the layer, unless the preferred height
      * of the layer is smaller than the height of the viewport.
      * <p/>
-     * If the ui delegate of this layer is not null, this method delegates its
-     * implementation to the {@code LayerUI.getScrollableTracksViewportHeight(JLayer)}
+     * If the view component of this layer implements {@link Scrollable}, this method delegates its
+     * implementation to the view component.
      *
      * @return whether the layer should track the height of the viewport
      *
      * @see Scrollable
-     * @see LayerUI#getScrollableTracksViewportHeight(JLayer)
      */
     public boolean getScrollableTracksViewportHeight() {
-        if (getUI() != null) {
-            return getUI().getScrollableTracksViewportHeight(this);
+        if (getView() instanceof Scrollable) {
+            return ((Scrollable)getView()).getScrollableTracksViewportHeight();
         }
         return false;
     }
@@ -524,17 +587,16 @@
      * determine the width of the layer, unless the preferred width
      * of the layer is smaller than the width of the viewport.
      * <p/>
-     * If the ui delegate of this layer is not null, this method delegates its
-     * implementation to the {@code LayerUI.getScrollableTracksViewportWidth(JLayer)}
+     * If the view component of this layer implements {@link Scrollable}, this method delegates its
+     * implementation to the view component.
      *
      * @return whether the layer should track the width of the viewport
      *
      * @see Scrollable
-     * @see LayerUI#getScrollableTracksViewportWidth(JLayer)
      */
     public boolean getScrollableTracksViewportWidth() {
-        if (getUI() != null) {
-            return getUI().getScrollableTracksViewportWidth(this);
+        if (getView() instanceof Scrollable) {
+            return ((Scrollable)getView()).getScrollableTracksViewportWidth();
         }
         return false;
     }
@@ -549,20 +611,19 @@
      * Scrolling containers, like {@code JScrollPane}, will use this method
      * each time the user requests a unit scroll.
      * <p/>
-     * If the ui delegate of this layer is not {@code null}, this method delegates its
-     * implementation to the {@code LayerUI.getScrollableUnitIncrement(JLayer,Rectangle,int,int)}
+     * If the view component of this layer implements {@link Scrollable}, this method delegates its
+     * implementation to the view component.
      *
      * @return The "unit" increment for scrolling in the specified direction.
      *         This value should always be positive.
      *
      * @see Scrollable
-     * @see LayerUI#getScrollableUnitIncrement(JLayer, Rectangle, int, int)
      */
     public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation,
                                           int direction) {
-        if (getUI() != null) {
-            return getUI().getScrollableUnitIncrement(
-                    this, visibleRect, orientation, direction);
+        if (getView() instanceof Scrollable) {
+            return ((Scrollable) getView()).getScrollableUnitIncrement(
+                    visibleRect, orientation, direction);
         }
         return 1;
     }
@@ -595,6 +656,16 @@
     }
 
     /**
+     * Delegates its functionality to the {@link javax.swing.plaf.LayerUI#doLayout(JLayer)} method,
+     * if {@code LayerUI} is set.
+     */
+    public void doLayout() {
+        if (getUI() != null) {
+            getUI().doLayout(this);
+        }
+    }
+
+    /**
      * static AWTEventListener to be shared with all AbstractLayerUIs
      */
     private static class LayerEventController implements AWTEventListener {
@@ -625,8 +696,8 @@
                         JLayer l = (JLayer) component;
                         LayerUI ui = l.getUI();
                         if (ui != null &&
-                                isEventEnabled(l.getLayerEventMask(),
-                                        event.getID())) {
+                                isEventEnabled(l.getLayerEventMask(), event.getID()) &&
+                                (!(event instanceof InputEvent) || !((InputEvent)event).isConsumed())) {
                             ui.eventDispatched(event, l);
                         }
                     }
@@ -758,82 +829,4 @@
             return super.contains(x, y);
         }
     }
-
-    /**
-     * The default layout manager for the {@link javax.swing.JLayer}.<br/>
-     * It places the glassPane on top of the view component
-     * and makes it the same size as {@code JLayer},
-     * it also makes the view component the same size but minus layer's insets<br/>
-     */
-    private static class DefaultLayerLayout implements LayoutManager, Serializable {
-        /**
-         * {@inheritDoc}
-         */
-        public void layoutContainer(Container parent) {
-            JLayer layer = (JLayer) parent;
-            Component view = layer.getView();
-            Component glassPane = layer.getGlassPane();
-            if (view != null) {
-                Insets insets = layer.getInsets();
-                view.setLocation(insets.left, insets.top);
-                view.setSize(layer.getWidth() - insets.left - insets.right,
-                        layer.getHeight() - insets.top - insets.bottom);
-            }
-            if (glassPane != null) {
-                glassPane.setLocation(0, 0);
-                glassPane.setSize(layer.getWidth(), layer.getHeight());
-            }
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public Dimension minimumLayoutSize(Container parent) {
-            JLayer layer = (JLayer) parent;
-            Insets insets = layer.getInsets();
-            Dimension ret = new Dimension(insets.left + insets.right,
-                    insets.top + insets.bottom);
-            Component view = layer.getView();
-            if (view != null) {
-                Dimension size = view.getMinimumSize();
-                ret.width += size.width;
-                ret.height += size.height;
-            }
-            if (ret.width == 0 || ret.height == 0) {
-                ret.width = ret.height = 4;
-            }
-            return ret;
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public Dimension preferredLayoutSize(Container parent) {
-            JLayer layer = (JLayer) parent;
-            Insets insets = layer.getInsets();
-            Dimension ret = new Dimension(insets.left + insets.right,
-                    insets.top + insets.bottom);
-            Component view = layer.getView();
-            if (view != null) {
-                Dimension size = view.getPreferredSize();
-                if (size.width > 0 && size.height > 0) {
-                    ret.width += size.width;
-                    ret.height += size.height;
-                }
-            }
-            return ret;
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public void addLayoutComponent(String name, Component comp) {
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public void removeLayoutComponent(Component comp) {
-        }
-    }
 }
--- a/jdk/src/share/classes/javax/swing/JTable.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/javax/swing/JTable.java	Wed Jul 05 17:24:21 2017 +0200
@@ -4574,9 +4574,8 @@
      * @see TableColumnModelListener
      */
     public void columnMoved(TableColumnModelEvent e) {
-        // If I'm currently editing, then I should stop editing
-        if (isEditing()) {
-            removeEditor();
+        if (isEditing() && !getCellEditor().stopCellEditing()) {
+            getCellEditor().cancelCellEditing();
         }
         repaint();
     }
@@ -4593,8 +4592,8 @@
      * @see TableColumnModelListener
      */
     public void columnMarginChanged(ChangeEvent e) {
-        if (isEditing()) {
-            removeEditor();
+        if (isEditing() && !getCellEditor().stopCellEditing()) {
+            getCellEditor().cancelCellEditing();
         }
         TableColumn resizingColumn = getResizingColumn();
         // Need to do this here, before the parent's
--- a/jdk/src/share/classes/javax/swing/ToolTipManager.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/javax/swing/ToolTipManager.java	Wed Jul 05 17:24:21 2017 +0200
@@ -459,7 +459,7 @@
         if (insideComponent == null) {
             // Drag exit
         }
-        if (window != null && event.getSource() == window) {
+        if (window != null && event.getSource() == window && insideComponent != null) {
           // if we get an exit and have a heavy window
           // we need to check if it if overlapping the inside component
             Container insideComponentWindow = insideComponent.getTopLevelAncestor();
--- a/jdk/src/share/classes/javax/swing/plaf/LayerUI.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/javax/swing/plaf/LayerUI.java	Wed Jul 05 17:24:21 2017 +0200
@@ -600,104 +600,6 @@
     }
 
     /**
-     * Returns the preferred size of the viewport for a view component.
-     *
-     * @param l the {@code JLayer} component where this UI delegate is being installed
-     * @return the preferred size of the viewport for a view component
-     * @see Scrollable#getPreferredScrollableViewportSize()
-     */
-    public Dimension getPreferredScrollableViewportSize(JLayer<? extends V> l) {
-        if (l.getView() instanceof Scrollable) {
-            return ((Scrollable)l.getView()).getPreferredScrollableViewportSize();
-        }
-        return l.getPreferredSize();
-    }
-
-    /**
-     * Returns a scroll increment, which is required for components
-     * that display logical rows or columns in order to completely expose
-     * one block of rows or columns, depending on the value of orientation.
-     *
-     * @param l the {@code JLayer} component where this UI delegate is being installed
-     * @param visibleRect The view area visible within the viewport
-     * @param orientation Either SwingConstants.VERTICAL or SwingConstants.HORIZONTAL.
-     * @param direction Less than zero to scroll up/left, greater than zero for down/right.
-     * @return the "block" increment for scrolling in the specified direction
-     * @see Scrollable#getScrollableBlockIncrement(Rectangle, int, int)
-     */
-     public int getScrollableBlockIncrement(JLayer<? extends V> l,
-                                           Rectangle visibleRect,
-                                           int orientation, int direction) {
-        if (l.getView() instanceof Scrollable) {
-            return ((Scrollable)l.getView()).getScrollableBlockIncrement(
-                    visibleRect,orientation, direction);
-        }
-        return (orientation == SwingConstants.VERTICAL) ? visibleRect.height :
-            visibleRect.width;
-    }
-
-    /**
-     * Returns {@code false} to indicate that the height of the viewport does not
-     * determine the height of the layer, unless the preferred height
-     * of the layer is smaller than the height of the viewport.
-     *
-     * @param l the {@code JLayer} component where this UI delegate is being installed
-     * @return whether the layer should track the height of the viewport
-     * @see Scrollable#getScrollableTracksViewportHeight()
-     */
-    public boolean getScrollableTracksViewportHeight(JLayer<? extends V> l) {
-        if (l.getView() instanceof Scrollable) {
-            return ((Scrollable)l.getView()).getScrollableTracksViewportHeight();
-        }
-        return false;
-    }
-
-    /**
-     * Returns {@code false} to indicate that the width of the viewport does not
-     * determine the width of the layer, unless the preferred width
-     * of the layer is smaller than the width of the viewport.
-     *
-     * @param l the {@code JLayer} component where this UI delegate is being installed
-     * @return whether the layer should track the width of the viewport
-     * @see Scrollable
-     * @see LayerUI#getScrollableTracksViewportWidth(JLayer)
-     */
-    public boolean getScrollableTracksViewportWidth(JLayer<? extends V> l) {
-        if (l.getView() instanceof Scrollable) {
-            return ((Scrollable)l.getView()).getScrollableTracksViewportWidth();
-        }
-        return false;
-    }
-
-    /**
-     * Returns a scroll increment, which is required for components
-     * that display logical rows or columns in order to completely expose
-     * one new row or column, depending on the value of orientation.
-     * Ideally, components should handle a partially exposed row or column
-     * by returning the distance required to completely expose the item.
-     * <p>
-     * Scrolling containers, like JScrollPane, will use this method
-     * each time the user requests a unit scroll.
-     *
-     * @param l the {@code JLayer} component where this UI delegate is being installed
-     * @param visibleRect The view area visible within the viewport
-     * @param orientation Either SwingConstants.VERTICAL or SwingConstants.HORIZONTAL.
-     * @param direction Less than zero to scroll up/left, greater than zero for down/right.
-     * @return The "unit" increment for scrolling in the specified direction.
-     *         This value should always be positive.
-     * @see Scrollable#getScrollableUnitIncrement(Rectangle, int, int)
-     */
-    public int getScrollableUnitIncrement(JLayer<? extends V> l,
-                                          Rectangle visibleRect,
-                                          int orientation, int direction) {
-        if (l.getView() instanceof Scrollable) {
-            return ((Scrollable)l.getView()).getScrollableUnitIncrement(
-                    visibleRect, orientation, direction);
-        }
-        return 1;
-    }
-
-    /**
      * If the {@code JLayer}'s view component is not {@code null},
      * this calls the view's {@code getBaseline()} method.
      * Otherwise, the default implementation is called.
@@ -718,7 +620,7 @@
 
     /**
      * If the {@code JLayer}'s view component is not {@code null},
-     * this calls the view's {@code getBaselineResizeBehavior()} method.
+     * this returns the result of the view's {@code getBaselineResizeBehavior()} method.
      * Otherwise, the default implementation is called.
      *
      * @param c {@code JLayer} to return baseline resize behavior for
@@ -732,4 +634,90 @@
         }
         return super.getBaselineResizeBehavior(c);
     }
+
+    /**
+     * Causes the passed instance of {@code JLayer} to lay out its components.
+     *
+     * @param l the {@code JLayer} component where this UI delegate is being installed
+     */
+    public void doLayout(JLayer<? extends V> l) {
+        Component view = l.getView();
+        if (view != null) {
+            view.setBounds(0, 0, l.getWidth(), l.getHeight());
+        }
+        Component glassPane = l.getGlassPane();
+        if (glassPane != null) {
+            glassPane.setBounds(0, 0, l.getWidth(), l.getHeight());
+        }
+    }
+
+    /**
+     * If the {@code JLayer}'s view component is not {@code null},
+     * this returns the result of  the view's {@code getPreferredSize()} method.
+     * Otherwise, the default implementation is used.
+     *
+     * @param c {@code JLayer} to return preferred size for
+     * @return preferred size for the passed {@code JLayer}
+     */
+    public Dimension getPreferredSize(JComponent c) {
+        JLayer l = (JLayer) c;
+        Component view = l.getView();
+        if (view != null) {
+            return view.getPreferredSize();
+        }
+        return super.getPreferredSize(c);
+    }
+
+    /**
+     * If the {@code JLayer}'s view component is not {@code null},
+     * this returns the result of  the view's {@code getMinimalSize()} method.
+     * Otherwise, the default implementation is used.
+     *
+     * @param c {@code JLayer} to return preferred size for
+     * @return minimal size for the passed {@code JLayer}
+     */
+    public Dimension getMinimumSize(JComponent c) {
+        JLayer l = (JLayer) c;
+        Component view = l.getView();
+        if (view != null) {
+            return view.getMinimumSize();
+        }
+        return super.getMinimumSize(c);
+    }
+
+    /**
+     * If the {@code JLayer}'s view component is not {@code null},
+     * this returns the result of  the view's {@code getMaximumSize()} method.
+     * Otherwise, the default implementation is used.
+     *
+     * @param c {@code JLayer} to return preferred size for
+     * @return maximun size for the passed {@code JLayer}
+     */
+    public Dimension getMaximumSize(JComponent c) {
+        JLayer l = (JLayer) c;
+        Component view = l.getView();
+        if (view != null) {
+            return view.getMaximumSize();
+        }
+        return super.getMaximumSize(c);
+    }
+
+    /**
+     * Adds the specified region to the dirty region list if the component
+     * is showing.  The component will be repainted after all of the
+     * currently pending events have been dispatched.
+     * <p/>
+     * This method is to be overridden when the dirty region needs to be changed.
+     *
+     * @param tm  this parameter is not used
+     * @param x  the x value of the dirty region
+     * @param y  the y value of the dirty region
+     * @param width  the width of the dirty region
+     * @param height  the height of the dirty region
+     * @see java.awt.Component#isShowing
+     * @see RepaintManager#addDirtyRegion
+     */
+    public void repaint(long tm, int x, int y, int width, int height, JLayer<? extends V> l) {
+        RepaintManager.currentManager(l).addDirtyRegion(l, x, y, width, height);
+    }
 }
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1603,6 +1603,7 @@
                 BoundedRangeModel newModel = (BoundedRangeModel)e.getNewValue();
                 oldModel.removeChangeListener(modelListener);
                 newModel.addChangeListener(modelListener);
+                scrollBarValue = scrollbar.getValue();
                 scrollbar.repaint();
                 scrollbar.revalidate();
             } else if ("orientation" == propertyName) {
--- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalComboBoxUI.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalComboBoxUI.java	Wed Jul 05 17:24:21 2017 +0200
@@ -144,7 +144,7 @@
      */
     public int getBaseline(JComponent c, int width, int height) {
         int baseline;
-        if (MetalLookAndFeel.usingOcean()) {
+        if (MetalLookAndFeel.usingOcean() && height >= 4) {
             height -= 4;
             baseline = super.getBaseline(c, width, height);
             if (baseline >= 0) {
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java	Wed Jul 05 17:24:21 2017 +0200
@@ -115,6 +115,9 @@
         return new SynthTabbedPaneUI();
     }
 
+    private SynthTabbedPaneUI() {
+    }
+
     private boolean scrollableTabLayoutEnabled() {
         return (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT);
     }
--- a/jdk/src/share/classes/sun/awt/AWTAccessor.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/sun/awt/AWTAccessor.java	Wed Jul 05 17:24:21 2017 +0200
@@ -344,6 +344,11 @@
          * Removes the last focus request for the heavyweight from the queue.
          */
         void removeLastFocusRequest(Component heavyweight);
+
+        /*
+         * Sets the most recent focus owner in the window.
+         */
+        void setMostRecentFocusOwner(Window window, Component component);
     }
 
     /*
--- a/jdk/src/share/classes/sun/awt/EmbeddedFrame.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/sun/awt/EmbeddedFrame.java	Wed Jul 05 17:24:21 2017 +0200
@@ -70,7 +70,10 @@
     // JDK 1.1 compatibility
     private static final long serialVersionUID = 2967042741780317130L;
 
-    // Use these in traverseOut method to determine directions
+    /*
+     * The constants define focus traversal directions.
+     * Use them in {@code traverseIn}, {@code traverseOut} methods.
+     */
     protected static final boolean FORWARD = true;
     protected static final boolean BACKWARD = false;
 
@@ -284,6 +287,41 @@
     }
 
     /**
+     * This method is called by the embedder when we should receive focus as element
+     * of the traversal chain.  The method requests focus on:
+     * 1. the first Component of this EmbeddedFrame if user moves focus forward
+     *    in the focus traversal cycle.
+     * 2. the last Component of this EmbeddedFrame if user moves focus backward
+     *    in the focus traversal cycle.
+     *
+     * The direction parameter specifies which of the two mentioned cases is
+     * happening. Use FORWARD and BACKWARD constants defined in the EmbeddedFrame class
+     * to avoid confusing boolean values.
+     *
+     * A concrete implementation of this method is defined in the platform-dependent
+     * subclasses.
+     *
+     * @param direction FORWARD or BACKWARD
+     * @return true, if the EmbeddedFrame wants to get focus, false otherwise.
+     */
+    public boolean traverseIn(boolean direction) {
+        Component comp = null;
+
+        if (direction == FORWARD) {
+            comp = getFocusTraversalPolicy().getFirstComponent(this);
+        } else {
+            comp = getFocusTraversalPolicy().getLastComponent(this);
+        }
+        if (comp != null) {
+            // comp.requestFocus(); - Leads to a hung.
+
+            AWTAccessor.getKeyboardFocusManagerAccessor().setMostRecentFocusOwner(this, comp);
+            synthesizeWindowActivation(true);
+        }
+        return (null != comp);
+    }
+
+    /**
      * This method is called from dispatchKeyEvent in the following two cases:
      * 1. The focus is on the first Component of this EmbeddedFrame and we are
      *    about to transfer the focus backward.
--- a/jdk/src/share/classes/sun/net/www/http/HttpClient.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/sun/net/www/http/HttpClient.java	Wed Jul 05 17:24:21 2017 +0200
@@ -55,6 +55,9 @@
     // Http data we send with the headers
     PosterOutputStream poster = null;
 
+    // true if we are in streaming mode (fixed length or chunked)
+    boolean streaming;
+
     // if we've had one io error
     boolean failedOnce = false;
 
@@ -275,6 +278,10 @@
                         ret.cachedHttpClient = true;
                         assert ret.inCache;
                         ret.inCache = false;
+                        PlatformLogger logger = HttpURLConnection.getHttpLogger();
+                        if (logger.isLoggable(PlatformLogger.FINEST)) {
+                            logger.finest("KeepAlive stream retrieved from the cache, " + ret);
+                        }
                     }
                 } else {
                     // We cannot return this connection to the cache as it's
@@ -545,6 +552,13 @@
         serverOutput.flush();
     }
 
+    public void writeRequests(MessageHeader head,
+                              PosterOutputStream pos,
+                              boolean streaming) throws IOException {
+        this.streaming = streaming;
+        writeRequests(head, pos);
+    }
+
     /** Parse the first line of the HTTP request.  It usually looks
         something like: "HTTP/1.0 <number> comment\r\n". */
 
@@ -577,11 +591,11 @@
             closeServer();
             cachedHttpClient = false;
             if (!failedOnce && requests != null) {
-                if (httpuc.getRequestMethod().equals("POST") && !retryPostProp) {
+                failedOnce = true;
+                if (httpuc.getRequestMethod().equals("POST") && (!retryPostProp || streaming)) {
                     // do not retry the request
                 }  else {
                     // try once more
-                    failedOnce = true;
                     openServer();
                     if (needsTunneling()) {
                         httpuc.doTunneling();
@@ -684,10 +698,10 @@
                 }
             } else if (nread != 8) {
                 if (!failedOnce && requests != null) {
-                    if (httpuc.getRequestMethod().equals("POST") && !retryPostProp) {
+                    failedOnce = true;
+                    if (httpuc.getRequestMethod().equals("POST") && (!retryPostProp || streaming)) {
                         // do not retry the request
                     } else {
-                        failedOnce = true;
                         closeServer();
                         cachedHttpClient = false;
                         openServer();
--- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Wed Jul 05 17:24:21 2017 +0200
@@ -494,7 +494,7 @@
         if (logger.isLoggable(PlatformLogger.FINE)) {
             logger.fine(requests.toString());
         }
-        http.writeRequests(requests, poster);
+        http.writeRequests(requests, poster, streaming());
         if (ps.checkError()) {
             String proxyHost = http.getProxyHostUsed();
             int proxyPort = http.getProxyPortUsed();
@@ -2825,6 +2825,38 @@
             }
         }
 
+        /* skip() calls read() in order to ensure that entire response gets
+         * cached. same implementation as InputStream.skip */
+
+        private byte[] skipBuffer;
+        private static final int SKIP_BUFFER_SIZE = 8096;
+
+        @Override
+        public long skip (long n) throws IOException {
+
+            long remaining = n;
+            int nr;
+            if (skipBuffer == null)
+                skipBuffer = new byte[SKIP_BUFFER_SIZE];
+
+            byte[] localSkipBuffer = skipBuffer;
+
+            if (n <= 0) {
+                return 0;
+            }
+
+            while (remaining > 0) {
+                nr = read(localSkipBuffer, 0,
+                          (int) Math.min(SKIP_BUFFER_SIZE, remaining));
+                if (nr < 0) {
+                    break;
+                }
+                remaining -= nr;
+            }
+
+            return n - remaining;
+        }
+
         @Override
         public void close () throws IOException {
             try {
--- a/jdk/src/share/classes/sun/security/tools/KeyTool.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/sun/security/tools/KeyTool.java	Wed Jul 05 17:24:21 2017 +0200
@@ -281,7 +281,7 @@
         RFC("rfc", null, "output in RFC style"),
         SIGALG("sigalg", "<sigalg>", "signature algorithm name"),
         SRCALIAS("srcalias", "<srcalias>", "source alias"),
-        SRCKEYPASS("srckeypass", "<arg>", "source keystore password"),
+        SRCKEYPASS("srckeypass", "<arg>", "source key password"),
         SRCKEYSTORE("srckeystore", "<srckeystore>", "source keystore name"),
         SRCPROTECTED("srcprotected", null, "source keystore password protected"),
         SRCPROVIDERNAME("srcprovidername", "<srcprovidername>", "source keystore provider name"),
--- a/jdk/src/share/classes/sun/security/util/Resources.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/sun/security/util/Resources.java	Wed Jul 05 17:24:21 2017 +0200
@@ -116,11 +116,9 @@
         {"X.509 extension",
                 "X.509 extension"}, //-ext
         {"output file name",
-                "output file name"}, //-file
+                "output file name"}, //-file and -outfile
         {"input file name",
-                "input file name"}, //-file
-        {"input file name",
-                "input file name"}, //-infile
+                "input file name"}, //-file and -infile
         {"key algorithm name",
                 "key algorithm name"}, //-keyalg
         {"key password",
@@ -133,8 +131,6 @@
                 "new password"}, //-new
         {"do not prompt",
                 "do not prompt"}, //-noprompt
-        {"output file name",
-                "output file name"}, //-outfile
         {"password through protected mechanism",
                 "password through protected mechanism"}, //-protected
         {"provider argument",
@@ -151,8 +147,8 @@
                 "signature algorithm name"}, //-sigalg
         {"source alias",
                 "source alias"}, //-srcalias
-        {"source keystore password",
-                "source keystore password"}, //-srckeypass
+        {"source key password",
+                "source key password"}, //-srckeypass
         {"source keystore name",
                 "source keystore name"}, //-srckeystore
         {"source keystore password protected",
@@ -276,8 +272,6 @@
                 "Alias <{0}> has no certificate"},
         {"Key pair not generated, alias <alias> already exists",
                 "Key pair not generated, alias <{0}> already exists"},
-        {"Cannot derive signature algorithm",
-                "Cannot derive signature algorithm"},
         {"Generating keysize bit keyAlgName key pair and self-signed certificate (sigAlgName) with a validity of validality days\n\tfor: x500Name",
                 "Generating {0} bit {1} key pair and self-signed certificate ({2}) with a validity of {3} days\n\tfor: {4}"},
         {"Enter key password for <alias>", "Enter key password for <{0}>"},
@@ -321,8 +315,6 @@
         {"Failed to parse input", "Failed to parse input"},
         {"Empty input", "Empty input"},
         {"Not X.509 certificate", "Not X.509 certificate"},
-        {"Cannot derive signature algorithm",
-                "Cannot derive signature algorithm"},
         {"alias has no public key", "{0} has no public key"},
         {"alias has no X.509 certificate", "{0} has no X.509 certificate"},
         {"New certificate (self-signed):", "New certificate (self-signed):"},
@@ -552,7 +544,6 @@
         {"package name", "package name"},
         {"policy type", "policy type"},
         {"property name", "property name"},
-        {"provider name", "provider name"},
         {"Principal List", "Principal List"},
         {"Permission List", "Permission List"},
         {"Code Base", "Code Base"},
--- a/jdk/src/share/classes/sun/util/locale/BaseLocale.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/classes/sun/util/locale/BaseLocale.java	Wed Jul 05 17:24:21 2017 +0200
@@ -64,12 +64,14 @@
 
     public static BaseLocale getInstance(String language, String script, String region, String variant) {
         // JDK uses deprecated ISO639.1 language codes for he, yi and id
-        if (AsciiUtil.caseIgnoreMatch(language, "he")) {
-            language = "iw";
-        } else if (AsciiUtil.caseIgnoreMatch(language, "yi")) {
-            language = "ji";
-        } else if (AsciiUtil.caseIgnoreMatch(language, "id")) {
-            language = "in";
+        if (language != null) {
+            if (AsciiUtil.caseIgnoreMatch(language, "he")) {
+                language = "iw";
+            } else if (AsciiUtil.caseIgnoreMatch(language, "yi")) {
+                language = "ji";
+            } else if (AsciiUtil.caseIgnoreMatch(language, "id")) {
+                language = "in";
+            }
         }
 
         Key key = new Key(language, script, region, variant);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/Demo.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,664 @@
+/*
+ * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.io.*;
+import java.nio.*;
+import java.nio.channels.*;
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.net.*;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+import static java.nio.file.StandardOpenOption.*;
+import static java.nio.file.StandardCopyOption.*;
+
+/*
+ * ZipFileSystem usage demo
+ *
+ * java [-cp .../zipfs.jar:./] Demo action ZipfileName [...]
+ *
+ * To deploy the provider, either copy the zipfs.jar into JDK/JRE
+ * extensions directory or add
+ *      <JDK_HOME>/demo/nio/ZipFileSystem/zipfs.jar
+ * into your class path as showed above.
+ *
+ * @author Xueming Shen
+ */
+
+public class Demo {
+
+    static enum Action {
+        rename,          // <java Demo rename zipfile src dst>
+                         // rename entry src to dst inside zipfile
+
+        movein,          // <java Demo movein zipfile src dst>
+                         // move an external src file into zipfile
+                         // as entry dst
+
+        moveout,         // <java Demo moveout zipfile src dst>
+                         // move a zipfile entry src out to dst
+
+        copy,            // <java Demo copy zipfile src dst>
+                         // copy entry src to dst inside zipfile
+
+        copyin,          // <java Demo copyin zipfile src dst>
+                         // copy an external src file into zipfile
+                         // as entry dst
+
+        copyout,         // <java Demo copyout zipfile src dst>
+                         // copy zipfile entry src" out to file dst
+
+        zzmove,          // <java Demo zzmove zfsrc zfdst path>
+                         // move entry path/dir from zfsrc to zfdst
+
+        zzcopy,          // <java Demo zzcopy zfsrc zfdst path>
+                         // copy path from zipfile zfsrc to zipfile
+                         // zfdst
+
+        attrs,           // <java Demo attrs zipfile path>
+                         // printout the attributes of entry path
+
+        attrsspace,      // <java Demo attrsspace zipfile path>
+                         // printout the storespace attrs of entry path
+
+        setmtime,        // <java Demo setmtime zipfile "MM/dd/yy-HH:mm:ss" path...>
+                         // set the lastModifiedTime of entry path
+
+        lsdir,           // <java Demo lsdir zipfile dir>
+                         // list dir's direct child files/dirs
+
+        mkdir,           // <java Demo mkdir zipfile dir>
+
+        mkdirs,          // <java Demo mkdirs zipfile dir>
+
+        rmdirs,          // <java Demo rmdirs zipfile dir>
+
+        list,            // <java Demo list zipfile [dir]>
+                         // recursively list all entries of dir
+                         // via DirectoryStream
+
+        tlist,           // <java Demo tlist zipfile [dir]>
+                         // list with buildDirTree=true
+
+        vlist,           // <java Demo vlist zipfile [dir]>
+                         // recursively verbose list all entries of
+                         // dir via DirectoryStream
+
+        walk,            // <java Demo walk zipfile [dir]>
+                         // recursively walk all entries of dir
+                         // via Files.walkFileTree
+
+        twalk,           // <java Demo twalk zipfile [dir]>
+                         // walk with buildDirTree=true
+
+        extract,         // <java Demo extract zipfile file [...]>
+
+        update,          // <java Demo extract zipfile file [...]>
+
+        delete,          // <java Demo delete zipfile file [...]>
+
+        add,             // <java Demo add zipfile file [...]>
+
+        create,          // <java Demo create zipfile file [...]>
+                         // create a new zipfile if it doesn't exit
+                         // and then add the file(s) into it.
+
+        attrs2,          // <java Demo attrs2 zipfile file [...]>
+                         // test different ways to print attrs
+    }
+
+    public static void main(String[] args) throws Throwable {
+
+        Action action = Action.valueOf(args[0]);;
+        Map<String, Object> env = env = new HashMap<String, Object>();
+        if (action == Action.create)
+            env.put("createNew", true);
+        if (action == Action.tlist || action == Action.twalk)
+            env.put("buildDirTree", true);
+
+        FileSystem fs = FileSystems.newFileSystem(
+                            URI.create("zip" + Paths.get(args[1]).toUri().toString().substring(4)),
+                            env,
+                            null);
+        try {
+            FileSystem fs2;
+            Path path, src, dst;
+            boolean isRename = false;
+            switch (action) {
+            case rename:
+                src = fs.getPath(args[2]);
+                dst = fs.getPath(args[3]);
+                src.moveTo(dst);
+                break;
+            case moveout:
+                src = fs.getPath(args[2]);
+                dst = Paths.get(args[3]);
+                src.moveTo(dst);
+                break;
+            case movein:
+                src = Paths.get(args[2]);
+                dst = fs.getPath(args[3]);
+                src.moveTo(dst);
+                break;
+            case copy:
+                src = fs.getPath(args[2]);
+                dst = fs.getPath(args[3]);
+                src.copyTo(dst);
+                break;
+            case copyout:
+                src = fs.getPath(args[2]);
+                dst = Paths.get(args[3]);
+                src.copyTo(dst);
+                break;
+            case copyin:
+                src = Paths.get(args[2]);
+                dst = fs.getPath(args[3]);
+                src.copyTo(dst);
+                break;
+            case zzmove:
+                fs2 = FileSystems.newFileSystem(
+                    URI.create("zip" + Paths.get(args[2]).toUri().toString().substring(4)),
+                    env,
+                    null);
+                //sf1.getPath(args[3]).moveTo(fs2.getPath(args[3]));
+                z2zmove(fs, fs2, args[3]);
+                fs2.close();
+                break;
+            case zzcopy:
+                fs2 = FileSystems.newFileSystem(
+                    URI.create("zip" + Paths.get(args[2]).toUri().toString().substring(4)),
+                    env,
+                    null);
+                //sf1.getPath(args[3]).copyTo(fs2.getPath(args[3]));
+                z2zcopy(fs, fs2, args[3]);
+                fs2.close();
+                break;
+            case attrs:
+                for (int i = 2; i < args.length; i++) {
+                    path = fs.getPath(args[i]);
+                    System.out.println(
+                        Attributes.readBasicFileAttributes(path).toString());
+                }
+                break;
+            case setmtime:
+                DateFormat df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss");
+                Date newDatetime = df.parse(args[2]);
+                for (int i = 3; i < args.length; i++) {
+                    path = fs.getPath(args[i]);
+                    path.setAttribute("lastModifiedTime",
+                                      FileTime.fromMillis(newDatetime.getTime()));
+                    System.out.println(
+                        Attributes.readBasicFileAttributes(path).toString());
+                }
+                break;
+            case attrsspace:
+                path = fs.getPath("/");
+                FileStore fstore = path.getFileStore();
+                //System.out.println(fstore.getFileStoreAttributeView(FileStoreSpaceAttributeView.class)
+                //                         .readAttributes());
+                // or
+                System.out.printf("filestore[%s]%n", fstore.name());
+                System.out.printf("    totalSpace: %d%n",
+                                  (Long)fstore.getAttribute("space:totalSpace"));
+                System.out.printf("   usableSpace: %d%n",
+                                  (Long)fstore.getAttribute("space:usableSpace"));
+                System.out.printf("  unallocSpace: %d%n",
+                                  (Long)fstore.getAttribute("space:unallocatedSpace"));
+                break;
+            case list:
+            case tlist:
+                if (args.length < 3)
+                    list(fs.getPath("/"), false);
+                else
+                    list(fs.getPath(args[2]), false);
+                break;
+            case vlist:
+                if (args.length < 3)
+                    list(fs.getPath("/"), true);
+                else
+                    list(fs.getPath(args[2]), true);
+                break;
+            case twalk:
+            case walk:
+                walk(fs.getPath((args.length > 2)? args[2] : "/"));
+                break;
+            case extract:
+                if (args.length == 2) {
+                     extract(fs, "/");
+                } else {
+                    for (int i = 2; i < args.length; i++) {
+                        extract(fs, args[i]);
+                    }
+                }
+                break;
+            case delete:
+                for (int i = 2; i < args.length; i++)
+                    fs.getPath(args[i]).delete();
+                break;
+            case create:
+            case add:
+            case update:
+                for (int i = 2; i < args.length; i++) {
+                    update(fs, args[i]);
+                }
+                break;
+            case lsdir:
+                path = fs.getPath(args[2]);
+                final String fStr = (args.length > 3)?args[3]:"";
+                DirectoryStream<Path> ds = path.newDirectoryStream(
+                    new DirectoryStream.Filter<Path>() {
+                        public boolean accept(Path path) {
+                            return path.toString().contains(fStr);
+                        }
+                    });
+                for (Path p : ds)
+                    System.out.println(p);
+                break;
+            case mkdir:
+                fs.getPath(args[2]).createDirectory();
+                break;
+            case mkdirs:
+                mkdirs(fs.getPath(args[2]));
+                break;
+            case attrs2:
+                for (int i = 2; i < args.length; i++) {
+                    path = fs.getPath(args[i]);
+                    System.out.println("-------(1)---------");
+                    System.out.println(
+                        Attributes.readBasicFileAttributes(path).toString());
+                    System.out.println("-------(2)---------");
+                    Map<String, ?> map = path.readAttributes("zip:*");
+                    for (Map.Entry<String, ?> e : map.entrySet()) {
+                        System.out.printf("    %s : %s%n", e.getKey(), e.getValue());
+                    }
+                    System.out.println("-------(3)---------");
+                    map = path.readAttributes("size,lastModifiedTime,isDirectory");
+                    for (Map.Entry<String, ?> e : map.entrySet()) {
+                        System.out.printf("    %s : %s%n", e.getKey(), e.getValue());
+                    }
+                }
+                break;
+            }
+        } catch (Exception x) {
+            x.printStackTrace();
+        } finally {
+            if (fs != null)
+                fs.close();
+        }
+    }
+
+    private static byte[] getBytes(String name) {
+        return name.getBytes();
+    }
+
+    private static String getString(byte[] name) {
+        return new String(name);
+    }
+
+    private static void walk(Path path) throws IOException
+    {
+        Files.walkFileTree(
+            path,
+            new SimpleFileVisitor<Path>() {
+                private int indent = 0;
+                private void indent() {
+                    int n = 0;
+                    while (n++ < indent)
+                        System.out.printf(" ");
+                }
+
+                @Override
+                public FileVisitResult visitFile(Path file,
+                                                 BasicFileAttributes attrs)
+                {
+                    indent();
+                    System.out.printf("%s%n", file.getName().toString());
+                    return FileVisitResult.CONTINUE;
+                }
+
+                @Override
+                public FileVisitResult preVisitDirectory(Path dir,
+                                                         BasicFileAttributes attrs)
+                {
+                    indent();
+                    System.out.printf("[%s]%n", dir.toString());
+                    indent += 2;
+                    return FileVisitResult.CONTINUE;
+                }
+
+                @Override
+                public FileVisitResult postVisitDirectory(Path dir,
+                                                          IOException ioe)
+                {
+                    indent -= 2;
+                    return FileVisitResult.CONTINUE;
+                }
+        });
+    }
+
+    private static void update(FileSystem fs, String path) throws Throwable{
+        Path src = FileSystems.getDefault().getPath(path);
+        if (Boolean.TRUE.equals(src.getAttribute("isDirectory"))) {
+            DirectoryStream<Path> ds = src.newDirectoryStream();
+            for (Path child : ds)
+                update(fs, child.toString());
+            ds.close();
+        } else {
+            Path dst = fs.getPath(path);
+            Path parent = dst.getParent();
+            if (parent != null && parent.notExists())
+                mkdirs(parent);
+            src.copyTo(dst, REPLACE_EXISTING);
+        }
+    }
+
+    private static void extract(FileSystem fs, String path) throws Throwable{
+        Path src = fs.getPath(path);
+        if (Boolean.TRUE.equals(src.getAttribute("isDirectory"))) {
+            DirectoryStream<Path> ds = src.newDirectoryStream();
+            for (Path child : ds)
+                extract(fs, child.toString());
+            ds.close();
+        } else {
+            if (path.startsWith("/"))
+                path = path.substring(1);
+            Path dst = FileSystems.getDefault().getPath(path);
+            Path parent = dst.getParent();
+            if (parent.notExists())
+                mkdirs(parent);
+            src.copyTo(dst, REPLACE_EXISTING);
+        }
+    }
+
+    // use DirectoryStream
+    private static void z2zcopy(FileSystem src, FileSystem dst, String path)
+        throws IOException
+    {
+        Path srcPath = src.getPath(path);
+        Path dstPath = dst.getPath(path);
+
+        if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) {
+            if (!dstPath.exists()) {
+                try {
+                    mkdirs(dstPath);
+                } catch (FileAlreadyExistsException x) {}
+            }
+            DirectoryStream<Path> ds = srcPath.newDirectoryStream();
+            for (Path child : ds) {
+                z2zcopy(src, dst,
+                        path + (path.endsWith("/")?"":"/") + child.getName());
+            }
+            ds.close();
+        } else {
+            //System.out.println("copying..." + path);
+            srcPath.copyTo(dstPath);
+        }
+    }
+
+    // use TreeWalk to move
+    private static void z2zmove(FileSystem src, FileSystem dst, String path)
+        throws IOException
+    {
+        final Path srcPath = src.getPath(path).toAbsolutePath();
+        final Path dstPath = dst.getPath(path).toAbsolutePath();
+
+        Files.walkFileTree(srcPath, new SimpleFileVisitor<Path>() {
+
+            @Override
+            public FileVisitResult visitFile(Path file,
+                                            BasicFileAttributes attrs)
+            {
+                Path dst = srcPath.relativize(file);
+                dst = dstPath.resolve(dst);
+                try {
+                    Path parent = dstPath.getParent();
+                    if (parent != null && parent.notExists())
+                        mkdirs(parent);
+                    file.moveTo(dst);
+                } catch (IOException x) {
+                    x.printStackTrace();
+                }
+                return FileVisitResult.CONTINUE;
+            }
+
+            @Override
+            public FileVisitResult preVisitDirectory(Path dir,
+                                                     BasicFileAttributes attrs)
+            {
+                Path dst = srcPath.relativize(dir);
+                dst = dstPath.resolve(dst);
+                try {
+
+                    if (dst.notExists())
+                        mkdirs(dst);
+                } catch (IOException x) {
+                    x.printStackTrace();
+                }
+                return FileVisitResult.CONTINUE;
+            }
+
+            @Override
+            public FileVisitResult postVisitDirectory(Path dir,
+                                                      IOException ioe)
+                throws IOException
+            {
+                try {
+                    dir.delete();
+                } catch (IOException x) {
+                    //x.printStackTrace();
+                }
+                return FileVisitResult.CONTINUE;
+            }
+        });
+
+    }
+
+    private static void mkdirs(Path path) throws IOException {
+        path = path.toAbsolutePath();
+        Path parent = path.getParent();
+        if (parent != null) {
+            if (parent.notExists())
+                mkdirs(parent);
+        }
+        path.createDirectory();
+    }
+
+    private static void rmdirs(Path path) throws IOException {
+        while (path != null && path.getNameCount() != 0) {
+            path.delete();
+            path = path.getParent();
+        }
+    }
+
+    private static void list(Path path, boolean verbose ) throws IOException {
+        if (verbose)
+            System.out.println(Attributes.readBasicFileAttributes(path).toString());
+        else
+            System.out.printf("  %s%n", path.toString());
+        if (path.notExists())
+            return;
+        if (Attributes.readBasicFileAttributes(path).isDirectory()) {
+            DirectoryStream<Path> ds = path.newDirectoryStream();
+            for (Path child : ds)
+                list(child, verbose);
+            ds.close();
+        }
+    }
+
+    // check the content of two paths are equal
+    private static void checkEqual(Path src, Path dst) throws IOException
+    {
+        //System.out.printf("checking <%s> vs <%s>...%n",
+        //                  src.toString(), dst.toString());
+
+        //streams
+        InputStream isSrc = src.newInputStream();
+        InputStream isDst = dst.newInputStream();
+        byte[] bufSrc = new byte[8192];
+        byte[] bufDst = new byte[8192];
+
+        try {
+            int nSrc = 0;
+            while ((nSrc = isSrc.read(bufSrc)) != -1) {
+                int nDst = 0;
+                while (nDst < nSrc) {
+                    int n = isDst.read(bufDst, nDst, nSrc - nDst);
+                    if (n == -1) {
+                        System.out.printf("checking <%s> vs <%s>...%n",
+                                          src.toString(), dst.toString());
+                        throw new RuntimeException("CHECK FAILED!");
+                    }
+                    nDst += n;
+                }
+                while (--nSrc >= 0) {
+                    if (bufSrc[nSrc] != bufDst[nSrc]) {
+                        System.out.printf("checking <%s> vs <%s>...%n",
+                                          src.toString(), dst.toString());
+                        throw new RuntimeException("CHECK FAILED!");
+                    }
+                    nSrc--;
+                }
+            }
+        } finally {
+            isSrc.close();
+            isDst.close();
+        }
+
+        // channels
+        SeekableByteChannel chSrc = src.newByteChannel();
+        SeekableByteChannel chDst = dst.newByteChannel();
+        if (chSrc.size() != chDst.size()) {
+            System.out.printf("src[%s].size=%d, dst[%s].size=%d%n",
+                              chSrc.toString(), chSrc.size(),
+                              chDst.toString(), chDst.size());
+            throw new RuntimeException("CHECK FAILED!");
+        }
+        ByteBuffer bbSrc = ByteBuffer.allocate(8192);
+        ByteBuffer bbDst = ByteBuffer.allocate(8192);
+
+        try {
+            int nSrc = 0;
+            while ((nSrc = chSrc.read(bbSrc)) != -1) {
+                int nDst = chDst.read(bbDst);
+                if (nSrc != nDst) {
+                    System.out.printf("checking <%s> vs <%s>...%n",
+                                      src.toString(), dst.toString());
+                    throw new RuntimeException("CHECK FAILED!");
+                }
+                while (--nSrc >= 0) {
+                    if (bbSrc.get(nSrc) != bbDst.get(nSrc)) {
+                        System.out.printf("checking <%s> vs <%s>...%n",
+                                          src.toString(), dst.toString());
+                        throw new RuntimeException("CHECK FAILED!");
+                    }
+                    nSrc--;
+                }
+                bbSrc.flip();
+                bbDst.flip();
+            }
+        } catch (IOException x) {
+            x.printStackTrace();
+        } finally {
+            chSrc.close();
+            chDst.close();
+        }
+    }
+
+    private static void fchCopy(Path src, Path dst) throws IOException
+    {
+        Set<OpenOption> read = new HashSet<>();
+        read.add(READ);
+        Set<OpenOption> openwrite = new HashSet<>();
+        openwrite.add(CREATE_NEW);
+        openwrite.add(WRITE);
+
+        FileChannel srcFc = src.getFileSystem()
+                               .provider()
+                               .newFileChannel(src, read);
+        FileChannel dstFc = dst.getFileSystem()
+                               .provider()
+                               .newFileChannel(dst, openwrite);
+
+        try {
+            ByteBuffer bb = ByteBuffer.allocate(8192);
+            while (srcFc.read(bb) >= 0) {
+                bb.flip();
+                dstFc.write(bb);
+                bb.clear();
+            }
+        } finally {
+            srcFc.close();
+            dstFc.close();
+        }
+    }
+
+    private static void chCopy(Path src, Path dst) throws IOException
+    {
+        Set<OpenOption> read = new HashSet<>();
+        read.add(READ);
+        Set<OpenOption> openwrite = new HashSet<>();
+        openwrite.add(CREATE_NEW);
+        openwrite.add(WRITE);
+
+        SeekableByteChannel srcCh = src.newByteChannel(read);
+        SeekableByteChannel dstCh = dst.newByteChannel(openwrite);
+
+        try {
+            ByteBuffer bb = ByteBuffer.allocate(8192);
+            while (srcCh.read(bb) >= 0) {
+                bb.flip();
+                dstCh.write(bb);
+                bb.clear();
+            }
+        } finally {
+            srcCh.close();
+            dstCh.close();
+        }
+    }
+
+    private static void streamCopy(Path src, Path dst) throws IOException
+    {
+        InputStream isSrc = src.newInputStream();
+        OutputStream osDst = dst.newOutputStream();
+        byte[] buf = new byte[8192];
+        try {
+            int n = 0;
+            while ((n = isSrc.read(buf)) != -1) {
+                osDst.write(buf, 0, n);
+            }
+        } finally {
+            isSrc.close();
+            osDst.close();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/META-INF/services/java.nio.file.spi.FileSystemProvider	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,3 @@
+com.sun.nio.zipfs.ZipFileSystemProvider
+com.sun.nio.zipfs.JarFileSystemProvider
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/README.txt	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,29 @@
+ZipFileSystem is a file system provider that treats the contents of a zip or
+JAR file as a java.nio.file.FileSystem.
+
+To deploy the provider you must copy zipfs.jar into your extensions
+directory or else add <JDK_HOME>/demo/nio/ZipFileSystem/zipfs.jar
+to your class path.
+
+The factory methods defined by the java.nio.file.FileSystems class can be
+used to create a FileSystem, eg:
+
+   // use file type detection
+   Map<String,?> env = Collections.emptyMap();
+   Path jarfile = Path.get("foo.jar");
+   FileSystem fs = FileSystems.newFileSystem(jarfile, env);
+
+-or
+
+   // locate file system by URI
+   Map<String,?> env = Collections.emptyMap();
+   URI uri = URI.create("zip:///mydir/foo.jar");
+   FileSystem fs = FileSystems.newFileSystem(uri, env);
+
+Once a FileSystem is created then classes in the java.nio.file package
+can be used to access files in the zip/JAR file, eg:
+
+   Path mf = fs.getPath("/META-INF/MANIFEST.MF");
+   InputStream in = mf.newInputStream();
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/JarFileSystemProvider.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Sun Microsystems nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.sun.nio.zipfs;
+
+import java.nio.file.*;
+import java.nio.file.spi.*;
+import java.nio.file.attribute.*;
+import java.nio.file.spi.FileSystemProvider;
+
+import java.net.URI;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.nio.channels.FileChannel;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+public class JarFileSystemProvider extends ZipFileSystemProvider
+{
+
+    @Override
+    public String getScheme() {
+        return "jar";
+    }
+
+    @Override
+    protected Path uriToPath(URI uri) {
+        String scheme = uri.getScheme();
+        if ((scheme == null) || !scheme.equalsIgnoreCase(getScheme())) {
+            throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'");
+        }
+        try {
+            String uristr = uri.toString();
+            int end = uristr.indexOf("!/");
+            uristr = uristr.substring(4, (end == -1) ? uristr.length() : end);
+            uri = new URI(uristr);
+            return Paths.get(new URI("file", uri.getHost(), uri.getPath(), null))
+                        .toAbsolutePath();
+        } catch (URISyntaxException e) {
+            throw new AssertionError(e); //never thrown
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipCoder.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
+import java.util.Arrays;
+
+/**
+ * Utility class for zipfile name and comment decoding and encoding
+ *
+ * @author  Xueming Shen
+ */
+
+final class ZipCoder {
+
+    String toString(byte[] ba, int length) {
+        CharsetDecoder cd = decoder().reset();
+        int len = (int)(length * cd.maxCharsPerByte());
+        char[] ca = new char[len];
+        if (len == 0)
+            return new String(ca);
+        ByteBuffer bb = ByteBuffer.wrap(ba, 0, length);
+        CharBuffer cb = CharBuffer.wrap(ca);
+        CoderResult cr = cd.decode(bb, cb, true);
+        if (!cr.isUnderflow())
+            throw new IllegalArgumentException(cr.toString());
+        cr = cd.flush(cb);
+        if (!cr.isUnderflow())
+            throw new IllegalArgumentException(cr.toString());
+        return new String(ca, 0, cb.position());
+    }
+
+    String toString(byte[] ba) {
+        return toString(ba, ba.length);
+    }
+
+    byte[] getBytes(String s) {
+        CharsetEncoder ce = encoder().reset();
+        char[] ca = s.toCharArray();
+        int len = (int)(ca.length * ce.maxBytesPerChar());
+        byte[] ba = new byte[len];
+        if (len == 0)
+            return ba;
+        ByteBuffer bb = ByteBuffer.wrap(ba);
+        CharBuffer cb = CharBuffer.wrap(ca);
+        CoderResult cr = ce.encode(cb, bb, true);
+        if (!cr.isUnderflow())
+            throw new IllegalArgumentException(cr.toString());
+        cr = ce.flush(bb);
+        if (!cr.isUnderflow())
+            throw new IllegalArgumentException(cr.toString());
+        if (bb.position() == ba.length)  // defensive copy?
+            return ba;
+        else
+            return Arrays.copyOf(ba, bb.position());
+    }
+
+    // assume invoked only if "this" is not utf8
+    byte[] getBytesUTF8(String s) {
+        if (isutf8)
+            return getBytes(s);
+        if (utf8 == null)
+            utf8 = new ZipCoder(Charset.forName("UTF-8"));
+        return utf8.getBytes(s);
+    }
+
+    String toStringUTF8(byte[] ba, int len) {
+        if (isutf8)
+            return toString(ba, len);
+        if (utf8 == null)
+            utf8 = new ZipCoder(Charset.forName("UTF-8"));
+        return utf8.toString(ba, len);
+    }
+
+    boolean isUTF8() {
+        return isutf8;
+    }
+
+    private Charset cs;
+    private boolean isutf8;
+    private ZipCoder utf8;
+
+    private ZipCoder(Charset cs) {
+        this.cs = cs;
+        this.isutf8 = cs.name().equals("UTF-8");
+    }
+
+    static ZipCoder get(Charset charset) {
+        return new ZipCoder(charset);
+    }
+
+    static ZipCoder get(String csn) {
+        try {
+            return new ZipCoder(Charset.forName(csn));
+        } catch (Throwable t) {
+            t.printStackTrace();
+        }
+        return new ZipCoder(Charset.defaultCharset());
+    }
+
+    private final ThreadLocal<CharsetDecoder> decTL = new ThreadLocal<>();
+    private final ThreadLocal<CharsetEncoder> encTL = new ThreadLocal<>();
+
+    private CharsetDecoder decoder() {
+        CharsetDecoder dec = decTL.get();
+        if (dec == null) {
+            dec = cs.newDecoder()
+              .onMalformedInput(CodingErrorAction.REPORT)
+              .onUnmappableCharacter(CodingErrorAction.REPORT);
+            decTL.set(dec);
+        }
+        return dec;
+    }
+
+    private CharsetEncoder encoder() {
+        CharsetEncoder enc = encTL.get();
+        if (enc == null) {
+            enc = cs.newEncoder()
+              .onMalformedInput(CodingErrorAction.REPORT)
+              .onUnmappableCharacter(CodingErrorAction.REPORT);
+            encTL.set(enc);
+        }
+        return enc;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipConstants.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+import java.nio.ByteBuffer;
+
+/**
+ *
+ * @author Xueming Shen
+ */
+
+class ZipConstants {
+    /*
+     * Compression methods
+     */
+    static final int METHOD_STORED     = 0;
+    static final int METHOD_DEFLATED   = 8;
+    static final int METHOD_DEFLATED64 = 9;
+    static final int METHOD_BZIP2      = 12;
+    static final int METHOD_LZMA       = 14;
+    static final int METHOD_LZ77       = 19;
+
+    /*
+     * General purpose big flag
+     */
+    static final int FLAG_ENCRYPTED  = 0x01;
+    static final int FLAG_DATADESCR  = 0x08;    // crc, size and csize in dd
+    static final int FLAG_EFS        = 0x800;   // If this bit is set the filename and
+                                                // comment fields for this file must be
+                                                // encoded using UTF-8.
+    /*
+     * Header signatures
+     */
+    static long LOCSIG = 0x04034b50L;   // "PK\003\004"
+    static long EXTSIG = 0x08074b50L;   // "PK\007\008"
+    static long CENSIG = 0x02014b50L;   // "PK\001\002"
+    static long ENDSIG = 0x06054b50L;   // "PK\005\006"
+
+    /*
+     * Header sizes in bytes (including signatures)
+     */
+    static final int LOCHDR = 30;       // LOC header size
+    static final int EXTHDR = 16;       // EXT header size
+    static final int CENHDR = 46;       // CEN header size
+    static final int ENDHDR = 22;       // END header size
+
+    /*
+     * Local file (LOC) header field offsets
+     */
+    static final int LOCVER = 4;        // version needed to extract
+    static final int LOCFLG = 6;        // general purpose bit flag
+    static final int LOCHOW = 8;        // compression method
+    static final int LOCTIM = 10;       // modification time
+    static final int LOCCRC = 14;       // uncompressed file crc-32 value
+    static final int LOCSIZ = 18;       // compressed size
+    static final int LOCLEN = 22;       // uncompressed size
+    static final int LOCNAM = 26;       // filename length
+    static final int LOCEXT = 28;       // extra field length
+
+    /*
+     * Extra local (EXT) header field offsets
+     */
+    static final int EXTCRC = 4;        // uncompressed file crc-32 value
+    static final int EXTSIZ = 8;        // compressed size
+    static final int EXTLEN = 12;       // uncompressed size
+
+    /*
+     * Central directory (CEN) header field offsets
+     */
+    static final int CENVEM = 4;        // version made by
+    static final int CENVER = 6;        // version needed to extract
+    static final int CENFLG = 8;        // encrypt, decrypt flags
+    static final int CENHOW = 10;       // compression method
+    static final int CENTIM = 12;       // modification time
+    static final int CENCRC = 16;       // uncompressed file crc-32 value
+    static final int CENSIZ = 20;       // compressed size
+    static final int CENLEN = 24;       // uncompressed size
+    static final int CENNAM = 28;       // filename length
+    static final int CENEXT = 30;       // extra field length
+    static final int CENCOM = 32;       // comment length
+    static final int CENDSK = 34;       // disk number start
+    static final int CENATT = 36;       // internal file attributes
+    static final int CENATX = 38;       // external file attributes
+    static final int CENOFF = 42;       // LOC header offset
+
+    /*
+     * End of central directory (END) header field offsets
+     */
+    static final int ENDSUB = 8;        // number of entries on this disk
+    static final int ENDTOT = 10;       // total number of entries
+    static final int ENDSIZ = 12;       // central directory size in bytes
+    static final int ENDOFF = 16;       // offset of first CEN header
+    static final int ENDCOM = 20;       // zip file comment length
+
+    /*
+     * ZIP64 constants
+     */
+    static final long ZIP64_ENDSIG = 0x06064b50L;  // "PK\006\006"
+    static final long ZIP64_LOCSIG = 0x07064b50L;  // "PK\006\007"
+    static final int  ZIP64_ENDHDR = 56;           // ZIP64 end header size
+    static final int  ZIP64_LOCHDR = 20;           // ZIP64 end loc header size
+    static final int  ZIP64_EXTHDR = 24;           // EXT header size
+    static final int  ZIP64_EXTID  = 0x0001;       // Extra field Zip64 header ID
+
+    static final int  ZIP64_MINVAL32 = 0xFFFF;
+    static final long ZIP64_MINVAL = 0xFFFFFFFFL;
+
+    /*
+     * Zip64 End of central directory (END) header field offsets
+     */
+    static final int  ZIP64_ENDLEN = 4;       // size of zip64 end of central dir
+    static final int  ZIP64_ENDVEM = 12;      // version made by
+    static final int  ZIP64_ENDVER = 14;      // version needed to extract
+    static final int  ZIP64_ENDNMD = 16;      // number of this disk
+    static final int  ZIP64_ENDDSK = 20;      // disk number of start
+    static final int  ZIP64_ENDTOD = 24;      // total number of entries on this disk
+    static final int  ZIP64_ENDTOT = 32;      // total number of entries
+    static final int  ZIP64_ENDSIZ = 40;      // central directory size in bytes
+    static final int  ZIP64_ENDOFF = 48;      // offset of first CEN header
+    static final int  ZIP64_ENDEXT = 56;      // zip64 extensible data sector
+
+    /*
+     * Zip64 End of central directory locator field offsets
+     */
+    static final int  ZIP64_LOCDSK = 4;       // disk number start
+    static final int  ZIP64_LOCOFF = 8;       // offset of zip64 end
+    static final int  ZIP64_LOCTOT = 16;      // total number of disks
+
+    /*
+     * Zip64 Extra local (EXT) header field offsets
+     */
+    static final int  ZIP64_EXTCRC = 4;       // uncompressed file crc-32 value
+    static final int  ZIP64_EXTSIZ = 8;       // compressed size, 8-byte
+    static final int  ZIP64_EXTLEN = 16;      // uncompressed size, 8-byte
+
+    /*
+     * Extra field header ID
+     */
+    static final int  EXTID_ZIP64 = 0x0001;      // ZIP64
+    static final int  EXTID_NTFS  = 0x000a;      // NTFS
+    static final int  EXTID_UNIX  = 0x000d;      // UNIX
+
+
+    /*
+     * fields access methods
+     */
+    ///////////////////////////////////////////////////////
+    static final int CH(byte[] b, int n) {
+       return b[n] & 0xff;
+    }
+
+    static final int SH(byte[] b, int n) {
+        return (b[n] & 0xff) | ((b[n + 1] & 0xff) << 8);
+    }
+
+    static final long LG(byte[] b, int n) {
+        return ((SH(b, n)) | (SH(b, n + 2) << 16)) & 0xffffffffL;
+    }
+
+    static final long LL(byte[] b, int n) {
+        return (LG(b, n)) | (LG(b, n + 4) << 32);
+    }
+
+    static final long GETSIG(byte[] b) {
+        return LG(b, 0);
+    }
+
+    // local file (LOC) header fields
+    static final long LOCSIG(byte[] b) { return LG(b, 0); } // signature
+    static final int  LOCVER(byte[] b) { return SH(b, 4); } // version needed to extract
+    static final int  LOCFLG(byte[] b) { return SH(b, 6); } // general purpose bit flags
+    static final int  LOCHOW(byte[] b) { return SH(b, 8); } // compression method
+    static final long LOCTIM(byte[] b) { return LG(b, 10);} // modification time
+    static final long LOCCRC(byte[] b) { return LG(b, 14);} // crc of uncompressed data
+    static final long LOCSIZ(byte[] b) { return LG(b, 18);} // compressed data size
+    static final long LOCLEN(byte[] b) { return LG(b, 22);} // uncompressed data size
+    static final int  LOCNAM(byte[] b) { return SH(b, 26);} // filename length
+    static final int  LOCEXT(byte[] b) { return SH(b, 28);} // extra field length
+
+    // extra local (EXT) header fields
+    static final long EXTCRC(byte[] b) { return LG(b, 4);}  // crc of uncompressed data
+    static final long EXTSIZ(byte[] b) { return LG(b, 8);}  // compressed size
+    static final long EXTLEN(byte[] b) { return LG(b, 12);} // uncompressed size
+
+    // end of central directory header (END) fields
+    static final int  ENDSUB(byte[] b) { return SH(b, 8); }  // number of entries on this disk
+    static final int  ENDTOT(byte[] b) { return SH(b, 10);}  // total number of entries
+    static final long ENDSIZ(byte[] b) { return LG(b, 12);}  // central directory size
+    static final long ENDOFF(byte[] b) { return LG(b, 16);}  // central directory offset
+    static final int  ENDCOM(byte[] b) { return SH(b, 20);}  // size of zip file comment
+    static final int  ENDCOM(byte[] b, int off) { return SH(b, off + 20);}
+
+    // zip64 end of central directory recoder fields
+    static final long ZIP64_ENDTOD(byte[] b) { return LL(b, 24);}  // total number of entries on disk
+    static final long ZIP64_ENDTOT(byte[] b) { return LL(b, 32);}  // total number of entries
+    static final long ZIP64_ENDSIZ(byte[] b) { return LL(b, 40);}  // central directory size
+    static final long ZIP64_ENDOFF(byte[] b) { return LL(b, 48);}  // central directory offset
+    static final long ZIP64_LOCOFF(byte[] b) { return LL(b, 8);}   // zip64 end offset
+
+    //////////////////////////////////////////
+    static final int CH(ByteBuffer b, int pos) {
+       return b.get(pos) & 0xff;
+    }
+    static final int SH(ByteBuffer b, int pos) {
+        return b.getShort(pos) & 0xffff;
+    }
+    static final long LG(ByteBuffer b, int pos) {
+        return b.getInt(pos) & 0xffffffffL;
+    }
+
+    // central directory header (END) fields
+    static final long CENSIG(ByteBuffer b, int pos) { return LG(b, pos + 0); }
+    static final int  CENVEM(ByteBuffer b, int pos) { return SH(b, pos + 4); }
+    static final int  CENVER(ByteBuffer b, int pos) { return SH(b, pos + 6); }
+    static final int  CENFLG(ByteBuffer b, int pos) { return SH(b, pos + 8); }
+    static final int  CENHOW(ByteBuffer b, int pos) { return SH(b, pos + 10);}
+    static final long CENTIM(ByteBuffer b, int pos) { return LG(b, pos + 12);}
+    static final long CENCRC(ByteBuffer b, int pos) { return LG(b, pos + 16);}
+    static final long CENSIZ(ByteBuffer b, int pos) { return LG(b, pos + 20);}
+    static final long CENLEN(ByteBuffer b, int pos) { return LG(b, pos + 24);}
+    static final int  CENNAM(ByteBuffer b, int pos) { return SH(b, pos + 28);}
+    static final int  CENEXT(ByteBuffer b, int pos) { return SH(b, pos + 30);}
+    static final int  CENCOM(ByteBuffer b, int pos) { return SH(b, pos + 32);}
+    static final int  CENDSK(ByteBuffer b, int pos) { return SH(b, pos + 34);}
+    static final int  CENATT(ByteBuffer b, int pos) { return SH(b, pos + 36);}
+    static final long CENATX(ByteBuffer b, int pos) { return LG(b, pos + 38);}
+    static final long CENOFF(ByteBuffer b, int pos) { return LG(b, pos + 42);}
+
+    /* The END header is followed by a variable length comment of size < 64k. */
+    static final long END_MAXLEN = 0xFFFF + ENDHDR;
+    static final int READBLOCKSZ = 128;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipDirectoryStream.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+import java.nio.file.DirectoryStream;
+import java.nio.file.ClosedDirectoryStreamException;
+import java.nio.file.NotDirectoryException;
+import java.nio.file.Path;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.io.IOException;
+import static com.sun.nio.zipfs.ZipUtils.*;
+
+/**
+ *
+ * @author  Xueming Shen, Rajendra Gutupalli, Jaya Hangal
+ */
+
+public class ZipDirectoryStream implements DirectoryStream<Path> {
+
+    private final ZipFileSystem zipfs;
+    private final byte[] path;
+    private final DirectoryStream.Filter<? super Path> filter;
+    private volatile boolean isClosed;
+    private volatile Iterator<Path> itr;
+
+    ZipDirectoryStream(ZipPath zipPath,
+                       DirectoryStream.Filter<? super java.nio.file.Path> filter)
+        throws IOException
+    {
+        this.zipfs = zipPath.getFileSystem();
+        this.path = zipPath.getResolvedPath();
+        this.filter = filter;
+        // sanity check
+        if (!zipfs.isDirectory(path))
+            throw new NotDirectoryException(zipPath.toString());
+    }
+
+    @Override
+    public synchronized Iterator<Path> iterator() {
+        if (isClosed)
+            throw new ClosedDirectoryStreamException();
+        if (itr != null)
+            throw new IllegalStateException("Iterator has already been returned");
+
+        try {
+            itr = zipfs.iteratorOf(path, filter);
+        } catch (IOException e) {
+            throw new IllegalStateException(e);
+        }
+        return new Iterator<Path>() {
+            private Path next;
+            @Override
+            public boolean hasNext() {
+                if (isClosed)
+                    return false;
+                return itr.hasNext();
+            }
+
+            @Override
+            public synchronized Path next() {
+                if (isClosed)
+                    throw new NoSuchElementException();
+                return itr.next();
+            }
+
+            @Override
+            public void remove() {
+                throw new UnsupportedOperationException();
+            }
+        };
+    }
+
+    @Override
+    public synchronized void close() throws IOException {
+        isClosed = true;
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributeView.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package com.sun.nio.zipfs;
+
+import java.nio.file.ReadOnlyFileSystemException;
+import java.nio.file.attribute.BasicFileAttributeView;
+import java.nio.file.attribute.FileAttributeView;
+import java.nio.file.attribute.FileTime;
+import java.io.IOException;
+import java.util.LinkedHashMap;
+
+/*
+ * @author  Xueming Shen, Rajendra Gutupalli, Jaya Hangal
+ */
+
+public class ZipFileAttributeView implements BasicFileAttributeView
+{
+    private static enum AttrID {
+        size,
+        creationTime,
+        lastAccessTime,
+        lastModifiedTime,
+        isDirectory,
+        isRegularFile,
+        isSymbolicLink,
+        isOther,
+        fileKey,
+        compressedSize,
+        crc,
+        method
+    };
+
+    private final ZipPath path;
+    private final boolean isZipView;
+
+    private ZipFileAttributeView(ZipPath path, boolean isZipView) {
+        this.path = path;
+        this.isZipView = isZipView;
+    }
+
+    static <V extends FileAttributeView> V get(ZipPath path, Class<V> type) {
+        if (type == null)
+            throw new NullPointerException();
+        if (type == BasicFileAttributeView.class)
+            return (V)new ZipFileAttributeView(path, false);
+        if (type == ZipFileAttributeView.class)
+            return (V)new ZipFileAttributeView(path, true);
+        return null;
+    }
+
+    static ZipFileAttributeView get(ZipPath path, String type) {
+        if (type == null)
+            throw new NullPointerException();
+        if (type.equals("basic"))
+            return new ZipFileAttributeView(path, false);
+        if (type.equals("zip"))
+            return new ZipFileAttributeView(path, true);
+        return null;
+    }
+
+    @Override
+    public String name() {
+        return isZipView ? "zip" : "basic";
+    }
+
+    public ZipFileAttributes readAttributes() throws IOException
+    {
+        return path.getAttributes();
+    }
+
+    @Override
+    public void setTimes(FileTime lastModifiedTime,
+                         FileTime lastAccessTime,
+                         FileTime createTime)
+        throws IOException
+    {
+        path.setTimes(lastModifiedTime, lastAccessTime, createTime);
+    }
+
+    void setAttribute(String attribute, Object value)
+        throws IOException
+    {
+        try {
+            if (AttrID.valueOf(attribute) == AttrID.lastModifiedTime)
+                setTimes ((FileTime)value, null, null);
+            return;
+        } catch (IllegalArgumentException x) {}
+        throw new UnsupportedOperationException("'" + attribute +
+            "' is unknown or read-only attribute");
+    }
+
+    public Object getAttribute(String attribute, boolean domap)
+        throws IOException
+    {
+        ZipFileAttributes zfas = readAttributes();
+        if (!domap) {
+            try {
+                return attribute(AttrID.valueOf(attribute), zfas);
+            } catch (IllegalArgumentException x) {}
+            return null;
+        }
+        LinkedHashMap<String, Object> map = new LinkedHashMap<>();
+        if ("*".equals(attribute)) {
+            for (AttrID id : AttrID.values()) {
+                try {
+                    map.put(id.name(), attribute(id, zfas));
+                } catch (IllegalArgumentException x) {}
+            }
+        } else {
+            String[] as = attribute.split(",");
+            for (String a : as) {
+                try {
+                    map.put(a, attribute(AttrID.valueOf(a), zfas));
+                } catch (IllegalArgumentException x) {}
+            }
+        }
+        return map;
+    }
+
+    Object attribute(AttrID id, ZipFileAttributes zfas) {
+        switch (id) {
+        case size:
+            return zfas.size();
+        case creationTime:
+            return zfas.creationTime();
+        case lastAccessTime:
+            return zfas.lastAccessTime();
+        case lastModifiedTime:
+            return zfas.lastModifiedTime();
+        case isDirectory:
+            return zfas.isDirectory();
+        case isRegularFile:
+            return zfas.isRegularFile();
+        case isSymbolicLink:
+            return zfas.isSymbolicLink();
+        case isOther:
+            return zfas.isOther();
+        case fileKey:
+            return zfas.fileKey();
+        case compressedSize:
+            if (isZipView)
+                return zfas.compressedSize();
+            break;
+        case crc:
+            if (isZipView)
+                return zfas.crc();
+            break;
+        case method:
+            if (isZipView)
+                return zfas.method();
+            break;
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributes.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package com.sun.nio.zipfs;
+
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.attribute.FileTime;
+import java.util.Arrays;
+import java.util.Formatter;
+import static com.sun.nio.zipfs.ZipUtils.*;
+
+/**
+ *
+ * @author  Xueming Shen, Rajendra Gutupalli,Jaya Hangal
+ */
+
+public class ZipFileAttributes implements BasicFileAttributes
+
+{
+    private final ZipFileSystem.Entry e;
+
+    ZipFileAttributes(ZipFileSystem.Entry e) {
+        this.e = e;
+    }
+
+    ///////// basic attributes ///////////
+    @Override
+    public FileTime creationTime() {
+        if (e.ctime != -1)
+            return FileTime.fromMillis(dosToJavaTime(e.ctime));
+        return null;
+    }
+
+    @Override
+    public boolean isDirectory() {
+        return e.isDir();
+    }
+
+    @Override
+    public boolean isOther() {
+        return false;
+    }
+
+    @Override
+    public boolean isRegularFile() {
+        return !e.isDir();
+    }
+
+    @Override
+    public FileTime lastAccessTime() {
+        if (e.atime != -1)
+            return FileTime.fromMillis(dosToJavaTime(e.atime));
+        return null;
+    }
+
+    @Override
+    public FileTime lastModifiedTime() {
+        return FileTime.fromMillis(dosToJavaTime(e.mtime));
+    }
+
+    @Override
+    public long size() {
+        return e.size;
+    }
+
+    @Override
+    public boolean isSymbolicLink() {
+        return false;
+    }
+
+    @Override
+    public Object fileKey() {
+        return null;
+    }
+
+    ///////// zip entry attributes ///////////
+    public byte[] name() {
+        return Arrays.copyOf(e.name, e.name.length);
+    }
+
+    public long compressedSize() {
+        return e.csize;
+    }
+
+    public long crc() {
+        return e.crc;
+    }
+
+    public int method() {
+        return e.method;
+    }
+
+    public byte[] extra() {
+        if (e.extra != null)
+            return Arrays.copyOf(e.extra, e.extra.length);
+        return null;
+    }
+
+    public byte[] comment() {
+        if (e.comment != null)
+            return Arrays.copyOf(e.comment, e.comment.length);
+        return null;
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        Formatter fm = new Formatter(sb);
+        fm.format("[/%s]%n", new String(e.name));  // TBD encoding
+        fm.format("    creationTime    : %s%n", creationTime());
+        if (lastAccessTime() != null)
+            fm.format("    lastAccessTime  : %tc%n", lastAccessTime().toMillis());
+        else
+            fm.format("    lastAccessTime  : null%n");
+        fm.format("    lastModifiedTime: %tc%n", lastModifiedTime().toMillis());
+        fm.format("    isRegularFile   : %b%n", isRegularFile());
+        fm.format("    isDirectory     : %b%n", isDirectory());
+        fm.format("    isSymbolicLink  : %b%n", isSymbolicLink());
+        fm.format("    isOther         : %b%n", isOther());
+        fm.format("    fileKey         : %s%n", fileKey());
+        fm.format("    size            : %d%n", size());
+        fm.format("    compressedSize  : %d%n", compressedSize());
+        fm.format("    crc             : %x%n", crc());
+        fm.format("    method          : %d%n", method());
+        fm.close();
+        return sb.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileStore.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+import java.io.IOException;
+import java.nio.file.FileStore;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+import java.nio.file.attribute.FileAttributeView;
+import java.nio.file.attribute.FileStoreAttributeView;
+import java.nio.file.attribute.FileStoreSpaceAttributeView;
+import java.nio.file.attribute.FileStoreSpaceAttributes;
+import java.nio.file.attribute.Attributes;
+import java.nio.file.attribute.BasicFileAttributeView;
+import java.util.Formatter;
+
+/*
+ *
+ * @author  Xueming Shen, Rajendra Gutupalli, Jaya Hangal
+ */
+
+public class ZipFileStore extends FileStore {
+
+    private final ZipFileSystem zfs;
+
+    ZipFileStore(ZipPath zpath) {
+        this.zfs = (ZipFileSystem)zpath.getFileSystem();
+    }
+
+    @Override
+    public String name() {
+        return zfs.toString() + "/";
+    }
+
+    @Override
+    public String type() {
+        return "zipfs";
+    }
+
+    @Override
+    public boolean isReadOnly() {
+        return zfs.isReadOnly();
+    }
+
+    @Override
+    public boolean supportsFileAttributeView(Class<? extends FileAttributeView> type) {
+        return (type == BasicFileAttributeView.class ||
+                type == ZipFileAttributeView.class);
+    }
+
+    @Override
+    public boolean supportsFileAttributeView(String name) {
+        return name.equals("basic") || name.equals("zip");
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> type) {
+        if (type == null)
+            throw new NullPointerException();
+        if (type == FileStoreSpaceAttributeView.class)
+            return (V) new ZipFileStoreAttributeView(this);
+        return null;
+    }
+
+    @Override
+    public Object getAttribute(String attribute) throws IOException {
+         if (attribute.equals("space:totalSpace"))
+               return new ZipFileStoreAttributeView(this).readAttributes().totalSpace();
+         if (attribute.equals("space:usableSpace"))
+               return new ZipFileStoreAttributeView(this).readAttributes().usableSpace();
+         if (attribute.equals("space:unallocatedSpace"))
+               return new ZipFileStoreAttributeView(this).readAttributes().unallocatedSpace();
+         throw new UnsupportedOperationException("does not support the given attribute");
+    }
+
+    private static class ZipFileStoreAttributeView implements FileStoreSpaceAttributeView {
+
+        private final ZipFileStore fileStore;
+
+        public ZipFileStoreAttributeView(ZipFileStore fileStore) {
+            this.fileStore = fileStore;
+        }
+
+        @Override
+        public String name() {
+            return "space";
+        }
+
+        @Override
+        public FileStoreSpaceAttributes readAttributes() throws IOException {
+            final String file = fileStore.name();
+            Path path = FileSystems.getDefault().getPath(file);
+            final long size = Attributes.readBasicFileAttributes(path).size();
+            final FileStore fstore = path.getFileStore();
+            final FileStoreSpaceAttributes fstoreAttrs =
+                Attributes.readFileStoreSpaceAttributes(fstore);
+            return new FileStoreSpaceAttributes() {
+                public long totalSpace() {
+                    return size;
+                }
+
+                public long usableSpace() {
+                    if (!fstore.isReadOnly())
+                        return fstoreAttrs.usableSpace();
+                    return 0;
+                }
+
+                public long unallocatedSpace() {
+                    if (!fstore.isReadOnly())
+                        return fstoreAttrs.unallocatedSpace();
+                    return 0;
+                }
+
+                public String toString() {
+                    StringBuilder sb = new StringBuilder();
+                    Formatter fm = new Formatter(sb);
+                    fm.format("FileStoreSpaceAttributes[%s]%n", file);
+                    fm.format("      totalSpace: %d%n", totalSpace());
+                    fm.format("     usableSpace: %d%n", usableSpace());
+                    fm.format("    unallocSpace: %d%n", unallocatedSpace());
+                    fm.close();
+                    return sb.toString();
+                }
+            };
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystem.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,2257 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.*;
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.nio.file.spi.*;
+import java.net.URI;
+import java.util.*;
+import java.util.regex.Pattern;
+import java.util.zip.CRC32;
+import java.util.zip.Inflater;
+import java.util.zip.Deflater;
+import java.util.zip.InflaterInputStream;
+import java.util.zip.DeflaterOutputStream;
+import java.util.zip.ZipException;
+import java.util.zip.ZipError;
+import static java.lang.Boolean.*;
+import static com.sun.nio.zipfs.ZipConstants.*;
+import static com.sun.nio.zipfs.ZipUtils.*;
+import static java.nio.file.StandardOpenOption.*;
+import static java.nio.file.StandardCopyOption.*;
+
+/**
+ * A FileSystem built on a zip file
+ *
+ * @author Xueming Shen
+ */
+
+public class ZipFileSystem extends FileSystem {
+
+    private final ZipFileSystemProvider provider;
+    private final ZipPath defaultdir;
+    private boolean readOnly = false;
+    private final Path zfpath;
+    private final ZipCoder zc;
+
+    private final Object lock = new Object();
+
+    // configurable by env map
+    private final String  defaultDir;    // default dir for the file system
+    private final String  nameEncoding;  // default encoding for name/comment
+    private final boolean buildDirTree;  // build a dir tree for directoryStream ops
+    private final boolean useTempFile;   // use a temp file for newOS, default
+                                         // is to use BAOS for better performance
+    private final boolean createNew;     // create a new zip if not exists
+
+    ZipFileSystem(ZipFileSystemProvider provider,
+                  Path zfpath,
+                  Map<String, ?> env)
+        throws IOException
+    {
+        // configurable env setup
+        this.buildDirTree = TRUE.equals(env.get("buildDirTree"));
+        this.useTempFile = TRUE.equals(env.get("useTempFile"));
+        this.createNew = TRUE.equals(env.get("createNew"));
+        this.nameEncoding = env.containsKey("nameEncoding") ?
+                            (String)env.get("nameEncoding") : "UTF-8";
+        this.defaultDir = env.containsKey("default.dir") ?
+                          (String)env.get("default.dir") : "/";
+        if (this.defaultDir.charAt(0) != '/')
+            throw new IllegalArgumentException("default dir should be absolute");
+
+        this.provider = provider;
+        this.zfpath = zfpath;
+        if (zfpath.notExists()) {
+            if (createNew) {
+                OutputStream os = zfpath.newOutputStream(CREATE_NEW, WRITE);
+                new END().write(os, 0);
+                os.close();
+            } else {
+                throw new FileSystemNotFoundException(zfpath.toString());
+            }
+        }
+        zfpath.checkAccess(AccessMode.READ); // sm and existence check
+        try {
+            zfpath.checkAccess(AccessMode.WRITE);
+        } catch (AccessDeniedException x) {
+            this.readOnly = true;
+        }
+        this.zc = ZipCoder.get(nameEncoding);
+        this.defaultdir = new ZipPath(this, getBytes(defaultDir));
+        initZipFile();
+    }
+
+    @Override
+    public FileSystemProvider provider() {
+        return provider;
+    }
+
+    @Override
+    public String getSeparator() {
+        return "/";
+    }
+
+    @Override
+    public boolean isOpen() {
+        return isOpen;
+    }
+
+    @Override
+    public boolean isReadOnly() {
+        return readOnly;
+    }
+
+    private void checkWritable() throws IOException {
+        if (readOnly)
+            throw new ReadOnlyFileSystemException();
+    }
+
+    @Override
+    public Iterable<Path> getRootDirectories() {
+        ArrayList<Path> pathArr = new ArrayList<>();
+        pathArr.add(new ZipPath(this, new byte[]{'/'}));
+        return pathArr;
+    }
+
+    ZipPath getDefaultDir() {  // package private
+        return defaultdir;
+    }
+
+    @Override
+    public ZipPath getPath(String path) {
+        if (path.length() == 0)
+            throw new InvalidPathException(path, "path should not be empty");
+        return new ZipPath(this, getBytes(path));
+    }
+
+    @Override
+    public UserPrincipalLookupService getUserPrincipalLookupService() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public WatchService newWatchService() {
+        throw new UnsupportedOperationException();
+    }
+
+    FileStore getFileStore(ZipPath path) {
+        return new ZipFileStore(path);
+    }
+
+    @Override
+    public Iterable<FileStore> getFileStores() {
+        ArrayList<FileStore> list = new ArrayList<FileStore>(1);
+        list.add(new ZipFileStore(new ZipPath(this, new byte[]{'/'})));
+        return list;
+    }
+
+    private static final Set<String> supportedFileAttributeViews =
+            Collections.unmodifiableSet(
+                new HashSet<String>(Arrays.asList("basic", "zip")));
+
+    @Override
+    public Set<String> supportedFileAttributeViews() {
+        return supportedFileAttributeViews;
+    }
+
+    @Override
+    public String toString() {
+        return zfpath.toString();
+    }
+
+    Path getZipFile() {
+        return zfpath;
+    }
+
+    private static final String GLOB_SYNTAX = "glob";
+    private static final String REGEX_SYNTAX = "regex";
+
+    @Override
+    public PathMatcher getPathMatcher(String syntaxAndInput) {
+        int pos = syntaxAndInput.indexOf(':');
+        if (pos <= 0 || pos == syntaxAndInput.length()) {
+            throw new IllegalArgumentException();
+        }
+        String syntax = syntaxAndInput.substring(0, pos);
+        String input = syntaxAndInput.substring(pos + 1);
+        String expr;
+        if (syntax.equals(GLOB_SYNTAX)) {
+            expr = toRegexPattern(input);
+        } else {
+            if (syntax.equals(REGEX_SYNTAX)) {
+                expr = input;
+            } else {
+                throw new UnsupportedOperationException("Syntax '" + syntax +
+                    "' not recognized");
+            }
+        }
+        // return matcher
+        final Pattern pattern = Pattern.compile(expr);
+        return new PathMatcher() {
+            @Override
+            public boolean matches(Path path) {
+                return pattern.matcher(path.toString()).matches();
+            }
+        };
+    }
+
+    @Override
+    public void close() throws IOException {
+        synchronized (lock) {
+            if (!isOpen)
+                return;
+            isOpen = false;
+            if (!streams.isEmpty()) {
+                synchronized(streams) {
+                    for (InputStream is: streams)
+                    is.close();
+                }
+            }
+            sync();
+            ch.close();
+        }
+        synchronized (inflaters) {
+            for (Inflater inf : inflaters)
+                inf.end();
+        }
+        synchronized (deflaters) {
+            for (Deflater def : deflaters)
+                def.end();
+        }
+        for (Path p: tmppaths) {
+            try {
+                p.deleteIfExists();
+            } catch (IOException x) {
+                x.printStackTrace();
+            }
+        }
+        provider.removeFileSystem(zfpath);
+    }
+
+    ZipFileAttributes[] getAllAttributes() throws IOException {
+        ensureOpen();
+        int n = inodes.size();
+        ZipFileAttributes[] zes = new ZipFileAttributes[n];
+        Iterator<IndexNode> itr = inodes.values().iterator();
+        int i = 0;
+        while(itr.hasNext()) {
+            zes[i++] = new ZipFileAttributes(Entry.readCEN(cen, itr.next().pos));
+        }
+        return zes;
+    }
+
+    EntryName[] getEntryNames() throws IOException {
+        ensureOpen();
+        return inodes.keySet().toArray(new EntryName[0]);
+    }
+
+    ZipFileAttributes getFileAttributes(byte[] path)
+        throws IOException
+    {
+        synchronized (lock) {
+            Entry e = getEntry0(path);
+            if (e == null) {
+                if (path.length == 0) {
+                    e = new Entry(new byte[0]);  // root
+                } else if (buildDirTree) {
+                    IndexNode inode = getDirs().get(new EntryName(path));
+                    if (inode == null)
+                        return null;
+                    e = new Entry(inode.name);
+                } else {
+                    return null;
+                }
+                e.method = METHOD_STORED;        // STORED for dir
+                BasicFileAttributes bfas = Attributes.readBasicFileAttributes(zfpath);
+                if (bfas.lastModifiedTime() != null)
+                    e.mtime = javaToDosTime(bfas.lastModifiedTime().toMillis());
+                if (bfas.lastAccessTime() != null)
+                    e.atime = javaToDosTime(bfas.lastAccessTime().toMillis());
+                if (bfas.creationTime() != null)
+                    e.ctime = javaToDosTime(bfas.creationTime().toMillis());
+            }
+            return new ZipFileAttributes(e);
+        }
+    }
+
+    void setTimes(byte[] path, FileTime mtime, FileTime atime, FileTime ctime)
+        throws IOException
+    {
+        checkWritable();
+        synchronized (lock) {
+            Entry e = getEntry0(path);    // ensureOpen checked
+            if (e == null)
+                throw new NoSuchFileException(getString(path));
+            if (e.type == Entry.CEN)
+                e.type = Entry.COPY;      // copy e
+            if (mtime != null)
+                e.mtime = javaToDosTime(mtime.toMillis());
+            if (atime != null)
+                e.atime = javaToDosTime(atime.toMillis());
+            if (ctime != null)
+                e.ctime = javaToDosTime(ctime.toMillis());
+            update(e);
+        }
+    }
+
+    boolean exists(byte[] path)
+        throws IOException
+    {
+        return getEntry0(path) != null;
+    }
+
+    boolean isDirectory(byte[] path)
+        throws IOException
+    {
+        synchronized (lock) {
+            if (buildDirTree) {
+                return getDirs().containsKey(new EntryName(path));
+            }
+            Entry e = getEntry0(path);
+            return (e != null && e.isDir()) || path.length == 0;
+        }
+    }
+
+    private ZipPath toZipPath(byte[] path) {
+        // make it absolute
+        byte[] p = new byte[path.length + 1];
+        p[0] = '/';
+        System.arraycopy(path, 0, p, 1, path.length);
+        return new ZipPath(this, p);
+    }
+
+    // returns the list of child paths of "path"
+    Iterator<Path> iteratorOf(byte[] path,
+                              DirectoryStream.Filter<? super Path> filter)
+        throws IOException
+    {
+        synchronized (lock) {
+            if (buildDirTree) {
+                IndexNode inode = getDirs().get(new EntryName(path));
+                if (inode == null)
+                    throw new NotDirectoryException(getString(path));
+                List<Path> list = new ArrayList<Path>();
+                IndexNode child = inode.child;
+                while (child != null) {
+                    ZipPath zp = toZipPath(child.name);
+                    if (filter == null || filter.accept(zp))
+                        list.add(zp);
+                    child = child.sibling;
+                }
+                return list.iterator();
+            }
+
+            if (!isDirectory(path))
+                throw new NotDirectoryException(getString(path));
+            List<Path> list = new ArrayList<Path>();
+            EntryName[] entries = getEntryNames();
+            path = toDirectoryPath(path);
+            for (EntryName en :entries) {
+                if (!isParentOf(path, en.name))  // is "path" the parent of "name"
+                    continue;
+                int off = path.length;
+                while (off < en.name.length) {
+                    if (en.name[off] == '/')
+                        break;
+                    off++;
+                }
+                if (off < (en.name.length - 1))
+                    continue;
+                ZipPath zp = toZipPath(en.name);
+                if (filter == null || filter.accept(zp))
+                    list.add(zp);
+            }
+            return list.iterator();
+        }
+    }
+
+    void createDirectory(byte[] dir, FileAttribute<?>... attrs)
+        throws IOException
+    {
+        checkWritable();
+        dir = toDirectoryPath(dir);
+        synchronized (lock) {
+            ensureOpen();
+            // pseudo root dir, or exiting dir
+            if (dir.length == 0 || exists(dir))
+                throw new FileAlreadyExistsException(getString(dir));
+            checkParents(dir);
+
+            Entry e = new Entry(dir, Entry.NEW);
+            e.method = METHOD_STORED;  // STORED for dir
+            update(e);
+        }
+    }
+
+    void copyFile(boolean deletesrc, byte[]src, byte[] dst, CopyOption... options)
+        throws IOException
+    {
+        checkWritable();
+        if (Arrays.equals(src, dst))
+            return;    // do nothing, src and dst are the same
+        synchronized (lock) {
+            Entry eSrc = getEntry0(src);  // ensureOpen checked
+            if (eSrc == null)
+                throw new NoSuchFileException(getString(src));
+            if (eSrc.isDir()) {    // spec says to create dst dir
+                createDirectory(dst);
+                return;
+            }
+            boolean hasReplace = false;
+            boolean hasCopyAttrs = false;
+            for (CopyOption opt : options) {
+                if (opt == REPLACE_EXISTING)
+                    hasReplace = true;
+                else if (opt == COPY_ATTRIBUTES)
+                    hasCopyAttrs = true;
+            }
+            Entry eDst = getEntry0(dst);
+            if (eDst != null) {
+                if (!hasReplace)
+                    throw new FileAlreadyExistsException(getString(dst));
+            } else {
+                checkParents(dst);
+            }
+            Entry u = new Entry(eSrc, Entry.COPY);    // copy eSrc entry
+            u.name = dst;                             // change name
+            // don't touch the "nlen and elen" here. writeLOC() always
+            // re-calculate from "name" and "extra" for the correct length,
+            // copyLOCEntry however needs the original lengths to skip the
+            // loc header.
+            // u.nlen = dst.length;
+            if (eSrc.type == Entry.NEW || eSrc.type == Entry.FILECH)
+            {
+                u.type = eSrc.type;    // make it the same type
+                if (!deletesrc) {      // if it's not "rename", just take the data
+                    if (eSrc.bytes != null)
+                        u.bytes = Arrays.copyOf(eSrc.bytes, eSrc.bytes.length);
+                    else if (eSrc.file != null) {
+                        u.file = getTempPathForEntry(null);
+                        eSrc.file.copyTo(u.file, REPLACE_EXISTING);
+                    }
+                }
+            }
+            if (!hasCopyAttrs)
+                u.mtime = u.atime= u.ctime = javaToDosTime(System.currentTimeMillis());
+            update(u);
+            if (deletesrc)
+                updateDelete(eSrc);
+        }
+    }
+
+    // Returns an output stream for writing the contents into the specified
+    // entry.
+    OutputStream newOutputStream(byte[] path, OpenOption... options)
+        throws IOException
+    {
+        checkWritable();
+        boolean hasCreateNew = false;
+        boolean hasCreate = false;
+        boolean hasAppend = false;
+        for (OpenOption opt: options) {
+            if (opt == READ)
+                throw new IllegalArgumentException("READ not allowed");
+            if (opt == CREATE_NEW)
+                hasCreateNew = true;
+            if (opt == CREATE)
+                hasCreate = true;
+            if (opt == APPEND)
+                hasAppend = true;
+        }
+        synchronized (lock) {
+            Entry e = getEntry0(path);
+            if (e != null) {
+                if (e.isDir() || hasCreateNew)
+                    throw new FileAlreadyExistsException(getString(path));
+                if (hasAppend) {
+                    InputStream is = getInputStream(e);
+                    OutputStream os = getOutputStream(new Entry(e, Entry.NEW));
+                    copyStream(is, os);
+                    is.close();
+                    return os;
+                 }
+                 return getOutputStream(new Entry(e, Entry.NEW));
+            } else {
+                if (!hasCreate && !hasCreateNew)
+                    throw new NoSuchFileException(getString(path));
+                checkParents(path);
+                return getOutputStream(new Entry(path, Entry.NEW));
+            }
+        }
+    }
+
+    // Returns an input stream for reading the contents of the specified
+    // file entry.
+    InputStream newInputStream(byte[] path) throws IOException {
+        synchronized (lock) {
+            Entry e = getEntry0(path);
+            if (e == null)
+                throw new NoSuchFileException(getString(path));
+            if (e.isDir())
+                throw new FileSystemException(getString(path), "is a directory", null);
+            return getInputStream(e);
+        }
+    }
+
+    private void checkOptions(Set<? extends OpenOption> options) {
+        // check for options of null type and option is an intance of StandardOpenOption
+        for (OpenOption option : options) {
+            if (option == null)
+                throw new NullPointerException();
+            if (!(option instanceof StandardOpenOption))
+                throw new IllegalArgumentException();
+        }
+    }
+
+    // Returns a Writable/ReadByteChannel for now. Might consdier to use
+    // newFileChannel() instead, which dump the entry data into a regular
+    // file on the default file system and create a FileChannel on top of
+    // it.
+    SeekableByteChannel newByteChannel(byte[] path,
+                                       Set<? extends OpenOption> options,
+                                       FileAttribute<?>... attrs)
+        throws IOException
+    {
+        checkOptions(options);
+        if (options.contains(StandardOpenOption.WRITE) ||
+            options.contains(StandardOpenOption.APPEND)) {
+            checkWritable();
+            final WritableByteChannel wbc = Channels.newChannel(newOutputStream(path,
+                                                options.toArray(new OpenOption[0])));
+            long leftover = 0;;
+            if (options.contains(StandardOpenOption.APPEND)) {
+                Entry e = getEntry0(path);
+                if (e != null && e.size >= 0)
+                    leftover = e.size;
+            }
+            final long offset = leftover;
+            return new SeekableByteChannel() {
+                long written = offset;
+                public boolean isOpen() {
+                    return wbc.isOpen();
+                }
+                public long position() throws IOException {
+                    return written;
+                }
+                public SeekableByteChannel position(long pos) throws IOException {
+                    throw new UnsupportedOperationException();
+                }
+                public int read(ByteBuffer dst) throws IOException {
+                    throw new UnsupportedOperationException();
+                }
+                public SeekableByteChannel truncate(long size) throws IOException {
+                    throw new UnsupportedOperationException();
+                }
+                public int write(ByteBuffer src) throws IOException {
+                    int n = wbc.write(src);
+                    written += n;
+                    return n;
+                }
+                public long size() throws IOException {
+                    return written;
+                }
+                public void close() throws IOException {
+                    wbc.close();
+                }
+            };
+        } else {
+            Entry e = getEntry0(path);
+            if (e == null || e.isDir())
+                throw new NoSuchFileException(getString(path));
+            final ReadableByteChannel rbc =
+                Channels.newChannel(getInputStream(e));
+            final long size = e.size;
+            return new SeekableByteChannel() {
+                long read = 0;
+                public boolean isOpen() {
+                    return rbc.isOpen();
+                }
+                public long position() throws IOException {
+                    return read;
+                }
+                public SeekableByteChannel position(long pos) throws IOException {
+                    throw new UnsupportedOperationException();
+                }
+                public int read(ByteBuffer dst) throws IOException {
+                    return rbc.read(dst);
+                }
+                public SeekableByteChannel truncate(long size) throws IOException {
+                    throw new NonWritableChannelException();
+                }
+                public int write (ByteBuffer src) throws IOException {
+                    throw new NonWritableChannelException();
+                }
+                public long size() throws IOException {
+                    return size;
+                }
+                public void close() throws IOException {
+                    rbc.close();
+                }
+            };
+        }
+    }
+
+    // Returns a FileChannel of the specified entry.
+    //
+    // This implementation creates a temporary file on the default file system,
+    // copy the entry data into it if the entry exists, and then create a
+    // FileChannel on top of it.
+    FileChannel newFileChannel(byte[] path,
+                               Set<? extends OpenOption> options,
+                               FileAttribute<?>... attrs)
+        throws IOException
+    {
+        checkOptions(options);
+        final  boolean forWrite = (options.contains(StandardOpenOption.WRITE) ||
+                                   options.contains(StandardOpenOption.APPEND));
+        Entry e = getEntry0(path);
+        if (forWrite) {
+            checkWritable();
+            if (e == null) {
+                if (!options.contains(StandardOpenOption.CREATE_NEW))
+                    throw new NoSuchFileException(getString(path));
+            } else {
+                if (options.contains(StandardOpenOption.CREATE_NEW))
+                    throw new FileAlreadyExistsException(getString(path));
+                if (e.isDir())
+                    throw new FileAlreadyExistsException("directory <"
+                        + getString(path) + "> exists");
+            }
+            options.remove(StandardOpenOption.CREATE_NEW); // for tmpfile
+        } else if (e == null || e.isDir()) {
+            throw new NoSuchFileException(getString(path));
+        }
+
+        final boolean isFCH = (e != null && e.type == Entry.FILECH);
+        final Path tmpfile = isFCH ? e.file : getTempPathForEntry(path);
+        final FileChannel fch = tmpfile.getFileSystem()
+                                       .provider()
+                                       .newFileChannel(tmpfile, options, attrs);
+        final Entry u = isFCH ? e : new Entry(path, tmpfile, Entry.FILECH);
+        if (forWrite) {
+            u.flag = FLAG_DATADESCR;
+            u.method = METHOD_DEFLATED;
+        }
+        // is there a better way to hook into the FileChannel's close method?
+        return new FileChannel() {
+            public int write(ByteBuffer src) throws IOException {
+                return fch.write(src);
+            }
+            public long write(ByteBuffer[] srcs, int offset, int length)
+                throws IOException
+            {
+                return fch.write(srcs, offset, length);
+            }
+            public long position() throws IOException {
+                return fch.position();
+            }
+            public FileChannel position(long newPosition)
+                throws IOException
+            {
+                fch.position(newPosition);
+                return this;
+            }
+            public long size() throws IOException {
+                return fch.size();
+            }
+            public FileChannel truncate(long size)
+                throws IOException
+            {
+                fch.truncate(size);
+                return this;
+            }
+            public void force(boolean metaData)
+                throws IOException
+            {
+                fch.force(metaData);
+            }
+            public long transferTo(long position, long count,
+                                   WritableByteChannel target)
+                throws IOException
+            {
+                return fch.transferTo(position, count, target);
+            }
+            public long transferFrom(ReadableByteChannel src,
+                                     long position, long count)
+                throws IOException
+            {
+                return fch.transferFrom(src, position, count);
+            }
+            public int read(ByteBuffer dst) throws IOException {
+                return fch.read(dst);
+            }
+            public int read(ByteBuffer dst, long position)
+                throws IOException
+            {
+                return fch.read(dst, position);
+            }
+            public long read(ByteBuffer[] dsts, int offset, int length)
+                throws IOException
+            {
+                return fch.read(dsts, offset, length);
+            }
+            public int write(ByteBuffer src, long position)
+                throws IOException
+            {
+               return fch.write(src, position);
+            }
+            public MappedByteBuffer map(MapMode mode,
+                                        long position, long size)
+                throws IOException
+            {
+                throw new UnsupportedOperationException();
+            }
+            public FileLock lock(long position, long size, boolean shared)
+                throws IOException
+            {
+                return fch.lock(position, size, shared);
+            }
+            public FileLock tryLock(long position, long size, boolean shared)
+                throws IOException
+            {
+                return fch.tryLock(position, size, shared);
+            }
+            protected void implCloseChannel() throws IOException {
+                fch.close();
+                if (forWrite) {
+                    u.mtime = javaToDosTime(System.currentTimeMillis());
+                    u.size = Attributes.readBasicFileAttributes(u.file).size();
+                    update(u);
+                } else {
+                    if (!isFCH)    // if this is a new fch for reading
+                        removeTempPathForEntry(tmpfile);
+                }
+            }
+        };
+    }
+
+    // the outstanding input streams that need to be closed
+    private Set<InputStream> streams =
+        Collections.synchronizedSet(new HashSet<InputStream>());
+
+    // the ex-channel and ex-path that need to close when their outstanding
+    // input streams are all closed by the obtainers.
+    private Set<ExChannelCloser> exChClosers = new HashSet<>();
+
+    private Set<Path> tmppaths = new HashSet<>();
+    private Path getTempPathForEntry(byte[] path) throws IOException {
+        Path tmpPath = createTempFileInSameDirectoryAs(zfpath);
+        tmppaths.add(tmpPath);
+
+        if (path != null) {
+            Entry e = getEntry0(path);
+            if (e != null) {
+                InputStream is = newInputStream(path);
+                OutputStream os = tmpPath.newOutputStream(WRITE);
+                try {
+                    copyStream(is, os);
+                } finally {
+                    is.close();
+                    os.close();
+                }
+            }
+        }
+        return tmpPath;
+    }
+
+    private void removeTempPathForEntry(Path path) throws IOException {
+        path.delete();
+        tmppaths.remove(path);
+    }
+
+    // check if all parents really exit. ZIP spec does not require
+    // the existence of any "parent directory".
+    private void checkParents(byte[] path) throws IOException {
+        while ((path = getParent(path)) != null) {
+            if (!inodes.containsKey(new EntryName(path)))
+                throw new NoSuchFileException(getString(path));
+        }
+    }
+
+    private static byte[] getParent(byte[] path) {
+        int off = path.length - 1;
+        if (off > 0 && path[off] == '/')  // isDirectory
+            off--;
+        while (off > 0 && path[off] != '/') { off--; }
+        if (off == 0)
+            return null;                  // top entry
+        return Arrays.copyOf(path, off + 1);
+    }
+
+    // If "starter" is the parent directory of "path"
+    private static boolean isParentOf(byte[] p, byte[] c) {
+        final int plen = p.length;
+        if (plen == 0)          // root dir
+            return true;
+        if (plen  >= c.length)
+            return false;
+        int n = 0;
+        while (n < plen) {
+            if (p[n] != c[n])
+                return false;
+            n++;
+        }
+        if (p[n - 1] != '/' && (c[n] != '/' || n == c.length - 1))
+            return false;
+        return true;
+    }
+
+    ///////////////////////////////////////////////////////////////////
+    private void initZipFile() throws IOException {
+        ch = zfpath.newByteChannel(READ);
+        initCEN();
+    }
+
+    private volatile boolean isOpen = true;
+    private SeekableByteChannel ch; // channel to the zipfile
+    ByteBuffer cen;        // CEN & ENDHDR
+    private END  end;
+    private long locpos;   // position of first LOC header (usually 0)
+
+    // name -> pos (in cen), package private for ZipInfo
+    LinkedHashMap<EntryName, IndexNode> inodes;
+
+    byte[] getBytes(String name) {
+        return zc.getBytes(name);
+    }
+    String getString(byte[] name) {
+        return zc.toString(name);
+    }
+
+    protected void finalize() throws IOException {
+        close();
+    }
+
+    private long getDataPos(Entry e) throws IOException {
+        if (e.locoff == -1) {
+            Entry e2 = getEntry0(e.name);
+            if (e2 == null)
+                throw new ZipException("invalid loc for entry <" + e.name + ">");
+            e.locoff = e2.locoff;
+        }
+        byte[] buf = new byte[LOCHDR];
+        if (readFullyAt(buf, 0, buf.length, e.locoff) != buf.length)
+            throw new ZipException("invalid loc for entry <" + e.name + ">");
+        return locpos + e.locoff + LOCHDR + LOCNAM(buf) + LOCEXT(buf);
+    }
+
+    // Reads len bytes of data from the specified offset into buf.
+    // Returns the total number of bytes read.
+    // Each/every byte read from here (except the cen, which is mapped).
+    private long readFullyAt(byte[] buf, int off, long len, long pos)
+        throws IOException
+    {
+        ByteBuffer bb = ByteBuffer.wrap(buf);
+        bb.position(off);
+        bb.limit((int)(off + len));
+        return readFullyAt(bb, pos);
+    }
+
+    private long readFullyAt(ByteBuffer bb, long pos)
+        throws IOException
+    {
+        synchronized(ch) {
+            return ch.position(pos).read(bb);
+        }
+    }
+
+    // Searches for end of central directory (END) header. The contents of
+    // the END header will be read and placed in endbuf. Returns the file
+    // position of the END header, otherwise returns -1 if the END header
+    // was not found or an error occurred.
+    private END findEND() throws IOException
+    {
+        byte[] buf = new byte[READBLOCKSZ];
+        long ziplen = ch.size();
+        long minHDR = (ziplen - END_MAXLEN) > 0 ? ziplen - END_MAXLEN : 0;
+        long minPos = minHDR - (buf.length - ENDHDR);
+
+        for (long pos = ziplen - buf.length; pos >= minPos; pos -= (buf.length - ENDHDR))
+        {
+            int off = 0;
+            if (pos < 0) {
+                // Pretend there are some NUL bytes before start of file
+                off = (int)-pos;
+                Arrays.fill(buf, 0, off, (byte)0);
+            }
+            int len = buf.length - off;
+            if (readFullyAt(buf, off, len, pos + off) != len)
+                zerror("zip END header not found");
+
+            // Now scan the block backwards for END header signature
+            for (int i = buf.length - ENDHDR; i >= 0; i--) {
+                if (buf[i+0] == (byte)'P'    &&
+                    buf[i+1] == (byte)'K'    &&
+                    buf[i+2] == (byte)'\005' &&
+                    buf[i+3] == (byte)'\006' &&
+                    (pos + i + ENDHDR + ENDCOM(buf, i) == ziplen)) {
+                    // Found END header
+                    buf = Arrays.copyOfRange(buf, i, i + ENDHDR);
+                    END end = new END();
+                    end.endsub = ENDSUB(buf);
+                    end.centot = ENDTOT(buf);
+                    end.cenlen = ENDSIZ(buf);
+                    end.cenoff = ENDOFF(buf);
+                    end.comlen = ENDCOM(buf);
+                    end.endpos = pos + i;
+                    if (end.cenlen == ZIP64_MINVAL ||
+                        end.cenoff == ZIP64_MINVAL ||
+                        end.centot == ZIP64_MINVAL32)
+                    {
+                        // need to find the zip64 end;
+                        byte[] loc64 = new byte[ZIP64_LOCHDR];
+                        if (readFullyAt(loc64, 0, loc64.length, end.endpos - ZIP64_LOCHDR)
+                            != loc64.length) {
+                            return end;
+                        }
+                        long end64pos = ZIP64_LOCOFF(loc64);
+                        byte[] end64buf = new byte[ZIP64_ENDHDR];
+                        if (readFullyAt(end64buf, 0, end64buf.length, end64pos)
+                            != end64buf.length) {
+                            return end;
+                        }
+                        // end64 found, re-calcualte everything.
+                        end.cenlen = ZIP64_ENDSIZ(end64buf);
+                        end.cenoff = ZIP64_ENDOFF(end64buf);
+                        end.centot = (int)ZIP64_ENDTOT(end64buf); // assume total < 2g
+                        end.endpos = end64pos;
+                    }
+                    return end;
+                }
+            }
+        }
+        zerror("zip END header not found");
+        return null; //make compiler happy
+    }
+
+    // Reads zip file central directory. Returns the file position of first
+    // CEN header, otherwise returns -1 if an error occured. If zip->msg != NULL
+    // then the error was a zip format error and zip->msg has the error text.
+    // Always pass in -1 for knownTotal; it's used for a recursive call.
+    private long initCEN() throws IOException {
+        end = findEND();
+        if (end.endpos == 0) {
+            inodes = new LinkedHashMap<EntryName, IndexNode>(10);
+            locpos = 0;
+            return 0;         // only END header present
+        }
+        if (end.cenlen > end.endpos)
+            zerror("invalid END header (bad central directory size)");
+        long cenpos = end.endpos - end.cenlen;     // position of CEN table
+
+        // Get position of first local file (LOC) header, taking into
+        // account that there may be a stub prefixed to the zip file.
+        locpos = cenpos - end.cenoff;
+        if (locpos < 0)
+            zerror("invalid END header (bad central directory offset)");
+
+        // read in the CEN and END
+        cen = ByteBuffer.allocate((int)(end.cenlen + ENDHDR));
+        if (readFullyAt(cen, cenpos) != end.cenlen + ENDHDR) {
+            zerror("read CEN tables failed");
+        }
+        cen.order(ByteOrder.LITTLE_ENDIAN).flip();
+
+        // Iterate through the entries in the central directory
+        inodes = new LinkedHashMap<EntryName, IndexNode>(end.centot + 1);
+        int pos = 0;
+        int limit = cen.remaining() - ENDHDR;
+        int i = 0;
+        byte[] bBuf = new byte[1024];
+        while (pos < limit) {
+            if (CENSIG(cen, pos) != CENSIG)
+                zerror("invalid CEN header (bad signature)");
+            int method = CENHOW(cen, pos);
+            int nlen   = CENNAM(cen, pos);
+            int elen   = CENEXT(cen, pos);
+            int clen   = CENCOM(cen, pos);
+            if ((CENFLG(cen, pos) & 1) != 0)
+                zerror("invalid CEN header (encrypted entry)");
+            if (method != METHOD_STORED && method != METHOD_DEFLATED)
+                zerror("invalid CEN header (bad compression method: " + method + ")");
+            if (pos + CENHDR + nlen > limit)
+                zerror("invalid CEN header (bad header size)");
+            if (bBuf.length < nlen)
+                 bBuf = new byte[nlen];
+            cen.position(pos + CENHDR);
+            byte[] name = new byte[nlen];
+            cen.get(name);
+            inodes.put(new EntryName(name), new IndexNode(name, pos));
+            // skip ext and comment
+            cen.position(pos += (CENHDR + nlen + elen + clen));
+            i++;
+        }
+        if (cen.remaining() != ENDHDR) {
+            zerror("invalid CEN header (bad header size)");
+        }
+        dirs = null;  // clear the dir map
+        return cenpos;
+    }
+
+    private void ensureOpen() throws IOException {
+        if (!isOpen)
+            throw new ClosedFileSystemException();
+    }
+
+    // Creates a new empty temporary file in the same directory as the
+    // specified file.  A variant of File.createTempFile.
+    private static Path createTempFileInSameDirectoryAs(Path path)
+        throws IOException
+    {
+        Path parent = path.toAbsolutePath().getParent();
+        String dir = (parent == null)? "." : parent.toString();
+        return File.createTempFile("zipfstmp", null, new File(dir)).toPath();
+    }
+
+    ////////////////////update & sync //////////////////////////////////////
+
+    private boolean hasUpdate = false;
+    private void updateDelete(Entry e) {
+        EntryName en = new EntryName(e.name);
+        inodes.remove(en);
+        hasUpdate = true;
+    }
+
+    private void update(Entry e) {
+        EntryName en = new EntryName(e.name);
+        inodes.put(en, e);
+        hasUpdate = true;
+    }
+
+    // copy over the whole LOC entry (header if necessary, data and ext) from
+    // old zip to the new one.
+    private long copyLOCEntry(Entry e, boolean updateHeader,
+                              OutputStream os,
+                              long written, byte[] buf)
+        throws IOException
+    {
+        long locoff = e.locoff;  // where to read
+        e.locoff = written;      // update the e.locoff with new value
+
+        // calculate the size need to write out
+        long size = 0;
+        //  if there is A ext
+        if ((e.flag & FLAG_DATADESCR) != 0) {
+            if (e.size >= ZIP64_MINVAL || e.csize >= ZIP64_MINVAL)
+                size = 24;
+            else
+                size = 16;
+        }
+        if (updateHeader) {       // if we need update the loc header
+            locoff += LOCHDR + e.nlen + e.elen;  // skip header
+            size += e.csize;
+            written = e.writeLOC(os) + size;
+        } else {
+            size += LOCHDR + e.nlen + e.elen + e.csize;
+            written = size;
+        }
+        int n;
+        while (size > 0 &&
+            (n = (int)readFullyAt(buf, 0, buf.length, locoff)) != -1)
+        {
+            if (size < n)
+                n = (int)size;
+            os.write(buf, 0, n);
+            size -= n;
+            locoff += n;
+        }
+        return written;
+    }
+
+    // sync the zip file system, if there is any udpate
+    private void sync() throws IOException {
+        assert Thread.holdsLock(this);
+
+        // check ex-closer
+        if (!exChClosers.isEmpty()) {
+            for (ExChannelCloser ecc : exChClosers) {
+                if (ecc.streams.isEmpty()) {
+                    ecc.ch.close();
+                    ecc.path.delete();
+                    exChClosers.remove(ecc);
+                }
+            }
+        }
+        if (!hasUpdate)
+            return;
+
+        Path tmpFile = createTempFileInSameDirectoryAs(zfpath);
+        OutputStream os = tmpFile.newOutputStream(WRITE);
+        ArrayList<Entry> elist = new ArrayList<>(inodes.size());
+        long written = 0;
+        byte[] buf = new byte[8192];
+        Entry e = null;
+
+        // write loc
+        for (IndexNode inode : inodes.values()) {
+            if (inode instanceof Entry) {    // an updated inode
+                e = (Entry)inode;
+                try {
+                    if (e.type == Entry.COPY) {
+                        // entry copy: the only thing changed is the "name"
+                        // and "nlen" in LOC header, so we udpate/rewrite the
+                        // LOC in new file and simply copy the rest (data and
+                        // ext) without enflating/deflating from the old zip
+                        // file LOC entry.
+                        written += copyLOCEntry(e, true, os, written, buf);
+                    } else {                          // NEW or FILECH
+                        e.locoff = written;
+                        written += e.writeLOC(os);    // write loc header
+                        if (e.bytes != null) {        // in-memory, deflated
+                            os.write(e.bytes);        // already
+                            written += e.bytes.length;
+                        } else if (e.file != null) {  // tmp file
+                            InputStream is = e.file.newInputStream();
+                            int n;
+                            if (e.type == Entry.NEW) {  // deflated already
+                                while ((n = is.read(buf)) != -1) {
+                                    os.write(buf, 0, n);
+                                    written += n;
+                                }
+                            } else if (e.type == Entry.FILECH) {
+                                // the data are not deflated, use ZEOS
+                                OutputStream os2 = new EntryOutputStream(e, os);
+                                while ((n = is.read(buf)) != -1) {
+                                    os2.write(buf, 0, n);
+                                }
+                                os2.close();
+                                written += e.csize;
+                                if ((e.flag & FLAG_DATADESCR) != 0)
+                                    written += e.writeEXT(os);
+                            }
+                            is.close();
+                            e.file.delete();
+                            tmppaths.remove(e.file);
+                        } else {
+                            // dir, 0-length data
+                        }
+                    }
+                    elist.add(e);
+                } catch (IOException x) {
+                    x.printStackTrace();    // skip any in-accurate entry
+                }
+            } else {    // unchanged inode
+                e = Entry.readCEN(cen, inode.pos);
+                try {
+                    written += copyLOCEntry(e, false, os, written, buf);
+                    elist.add(e);
+                } catch (IOException x) {
+                    x.printStackTrace();    // skip any wrong entry
+                }
+            }
+        }
+
+        // now write back the cen and end table
+        end.cenoff = written;
+        for (Entry entry : elist) {
+            written += entry.writeCEN(os);
+        }
+        end.centot = elist.size();
+        end.cenlen = written - end.cenoff;
+        end.write(os, written);
+        os.close();
+
+        if (!streams.isEmpty()) {
+            // There are outstanding input streams open on existing "ch",
+            // so, don't close the "cha" and delete the "file for now, let
+            // the "ex-channel-closer" to handle them
+            ExChannelCloser ecc = new ExChannelCloser(
+                                      createTempFileInSameDirectoryAs(zfpath),
+                                      ch,
+                                      streams);
+            zfpath.moveTo(ecc.path, REPLACE_EXISTING);
+            exChClosers.add(ecc);
+            streams = Collections.synchronizedSet(new HashSet<InputStream>());
+        } else {
+            ch.close();
+            zfpath.delete();
+        }
+        tmpFile.moveTo(zfpath, REPLACE_EXISTING);
+        hasUpdate = false;    // clear
+
+        if (isOpen) {
+            ch = zfpath.newByteChannel(READ); // re-fresh "ch" and "cen"
+            initCEN();
+        }
+        //System.out.println("->sync() done!");
+    }
+
+    private Entry getEntry0(byte[] path) throws IOException {
+        assert Thread.holdsLock(this);
+
+        if (path == null)
+            throw new NullPointerException("path");
+        if (path.length == 0)
+            return null;
+        EntryName en = new EntryName(path);
+        IndexNode inode = null;
+        synchronized (lock) {
+            ensureOpen();
+            if ((inode = inodes.get(en)) == null) {
+                if (path[path.length -1] == '/')  // already has a slash
+                    return null;
+                path = Arrays.copyOf(path, path.length + 1);
+                path[path.length - 1] = '/';
+                en.name(path);
+                if ((inode = inodes.get(en)) == null)
+                    return null;
+            }
+            if (inode instanceof Entry)
+                return (Entry)inode;
+            return Entry.readCEN(cen, inode.pos);
+        }
+    }
+
+    // Test if the "name" a parent directory of any entry (dir empty)
+    boolean isAncestor(byte[] name) {
+        for (Map.Entry<EntryName, IndexNode> entry : inodes.entrySet()) {
+            byte[] ename = entry.getKey().name;
+            if (isParentOf(name, ename))
+                return true;
+        }
+        return false;
+    }
+
+    public void deleteFile(byte[] path, boolean failIfNotExists)
+        throws IOException
+    {
+        checkWritable();
+        synchronized(lock) {
+            Entry e = getEntry0(path);
+            if (e == null) {
+                if (path != null && path.length == 0)
+                    throw new ZipException("root directory </> can't not be delete");
+                if (failIfNotExists)
+                    throw new NoSuchFileException(getString(path));
+            } else {
+                if (e.isDir() && isAncestor(path))
+                    throw new DirectoryNotEmptyException(getString(path));
+                updateDelete(e);
+            }
+        }
+    }
+
+    private static void copyStream(InputStream is, OutputStream os)
+        throws IOException
+    {
+        byte[] copyBuf = new byte[8192];
+        int n;
+        while ((n = is.read(copyBuf)) != -1) {
+            os.write(copyBuf, 0, n);
+        }
+    }
+
+    // Returns an out stream for either
+    // (1) writing the contents of a new entry, if the entry exits, or
+    // (2) updating/replacing the contents of the specified existing entry.
+    private OutputStream getOutputStream(Entry e) throws IOException {
+
+        ensureOpen();
+        if (e.mtime == -1)
+            e.mtime = javaToDosTime(System.currentTimeMillis());
+        if (e.method == -1)
+            e.method = METHOD_DEFLATED;  // TBD:  use default method
+        // store size, compressed size, and crc-32 in LOC header
+        e.flag = 0;
+        if (zc.isUTF8())
+            e.flag |= FLAG_EFS;
+        OutputStream os;
+        if (useTempFile) {
+            e.file = getTempPathForEntry(null);
+            os = e.file.newOutputStream(WRITE);
+        } else {
+            os = new ByteArrayOutputStream((e.size > 0)? (int)e.size : 8192);
+        }
+        return new EntryOutputStream(e, os);
+    }
+
+    private InputStream getInputStream(Entry e)
+        throws IOException
+    {
+        InputStream eis = null;
+
+        if (e.type == Entry.NEW) {
+            if (e.bytes != null)
+                eis = new ByteArrayInputStream(e.bytes);
+            else if (e.file != null)
+                eis = e.file.newInputStream();
+            else
+                throw new ZipException("update entry data is missing");
+        } else if (e.type == Entry.FILECH) {
+            // FILECH result is un-compressed.
+            eis = e.file.newInputStream();
+            // TBD: wrap to hook close()
+            // streams.add(eis);
+            return eis;
+        } else {  // untouced  CEN or COPY
+            eis = new EntryInputStream(e, ch);
+        }
+        if (e.method == METHOD_DEFLATED) {
+            // MORE: Compute good size for inflater stream:
+            long bufSize = e.size + 2; // Inflater likes a bit of slack
+            if (bufSize > 65536)
+                bufSize = 8192;
+            final long size = e.size;;
+            eis = new InflaterInputStream(eis, getInflater(), (int)bufSize) {
+
+                private boolean isClosed = false;
+                public void close() throws IOException {
+                    if (!isClosed) {
+                        releaseInflater(inf);
+                        this.in.close();
+                        isClosed = true;
+                    }
+                }
+                // Override fill() method to provide an extra "dummy" byte
+                // at the end of the input stream. This is required when
+                // using the "nowrap" Inflater option. (it appears the new
+                // zlib in 7 does not need it, but keep it for now)
+                protected void fill() throws IOException {
+                    if (eof) {
+                        throw new EOFException(
+                            "Unexpected end of ZLIB input stream");
+                    }
+                    len = this.in.read(buf, 0, buf.length);
+                    if (len == -1) {
+                        buf[0] = 0;
+                        len = 1;
+                        eof = true;
+                    }
+                    inf.setInput(buf, 0, len);
+                }
+                private boolean eof;
+
+                public int available() throws IOException {
+                    if (isClosed)
+                        return 0;
+                    long avail = size - inf.getBytesWritten();
+                    return avail > (long) Integer.MAX_VALUE ?
+                        Integer.MAX_VALUE : (int) avail;
+                }
+            };
+        } else if (e.method != METHOD_STORED) {
+            throw new ZipException("invalid compression method");
+        }
+        streams.add(eis);
+        return eis;
+    }
+
+    // Inner class implementing the input stream used to read
+    // a (possibly compressed) zip file entry.
+    private class EntryInputStream extends InputStream {
+        private SeekableByteChannel zfch; // local ref to zipfs's "ch". zipfs.ch might
+                                          // point to a new channel after sync()
+        private   long pos;               // current position within entry data
+        protected long rem;               // number of remaining bytes within entry
+        protected long size;              // uncompressed size of this entry
+
+        EntryInputStream(Entry e, SeekableByteChannel zfch)
+            throws IOException
+        {
+            this.zfch = zfch;
+            rem = e.csize;
+            size = e.size;
+            pos = getDataPos(e);
+        }
+        public int read(byte b[], int off, int len) throws IOException {
+            ensureOpen();
+            if (rem == 0) {
+                return -1;
+            }
+            if (len <= 0) {
+                return 0;
+            }
+            if (len > rem) {
+                len = (int) rem;
+            }
+            // readFullyAt()
+            long n = 0;
+            ByteBuffer bb = ByteBuffer.wrap(b);
+            bb.position(off);
+            bb.limit(off + len);
+            synchronized(zfch) {
+                n = zfch.position(pos).read(bb);
+            }
+            if (n > 0) {
+                pos += n;
+                rem -= n;
+            }
+            if (rem == 0) {
+                close();
+            }
+            return (int)n;
+        }
+        public int read() throws IOException {
+            byte[] b = new byte[1];
+            if (read(b, 0, 1) == 1) {
+                return b[0] & 0xff;
+            } else {
+                return -1;
+            }
+        }
+        public long skip(long n) throws IOException {
+            ensureOpen();
+            if (n > rem)
+                n = rem;
+            pos += n;
+            rem -= n;
+            if (rem == 0) {
+                close();
+            }
+            return n;
+        }
+        public int available() {
+            return rem > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) rem;
+        }
+
+        public long size() {
+            return size;
+        }
+        public void close() {
+            rem = 0;
+            streams.remove(this);
+        }
+    }
+
+    class EntryOutputStream extends DeflaterOutputStream
+    {
+        private CRC32 crc;
+        private Entry e;
+        private long written;
+
+        EntryOutputStream(Entry e, OutputStream os)
+            throws IOException
+        {
+            super(os, getDeflater());
+            if (e == null)
+                throw new NullPointerException("Zip entry is null");
+            this.e = e;
+            crc = new CRC32();
+        }
+
+        @Override
+        public void write(byte b[], int off, int len) throws IOException {
+            if (e.type != Entry.FILECH)    // only from sync
+                ensureOpen();
+            if (off < 0 || len < 0 || off > b.length - len) {
+                throw new IndexOutOfBoundsException();
+            } else if (len == 0) {
+                return;
+            }
+            switch (e.method) {
+            case METHOD_DEFLATED:
+                super.write(b, off, len);
+                break;
+            case METHOD_STORED:
+                written += len;
+                out.write(b, off, len);
+                break;
+            default:
+                throw new ZipException("invalid compression method");
+            }
+            crc.update(b, off, len);
+        }
+
+        @Override
+        public void close() throws IOException {
+            // TBD ensureOpen();
+            switch (e.method) {
+            case METHOD_DEFLATED:
+                finish();
+                e.size  = def.getBytesRead();
+                e.csize = def.getBytesWritten();
+                e.crc = crc.getValue();
+                break;
+            case METHOD_STORED:
+                // we already know that both e.size and e.csize are the same
+                e.size = e.csize = written;
+                e.crc = crc.getValue();
+                break;
+            default:
+                throw new ZipException("invalid compression method");
+            }
+            //crc.reset();
+            if (out instanceof ByteArrayOutputStream)
+                e.bytes = ((ByteArrayOutputStream)out).toByteArray();
+
+            if (e.type == Entry.FILECH) {
+                releaseDeflater(def);
+                return;
+            }
+            super.close();
+            releaseDeflater(def);
+            update(e);
+        }
+    }
+
+    private static void zerror(String msg) {
+        throw new ZipError(msg);
+    }
+
+    // Maxmum number of de/inflater we cache
+    private final int MAX_FLATER = 20;
+    // List of available Inflater objects for decompression
+    private List<Inflater> inflaters = new ArrayList<>();
+
+    // Gets an inflater from the list of available inflaters or allocates
+    // a new one.
+    private Inflater getInflater() {
+        synchronized (inflaters) {
+            int size = inflaters.size();
+            if (size > 0) {
+                Inflater inf = (Inflater)inflaters.remove(size - 1);
+                return inf;
+            } else {
+                return new Inflater(true);
+            }
+        }
+    }
+
+    // Releases the specified inflater to the list of available inflaters.
+    private void releaseInflater(Inflater inf) {
+        synchronized (inflaters) {
+            if (inflaters.size() < MAX_FLATER) {
+                inf.reset();
+                inflaters.add(inf);
+            } else {
+                inf.end();
+            }
+        }
+    }
+
+    // List of available Deflater objects for compression
+    private List<Deflater> deflaters = new ArrayList<>();
+
+    // Gets an deflater from the list of available deflaters or allocates
+    // a new one.
+    private Deflater getDeflater() {
+        synchronized (deflaters) {
+            int size = deflaters.size();
+            if (size > 0) {
+                Deflater def = (Deflater)deflaters.remove(size - 1);
+                return def;
+            } else {
+                return new Deflater(Deflater.DEFAULT_COMPRESSION, true);
+            }
+        }
+    }
+
+    // Releases the specified inflater to the list of available inflaters.
+    private void releaseDeflater(Deflater def) {
+        synchronized (deflaters) {
+            if (inflaters.size() < MAX_FLATER) {
+               def.reset();
+               deflaters.add(def);
+            } else {
+               def.end();
+            }
+        }
+    }
+
+    // End of central directory record
+    static class END {
+        int  disknum;
+        int  sdisknum;
+        int  endsub;     // endsub
+        int  centot;     // 4 bytes
+        long cenlen;     // 4 bytes
+        long cenoff;     // 4 bytes
+        int  comlen;     // comment length
+        byte[] comment;
+
+        /* members of Zip64 end of central directory locator */
+        int diskNum;
+        long endpos;
+        int disktot;
+
+        void write(OutputStream os, long offset) throws IOException {
+            boolean hasZip64 = false;
+            long xlen = cenlen;
+            long xoff = cenoff;
+            if (xlen >= ZIP64_MINVAL) {
+                xlen = ZIP64_MINVAL;
+                hasZip64 = true;
+            }
+            if (xoff >= ZIP64_MINVAL) {
+                xoff = ZIP64_MINVAL;
+                hasZip64 = true;
+            }
+            int count = centot;
+            if (count >= ZIP64_MINVAL32) {
+                count = ZIP64_MINVAL32;
+                hasZip64 = true;
+            }
+            if (hasZip64) {
+                long off64 = offset;
+                //zip64 end of central directory record
+                writeInt(os, ZIP64_ENDSIG);       // zip64 END record signature
+                writeLong(os, ZIP64_ENDHDR - 12); // size of zip64 end
+                writeShort(os, 45);               // version made by
+                writeShort(os, 45);               // version needed to extract
+                writeInt(os, 0);                  // number of this disk
+                writeInt(os, 0);                  // central directory start disk
+                writeLong(os, centot);            // number of directory entires on disk
+                writeLong(os, centot);            // number of directory entires
+                writeLong(os, cenlen);            // length of central directory
+                writeLong(os, cenoff);            // offset of central directory
+
+                //zip64 end of central directory locator
+                writeInt(os, ZIP64_LOCSIG);       // zip64 END locator signature
+                writeInt(os, 0);                  // zip64 END start disk
+                writeLong(os, off64);             // offset of zip64 END
+                writeInt(os, 1);                  // total number of disks (?)
+            }
+            writeInt(os, ENDSIG);                 // END record signature
+            writeShort(os, 0);                    // number of this disk
+            writeShort(os, 0);                    // central directory start disk
+            writeShort(os, count);                // number of directory entries on disk
+            writeShort(os, count);                // total number of directory entries
+            writeInt(os, xlen);                   // length of central directory
+            writeInt(os, xoff);                   // offset of central directory
+            if (comment != null) {            // zip file comment
+                writeShort(os, comment.length);
+                writeBytes(os, comment);
+            } else {
+                writeShort(os, 0);
+            }
+        }
+    }
+
+    // wrapper for the byte[] name
+    static class EntryName {
+        byte[] name;
+        int hashcode;    // node is hashable/hashed by its name
+
+        public EntryName (byte[] name) {
+            name(name);
+        }
+
+        void name(byte[] name) {
+            this.name = name;
+            this.hashcode = Arrays.hashCode(name);
+        }
+
+        public boolean equals(Object other) {
+            if (!(other instanceof EntryName))
+                return false;
+            return Arrays.equals(name, ((EntryName)other).name);
+        }
+
+        public int hashCode() {
+            return hashcode;
+        }
+    }
+
+    // can simply use Integer instead, if we don't use it to
+    // build a internal node tree.
+    static class IndexNode {
+        byte[] name;
+        int pos = -1;     // postion in cen table, -1 menas the
+                          // entry does not exists in zip file
+        IndexNode(byte[] name, int pos) {
+            this.name = name;
+            this.pos = pos;
+        }
+
+        IndexNode() {}
+
+        IndexNode sibling;
+        IndexNode child;  // 1st child
+    }
+
+    static class Entry extends IndexNode {
+
+        static final int CEN    = 1;    // entry read from cen
+        static final int NEW    = 2;    // updated contents in bytes or file
+        static final int FILECH = 3;    // fch update in "file"
+        static final int COPY   = 4;    // copy of a CEN entry
+
+        byte[] bytes;      // updated content bytes
+        Path   file;       // use tmp file to store bytes;
+        int    type = CEN; // default is the entry read from cen
+
+        // entry attributes
+        int    version;
+        int    flag;
+        int    method = -1;    // compression method
+        long   mtime  = -1;    // last modification time (in DOS time)
+        long   atime  = -1;    // last access time
+        long   ctime  = -1;    // create time
+        long   crc    = -1;    // crc-32 of entry data
+        long   csize  = -1;    // compressed size of entry data
+        long   size   = -1;    // uncompressed size of entry data
+        int    nlen;
+        int    elen;
+        byte[] extra;
+
+        // loc
+        long   startPos;
+        long   endPos;         // exclusive
+
+        // cen
+        int    versionMade;
+        int    disk;
+        int    attrs;
+        long   attrsEx;
+        long   locoff;
+
+        int    clen;
+        byte[] comment;
+
+        // ZIP64 flag
+        boolean hasZip64;
+
+        Entry() {}
+
+        Entry(byte[] name) {
+            this.name = name;
+            //this.nlen = name.length;
+            this.mtime  = javaToDosTime(System.currentTimeMillis());
+            this.crc       = 0;
+            this.size      = 0;
+            this.csize     = 0;
+            this.method    = METHOD_DEFLATED;
+        }
+
+        Entry(byte[] name, int type) {
+            this(name);
+            this.type = type;
+        }
+
+        Entry (byte[] name, Path file, int type) {
+            this(name, type);
+            this.file = file;
+            this.method = METHOD_STORED;
+        }
+
+        Entry(Entry e) {
+            this.version   = e.version;
+            this.name      = e.name;  // copyOf?
+            this.nlen      = e.nlen;
+            this.ctime     = e.ctime;
+            this.atime     = e.atime;
+            this.mtime     = e.mtime;
+            this.crc       = e.crc;
+            this.size      = e.size;
+            this.csize     = e.csize;
+            this.method    = e.method;
+            this.extra     = (e.extra == null)?
+                             null:Arrays.copyOf(e.extra, e.extra.length);
+            this.elen      = e.elen;
+            this.versionMade = e.versionMade;
+            this.disk      = e.disk;
+            this.attrs     = e.attrs;
+            this.attrsEx   = e.attrsEx;
+            this.locoff    = e.locoff;
+            this.clen      = e.clen;
+            this.comment   = (e.comment == null)?
+                             null:Arrays.copyOf(e.comment, e.comment.length);
+            this.startPos = e.startPos;
+            this.endPos   = e.endPos;
+            this.hasZip64 = e.hasZip64;;
+        }
+
+        Entry (Entry e, int type) {
+            this(e);
+            this.type = type;
+        }
+
+        boolean isDir() {
+            return name != null &&
+                   (name.length == 0 ||
+                    name[name.length - 1] == '/');
+        }
+
+        int version() throws ZipException {
+            if (method == METHOD_DEFLATED)
+                return 20;
+            else if (method == METHOD_STORED)
+                return 10;
+            throw new ZipException("unsupported compression method");
+        }
+
+        ///////////////////// CEN //////////////////////
+        static Entry readCEN(ByteBuffer cen, int pos) throws IOException
+        {
+            return new Entry().cen(cen, pos);
+        }
+
+        private Entry cen(ByteBuffer cen, int pos) throws IOException
+        {
+            if (CENSIG(cen, pos) != CENSIG)
+                zerror("invalid CEN header (bad signature)");
+            versionMade = CENVEM(cen, pos);
+            version     = CENVER(cen, pos);
+            flag        = CENFLG(cen, pos);
+            method      = CENHOW(cen, pos);
+            mtime       = CENTIM(cen, pos);
+            crc         = CENCRC(cen, pos);
+            csize       = CENSIZ(cen, pos);
+            size        = CENLEN(cen, pos);
+            nlen        = CENNAM(cen, pos);
+            elen        = CENEXT(cen, pos);
+            clen        = CENCOM(cen, pos);
+            disk        = CENDSK(cen, pos);
+            attrs       = CENATT(cen, pos);
+            attrsEx     = CENATX(cen, pos);
+            locoff      = CENOFF(cen, pos);
+
+            cen.position(pos + CENHDR);
+            name = new byte[nlen];
+            cen.get(name);
+
+            if (elen > 0) {
+                extra = new byte[elen];
+                cen.get(extra);
+                if (csize == ZIP64_MINVAL || size == ZIP64_MINVAL ||
+                    locoff == ZIP64_MINVAL) {
+                    int off = 0;
+                    while (off + 4 < elen) {
+                        // extra spec: HeaderID+DataSize+Data
+                        int sz = SH(extra, off + 2);
+                        if (SH(extra, off) == EXTID_ZIP64) {
+                            off += 4;
+                            if (size == ZIP64_MINVAL) {
+                                // if invalid zip64 extra fields, just skip
+                                if (sz < 8 || (off + 8) > elen)
+                                    break;
+                                size = LL(extra, off);
+                                sz -= 8;
+                                off += 8;
+                            }
+                            if (csize == ZIP64_MINVAL) {
+                                if (sz < 8 || (off + 8) > elen)
+                                    break;
+                                csize = LL(extra, off);
+                                sz -= 8;
+                                off += 8;
+                            }
+                            if (locoff == ZIP64_MINVAL) {
+                                if (sz < 8 || (off + 8) > elen)
+                                    break;
+                                locoff = LL(extra, off);
+                                sz -= 8;
+                                off += 8;
+                            }
+                            break;
+                        }
+                        off += (sz + 4);
+                    }
+                }
+            }
+            if (clen > 0) {
+                comment = new byte[clen];
+                cen.get(comment);
+            }
+            return this;
+        }
+
+        int writeCEN(OutputStream os) throws IOException
+        {
+            int written  = CENHDR;
+            int version0 = version();
+
+            long csize0  = csize;
+            long size0   = size;
+            long locoff0 = locoff;
+            int e64len   = 0;
+
+            // confirm size/length
+            nlen = (name != null) ? name.length : 0;
+            elen = (extra != null) ? extra.length : 0;
+            clen = (comment != null) ? comment.length : 0;
+
+            boolean hasZip64 = false;
+            if (csize >= ZIP64_MINVAL) {
+                csize0 = ZIP64_MINVAL;
+                e64len += 8;                 // csize(8)
+                hasZip64 = true;
+            }
+            if (size >= ZIP64_MINVAL) {
+                size0 = ZIP64_MINVAL;        // size(8)
+                e64len += 8;
+                hasZip64 = true;
+            }
+            if (locoff >= ZIP64_MINVAL) {
+                locoff0 = ZIP64_MINVAL;
+                e64len += 8;                 // offset(8)
+                hasZip64 = true;
+            }
+            writeInt(os, CENSIG);            // CEN header signature
+            if (hasZip64) {
+                writeShort(os, 45);          // ver 4.5 for zip64
+                writeShort(os, 45);
+            } else {
+                writeShort(os, version0);    // version made by
+                writeShort(os, version0);    // version needed to extract
+            }
+            writeShort(os, flag);            // general purpose bit flag
+            writeShort(os, method);          // compression method
+            writeInt(os, mtime);             // last modification time
+            writeInt(os, crc);               // crc-32
+            writeInt(os, csize0);            // compressed size
+            writeInt(os, size0);             // uncompressed size
+            writeShort(os, name.length);
+
+            if (hasZip64) {
+                // + headid(2) + datasize(2)
+                writeShort(os, e64len + 4 + elen);
+            } else {
+                writeShort(os, elen);
+            }
+            if (comment != null) {
+                writeShort(os, Math.min(clen, 0xffff));
+            } else {
+                writeShort(os, 0);
+            }
+            writeShort(os, 0);              // starting disk number
+            writeShort(os, 0);              // internal file attributes (unused)
+            writeInt(os, 0);                // external file attributes (unused)
+            writeInt(os, locoff0);          // relative offset of local header
+            writeBytes(os, name);
+            if (hasZip64) {
+                writeShort(os, EXTID_ZIP64);// Zip64 extra
+                writeShort(os, e64len);
+                if (size0 == ZIP64_MINVAL)
+                    writeLong(os, size);
+                if (csize0 == ZIP64_MINVAL)
+                    writeLong(os, csize);
+                if (locoff0 == ZIP64_MINVAL)
+                    writeLong(os, locoff);
+            }
+            if (extra != null) {
+                writeBytes(os, extra);
+            }
+            if (comment != null) {
+                //TBD: 0, Math.min(commentBytes.length, 0xffff));
+                writeBytes(os, comment);
+            }
+            return CENHDR + nlen + elen + clen + (hasZip64?(e64len + 4):0);
+        }
+
+        ///////////////////// LOC //////////////////////
+        static Entry readLOC(ZipFileSystem zf, long pos)
+            throws IOException
+        {
+            return readLOC(zf, pos, new byte[1024]);
+        }
+
+        static Entry readLOC(ZipFileSystem zf, long pos, byte[] buf)
+            throws IOException
+        {
+            return new Entry().loc(zf, pos, buf);
+        }
+
+        Entry loc(ZipFileSystem zf, long pos, byte[] buf)
+            throws IOException
+        {
+            assert (buf.length >= LOCHDR);
+            if (zf.readFullyAt(buf, 0, LOCHDR , pos) != LOCHDR) {
+                throw new ZipException("loc: reading failed");
+            }
+            if (LOCSIG(buf) != LOCSIG) {
+                throw new ZipException("loc: wrong sig ->"
+                                       + Long.toString(LOCSIG(buf), 16));
+            }
+            startPos = pos;
+            version  = LOCVER(buf);
+            flag     = LOCFLG(buf);
+            method   = LOCHOW(buf);
+            mtime    = LOCTIM(buf);
+            crc      = LOCCRC(buf);
+            csize    = LOCSIZ(buf);
+            size     = LOCLEN(buf);
+            nlen     = LOCNAM(buf);
+            elen     = LOCEXT(buf);
+
+            name = new byte[nlen];
+            if (zf.readFullyAt(name, 0, nlen, pos + LOCHDR) != nlen) {
+                throw new ZipException("loc: name reading failed");
+            }
+            if (elen > 0) {
+                extra = new byte[elen];
+                if (zf.readFullyAt(extra, 0, elen, pos + LOCHDR + nlen)
+                    != elen) {
+                    throw new ZipException("loc: ext reading failed");
+                }
+            }
+            pos += (LOCHDR + nlen + elen);
+            if ((flag & FLAG_DATADESCR) != 0) {
+                // Data Descriptor
+                Entry e = zf.getEntry0(name);  // get the size/csize from cen
+                if (e == null)
+                    throw new ZipException("loc: name not found in cen");
+                size = e.size;
+                csize = e.csize;
+                pos += (method == METHOD_STORED ? size : csize);
+                if (size >= ZIP64_MINVAL || csize >= ZIP64_MINVAL)
+                    pos += 24;
+                else
+                    pos += 16;
+            } else {
+                boolean hasZip64 = false;
+                if (extra != null &&
+                    (size == ZIP64_MINVAL || csize == ZIP64_MINVAL)) {
+                    // zip64 ext: must include both size and csize
+                    int off = 0;
+                    while (off + 20 < elen) {    // HeaderID+DataSize+Data
+                        int sz = SH(extra, off + 2);
+                        if (SH(extra, off) == EXTID_ZIP64 && sz == 16) {
+                            size = LL(extra, off + 4);
+                            csize = LL(extra, off + 12);
+                            hasZip64 = true;
+                            break;
+                        }
+                        off += (sz + 4);
+                    }
+                }
+                pos += (method == METHOD_STORED ? size : csize);
+            }
+            endPos = pos;
+            return this;
+        }
+
+        int writeLOC(OutputStream os)
+            throws IOException
+        {
+            writeInt(os, LOCSIG);               // LOC header signature
+
+            int version = version();
+            if ((flag & FLAG_DATADESCR) != 0) {
+                writeShort(os, version());      // version needed to extract
+                writeShort(os, flag);           // general purpose bit flag
+                writeShort(os, method);         // compression method
+                writeInt(os, mtime);            // last modification time
+
+                // store size, uncompressed size, and crc-32 in data descriptor
+                // immediately following compressed entry data
+                writeInt(os, 0);
+                writeInt(os, 0);
+                writeInt(os, 0);
+            } else {
+                if (csize >= ZIP64_MINVAL || size >= ZIP64_MINVAL) {
+                    hasZip64 = true;
+                    writeShort(os, 45);         // ver 4.5 for zip64
+                } else {
+                    writeShort(os, version());  // version needed to extract
+                }
+                writeShort(os, flag);           // general purpose bit flag
+                writeShort(os, method);         // compression method
+                writeInt(os, mtime);            // last modification time
+                writeInt(os, crc);              // crc-32
+                if (hasZip64) {
+                    writeInt(os, ZIP64_MINVAL);
+                    writeInt(os, ZIP64_MINVAL);
+                    //TBD:  e.elen += 20;       //headid(2) + size(2) + size(8) + csize(8)
+                } else {
+                    writeInt(os, csize);        // compressed size
+                    writeInt(os, size);         // uncompressed size
+                }
+            }
+            writeShort(os, name.length);
+            writeShort(os, elen + (hasZip64 ? 20 : 0));
+            writeBytes(os, name);
+            if (hasZip64) {
+                // TBD: should we update extra directory?
+                writeShort(os, EXTID_ZIP64);
+                writeShort(os, 16);
+                writeLong(os, size);
+                writeLong(os, csize);
+            }
+            if (extra != null) {
+                writeBytes(os, extra);
+            }
+            return LOCHDR + name.length + elen + (hasZip64 ? 20 : 0);
+        }
+
+        // Data Descriptior
+        int writeEXT(OutputStream os)
+            throws IOException
+        {
+            writeInt(os, EXTSIG);           // EXT header signature
+            writeInt(os, crc);              // crc-32
+            if (csize >= ZIP64_MINVAL || size >= ZIP64_MINVAL) {
+                writeLong(os, csize);
+                writeLong(os, size);
+                return 24;
+            } else {
+                writeInt(os, csize);        // compressed size
+                writeInt(os, size);         // uncompressed size
+                return 16;
+            }
+        }
+
+        // read NTFS, UNIX and ZIP64 data from cen.extra
+        void readExtra() {
+            if (extra == null)
+                return;
+            int elen = extra.length;
+            int off = 0;
+            while (off + 4 < elen) {
+                // extra spec: HeaderID+DataSize+Data
+                int sz = SH(extra, off + 2);
+                int tag = SH(extra, off);
+                off += 4;
+                int pos = off;
+                if (pos + sz > elen)         // invalid data
+                    break;
+                switch (tag) {
+                case EXTID_ZIP64 :
+                    if (size == ZIP64_MINVAL) {
+                        if (pos + 8 > elen)  // invalid zip64 extra
+                            break;           // fields, just skip
+                        size = LL(extra, pos);
+                        pos += 8;
+                    }
+                    if (csize == ZIP64_MINVAL) {
+                        if (pos + 8 > elen)
+                            break;
+                        csize = LL(extra, pos);
+                        pos += 8;
+                    }
+                    if (locoff == ZIP64_MINVAL) {
+                        if (pos + 8 > elen)
+                            break;
+                        locoff = LL(extra, pos);
+                        pos += 8;
+                    }
+                    break;
+                case EXTID_NTFS:
+                    pos += 4;    // reserved 4 bytes
+                    if (SH(extra, pos) !=  0x0001)
+                        break;
+                    if (SH(extra, pos + 2) != 24)
+                        break;
+                    mtime = LL(extra, pos + 4);
+                    atime = LL(extra, pos + 12);
+                    ctime = LL(extra, pos + 20);
+                    break;
+                case EXTID_UNIX:
+                    atime = LG(extra, pos);
+                    mtime = LG(extra, pos + 4);
+                    break;
+                default:    // unknow
+                }
+                off += sz;
+            }
+        }
+    }
+
+    private static class ExChannelCloser  {
+        Path path;
+        SeekableByteChannel ch;
+        Set<InputStream> streams;
+        ExChannelCloser(Path path,
+                        SeekableByteChannel ch,
+                        Set<InputStream> streams)
+        {
+            this.path = path;
+            this.ch = ch;
+            this.streams = streams;
+        }
+    }
+
+    // ZIP directory has two issues:
+    // (1) ZIP spec does not require the ZIP file to include
+    //     directory entry
+    // (2) all entries are not stored/organized in a "tree"
+    //     structure.
+    // A possible solution is to build the node tree ourself as
+    // implemented below.
+    private HashMap<EntryName, IndexNode> dirs;
+    private IndexNode root;
+    private IndexNode addToDir(EntryName child) {
+        IndexNode cinode = dirs.get(child);
+        if (cinode != null)
+            return cinode;
+
+        byte[] cname = child.name;
+        byte[] pname = getParent(cname);
+        IndexNode pinode;
+
+        if (pname != null)
+            pinode = addToDir(new EntryName(pname));
+        else
+            pinode = root;
+        cinode = inodes.get(child);
+        if (cname[cname.length -1] != '/') {  // not a dir
+            cinode.sibling = pinode.child;
+            pinode.child = cinode;
+            return null;
+        }
+        cinode = dirs.get(child);
+        if (cinode == null)  // pseudo directry entry
+            cinode = new IndexNode(cname, -1);
+        cinode.sibling = pinode.child;
+        pinode.child = cinode;
+
+        dirs.put(child, cinode);
+        return cinode;
+    }
+
+    private HashMap<EntryName, IndexNode> getDirs()
+        throws IOException
+    {
+        if (hasUpdate)
+            sync();
+        if (dirs != null)
+            return dirs;
+        dirs = new HashMap<EntryName, IndexNode>();
+        byte[] empty = new byte[0];
+        root = new IndexNode(empty, -1);
+        dirs.put(new EntryName(empty), root);
+
+        EntryName[] names = inodes.keySet().toArray(new EntryName[0]);
+        int i = names.length;
+        while (--i >= 0) {
+            addToDir(names[i]);
+        }
+        // for (int i EntryName en : inodes.keySet()) {
+        //     addToDir(en);
+        // }
+        return dirs;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystemProvider.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+import java.nio.file.FileRef;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystemNotFoundException;
+import java.nio.file.FileSystemAlreadyExistsException;
+import java.nio.file.OpenOption;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.ProviderMismatchException;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.file.spi.FileSystemProvider;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/*
+ *
+ * @author  Xueming Shen, Rajendra Gutupalli, Jaya Hangal
+ */
+
+public class ZipFileSystemProvider extends FileSystemProvider {
+    private final Map<Path, ZipFileSystem> filesystems = new HashMap<>();
+
+    public ZipFileSystemProvider() {}
+
+    @Override
+    public String getScheme() {
+        return "zip";
+    }
+
+    protected Path uriToPath(URI uri) {
+        String scheme = uri.getScheme();
+        if ((scheme == null) || !scheme.equalsIgnoreCase(getScheme())) {
+            throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'");
+        }
+        try {
+            return Paths.get(new URI("file", uri.getHost(), uri.getPath(), null))
+                        .toAbsolutePath();
+        } catch (URISyntaxException e) {
+            throw new AssertionError(e); //never thrown
+        }
+    }
+
+    @Override
+    public FileSystem newFileSystem(URI uri, Map<String, ?> env)
+        throws IOException
+    {
+        return newFileSystem(uriToPath(uri), env);
+    }
+
+    @Override
+    public FileSystem newFileSystem(FileRef file, Map<String, ?> env)
+        throws IOException
+    {
+        if (!(file instanceof Path))
+            throw new UnsupportedOperationException();
+        Path path = (Path)file;
+        if (!path.toUri().getScheme().equalsIgnoreCase("file")) {
+            throw new UnsupportedOperationException();
+        }
+        return newFileSystem(path, env);
+    }
+
+    private FileSystem newFileSystem(Path path, Map<String, ?> env)
+        throws IOException
+    {
+        synchronized(filesystems) {
+            if (filesystems.containsKey(path))
+                throw new FileSystemAlreadyExistsException();
+            ZipFileSystem zipfs = new ZipFileSystem(this, path, env);
+            filesystems.put(path, zipfs);
+            return zipfs;
+        }
+    }
+
+    @Override
+    public Path getPath(URI uri) {
+        FileSystem fs = getFileSystem(uri);
+        String fragment = uri.getFragment();
+        if (fragment == null) {
+            throw new IllegalArgumentException("URI: "
+                + uri
+                + " does not contain path fragment ex. zip:///c:/foo.zip#/BAR");
+        }
+        return fs.getPath(fragment);
+    }
+
+    @Override
+    public FileChannel newFileChannel(Path path,
+            Set<? extends OpenOption> options,
+            FileAttribute<?>... attrs)
+            throws IOException
+    {
+        if (path == null)
+            throw new NullPointerException("path is null");
+        if (path instanceof ZipPath)
+            return ((ZipPath)path).newFileChannel(options, attrs);
+        throw new ProviderMismatchException();
+    }
+
+    @Override
+    public FileSystem getFileSystem(URI uri) {
+        synchronized (filesystems) {
+            ZipFileSystem zipfs = filesystems.get(uriToPath(uri));
+            if (zipfs == null)
+                throw new FileSystemNotFoundException();
+            return zipfs;
+        }
+    }
+
+    void removeFileSystem(Path zfpath) {
+        synchronized (filesystems) {
+            filesystems.remove(zfpath);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipInfo.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+import java.io.PrintStream;
+import java.nio.file.Paths;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+import com.sun.nio.zipfs.ZipFileSystem.Entry;
+import static com.sun.nio.zipfs.ZipConstants.*;
+import static com.sun.nio.zipfs.ZipUtils.*;
+
+/**
+ * Print the loc and cen tables of the ZIP file
+ *
+ * @author  Xueming Shen
+ */
+
+public class ZipInfo {
+
+    public static void main(String[] args) throws Throwable {
+        if (args.length < 2) {
+            print("Usage: java ZipInfo [cen|loc] zfname");
+        } else {
+            Map<String, ?> env = Collections.emptyMap();
+            ZipFileSystem zfs = (ZipFileSystem)(new ZipFileSystemProvider()
+                                    .newFileSystem(Paths.get(args[1]), env));
+
+            long pos = 0;
+
+            if ("loc".equals(args[0])) {
+                print("[Local File Header]%n");
+                byte[] buf = new byte[1024];
+                for (int i = 0; i < zfs.getEntryNames().length; i++) {
+                    Entry loc = Entry.readLOC(zfs, pos, buf);
+                    print("--------loc[%x]--------%n", pos);
+                    printLOC(loc);
+                    pos = loc.endPos;
+                }
+            } if ("cen".equals(args[0])) {
+                int i = 0;
+                Iterator<ZipFileSystem.IndexNode> itr = zfs.inodes.values().iterator();
+                print("[Central Directory Header]%n");
+                while (itr.hasNext()) {
+                    Entry cen = Entry.readCEN(zfs.cen, itr.next().pos);
+                    print("--------cen[%d]--------%n", i);
+                    printCEN(cen);
+                    i++;
+                }
+            }
+            zfs.close();
+        }
+    }
+
+    static void print(String fmt, Object... objs) {
+        System.out.printf(fmt, objs);
+    }
+
+    static void printLOC(Entry loc) {
+        print("  [%x, %x]%n", loc.startPos, loc.endPos);
+        print("  Signature   :     %8x%n", LOCSIG);
+        print("  Version     :         %4x    [%d.%d]%n",
+                  loc.version, loc. version/10, loc. version%10);
+        print("  Flag        :         %4x%n", loc.flag);
+        print("  Method      :         %4x%n", loc. method);
+        print("  LastMTime   :     %8x    [%tc]%n",
+                  loc.mtime, dosToJavaTime(loc.mtime));
+        print("  CRC         :     %8x%n", loc.crc);
+        print("  CSize       :     %8x%n", loc.csize);
+        print("  Size        :     %8x%n", loc.size);
+        print("  NameLength  :         %4x    [%s]%n",
+                  loc.nlen, new String(loc.name));
+        print("  ExtraLength :         %4x%n", loc.elen);
+        if (loc.hasZip64)
+            print(" *ZIP64*%n");
+    }
+
+    static void printCEN(Entry cen) {
+        print("  Signature   :     %08x%n", CENSIG);
+        print("  VerMadeby   :         %4x    [%d.%d]%n",
+                  cen.versionMade, cen.versionMade/10, cen.versionMade%10);
+        print("  VerExtract  :         %4x    [%d.%d]%n",
+                  cen.version, cen.version/10, cen.version%10);
+        print("  Flag        :         %4x%n", cen.flag);
+        print("  Method      :         %4x%n", cen.method);
+        print("  LastMTime   :     %8x    [%tc]%n",
+                  cen.mtime, dosToJavaTime(cen.mtime));
+        print("  CRC         :     %8x%n", cen.crc);
+        print("  CSize       :     %8x%n", cen.csize);
+        print("  Size        :     %8x%n", cen.size);
+        print("  NameLen     :         %4x    [%s]%n",
+                  cen.nlen, new String(cen.name));
+        print("  ExtraLen    :         %4x%n", cen.elen);
+        print("  CommentLen  :         %4x%n", cen.clen);
+        print("  DiskStart   :         %4x%n", cen.disk);
+        print("  Attrs       :         %4x%n", cen.attrs);
+        print("  AttrsEx     :     %8x%n", cen.attrsEx);
+        print("  LocOff      :     %8x%n", cen.locoff);
+        if (cen.hasZip64)
+            print(" *ZIP64*%n");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipPath.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,964 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+import java.io.File;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.channels.SeekableByteChannel;
+import java.nio.file.*;
+import java.nio.file.DirectoryStream.Filter;
+import java.nio.file.spi.FileSystemProvider;
+import java.nio.file.attribute.BasicFileAttributeView;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.file.attribute.FileAttributeView;
+import java.nio.file.attribute.FileTime;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import static java.nio.file.StandardOpenOption.*;
+import static java.nio.file.StandardCopyOption.*;
+
+/**
+ *
+ * @author  Xueming Shen, Rajendra Gutupalli,Jaya Hangal
+ */
+
+public class ZipPath extends Path {
+
+    private final ZipFileSystem zfs;
+    private final byte[] path;
+    private volatile int[] offsets;
+    private int hashcode = 0;  // cached hashcode (created lazily)
+
+    ZipPath(ZipFileSystem zfs, byte[] path) {
+        this(zfs, path, false);
+    }
+
+    ZipPath(ZipFileSystem zfs, byte[] path, boolean normalized)
+    {
+        this.zfs = zfs;
+        if (normalized)
+            this.path = path;
+        else
+            this.path = normalize(path);
+    }
+
+    @Override
+    public ZipPath getRoot() {
+        if (this.isAbsolute())
+            return new ZipPath(zfs, new byte[]{path[0]});
+        else
+            return null;
+    }
+
+    @Override
+    public Path getName() {
+        initOffsets();
+        int count = offsets.length;
+        if (count == 0)
+            return null;  // no elements so no name
+        if (count == 1 && path[0] != '/')
+            return this;
+        int lastOffset = offsets[count-1];
+        int len = path.length - lastOffset;
+        byte[] result = new byte[len];
+        System.arraycopy(path, lastOffset, result, 0, len);
+        return new ZipPath(zfs, result);
+    }
+
+    @Override
+    public ZipPath getParent() {
+        initOffsets();
+        int count = offsets.length;
+        if (count == 0)    // no elements so no parent
+            return null;
+        int len = offsets[count-1] - 1;
+        if (len <= 0)      // parent is root only (may be null)
+            return getRoot();
+        byte[] result = new byte[len];
+        System.arraycopy(path, 0, result, 0, len);
+        return new ZipPath(zfs, result);
+    }
+
+    @Override
+    public int getNameCount() {
+        initOffsets();
+        return offsets.length;
+    }
+
+    @Override
+    public ZipPath getName(int index) {
+        initOffsets();
+        if (index < 0 || index >= offsets.length)
+            throw new IllegalArgumentException();
+        int begin = offsets[index];
+        int len;
+        if (index == (offsets.length-1))
+            len = path.length - begin;
+        else
+            len = offsets[index+1] - begin - 1;
+        // construct result
+        byte[] result = new byte[len];
+        System.arraycopy(path, begin, result, 0, len);
+        return new ZipPath(zfs, result);
+    }
+
+    @Override
+    public ZipPath subpath(int beginIndex, int endIndex) {
+        initOffsets();
+        if (beginIndex < 0 ||
+            beginIndex >=  offsets.length ||
+            endIndex > offsets.length ||
+            beginIndex >= endIndex)
+            throw new IllegalArgumentException();
+
+        // starting offset and length
+        int begin = offsets[beginIndex];
+        int len;
+        if (endIndex == offsets.length)
+            len = path.length - begin;
+        else
+            len = offsets[endIndex] - begin - 1;
+        // construct result
+        byte[] result = new byte[len];
+        System.arraycopy(path, begin, result, 0, len);
+        return new ZipPath(zfs, result);
+    }
+
+    @Override
+    public ZipPath toRealPath(boolean resolveLinks) throws IOException {
+        ZipPath realPath = new ZipPath(zfs, getResolvedPath());
+        realPath.checkAccess();
+        return realPath;
+    }
+
+    @Override
+    public boolean isHidden() {
+        return false;
+    }
+
+    @Override
+    public ZipPath toAbsolutePath() {
+        if (isAbsolute()) {
+            return this;
+        } else {
+            //add / bofore the existing path
+            byte[] defaultdir = zfs.getDefaultDir().path;
+            int defaultlen = defaultdir.length;
+            boolean endsWith = (defaultdir[defaultlen - 1] == '/');
+            byte[] t = null;
+            if (endsWith)
+                t = new byte[defaultlen + path.length];
+            else
+                t = new byte[defaultlen + 1 + path.length];
+            System.arraycopy(defaultdir, 0, t, 0, defaultlen);
+            if (!endsWith)
+                t[defaultlen++] = '/';
+            System.arraycopy(path, 0, t, defaultlen, path.length);
+            return new ZipPath(zfs, t, true);  // normalized
+        }
+    }
+
+    @Override
+    public URI toUri() {
+        String zfPath = zfs.toString();
+        if (File.separatorChar == '\\')  // replace all separators by '/'
+            zfPath = "/" + zfPath.replace("\\", "/");
+        try {
+            return new URI("zip", "",
+                           zfPath,
+                           zfs.getString(toAbsolutePath().path));
+        } catch (Exception ex) {
+            throw new AssertionError(ex);
+        }
+    }
+
+    private boolean equalsNameAt(ZipPath other, int index) {
+        int mbegin = offsets[index];
+        int mlen = 0;
+        if (index == (offsets.length-1))
+            mlen = path.length - mbegin;
+        else
+            mlen = offsets[index + 1] - mbegin - 1;
+        int obegin = other.offsets[index];
+        int olen = 0;
+        if (index == (other.offsets.length - 1))
+            olen = other.path.length - obegin;
+        else
+            olen = other.offsets[index + 1] - obegin - 1;
+        if (mlen != olen)
+            return false;
+        int n = 0;
+        while(n < mlen) {
+            if (path[mbegin + n] != other.path[obegin + n])
+                return false;
+            n++;
+        }
+        return true;
+    }
+
+    @Override
+    public Path relativize(Path other) {
+        final ZipPath o = checkPath(other);
+        if (o.equals(this))
+            return null;
+        if (/* this.getFileSystem() != o.getFileSystem() || */
+            this.isAbsolute() != o.isAbsolute()) {
+            throw new IllegalArgumentException();
+        }
+        int mc = this.getNameCount();
+        int oc = o.getNameCount();
+        int n = Math.min(mc, oc);
+        int i = 0;
+        while (i < n) {
+            if (!equalsNameAt(o, i))
+                break;
+            i++;
+        }
+        int dotdots = mc - i;
+        int len = dotdots * 3 - 1;
+        if (i < oc)
+            len += (o.path.length - o.offsets[i] + 1);
+        byte[] result = new byte[len];
+
+        int pos = 0;
+        while (dotdots > 0) {
+            result[pos++] = (byte)'.';
+            result[pos++] = (byte)'.';
+            if (pos < len)       // no tailing slash at the end
+                result[pos++] = (byte)'/';
+            dotdots--;
+        }
+        if (i < oc)
+            System.arraycopy(o.path, o.offsets[i],
+                             result, pos,
+                             o.path.length - o.offsets[i]);
+        return new ZipPath(getFileSystem(), result);
+    }
+
+    @Override
+    public ZipFileSystem getFileSystem() {
+        return zfs;
+    }
+
+    @Override
+    public boolean isAbsolute() {
+        return (this.path[0] == '/');
+    }
+
+    @Override
+    public ZipPath resolve(Path other) {
+        if (other == null)
+            return this;
+        final ZipPath o = checkPath(other);
+        if (o.isAbsolute())
+            return o;
+        byte[] resolved = null;
+        if (this.path[path.length - 1] == '/') {
+            resolved = new byte[path.length + o.path.length];
+            System.arraycopy(path, 0, resolved, 0, path.length);
+            System.arraycopy(o.path, 0, resolved, path.length, o.path.length);
+        } else {
+            resolved = new byte[path.length + 1 + o.path.length];
+            System.arraycopy(path, 0, resolved, 0, path.length);
+            resolved[path.length] = '/';
+            System.arraycopy(o.path, 0, resolved, path.length + 1, o.path.length);
+        }
+        return new ZipPath(zfs, resolved);
+    }
+
+    @Override
+    public ZipPath resolve(String other) {
+        return resolve(getFileSystem().getPath(other));
+    }
+
+    @Override
+    public boolean startsWith(Path other) {
+        final ZipPath o = checkPath(other);
+        if (o.isAbsolute() != this.isAbsolute())
+            return false;
+        final int oCount = o.getNameCount();
+        if (getNameCount() < oCount)
+            return false;
+        for (int i = 0; i < oCount; i++) {
+            if (!o.getName(i).equals(getName(i)))
+                return false;
+        }
+        return true;
+    }
+
+    @Override
+    public boolean endsWith(Path other) {
+        final ZipPath o = checkPath(other);
+        if (o.isAbsolute())
+            return this.isAbsolute() ? this.equals(o) : false;
+        int i = o.getNameCount();
+        int j = this.getNameCount();
+        if (j < i)
+            return false;
+        for (--i, --j; i >= 0; i--, j--) {
+            if (!o.getName(i).equals(this.getName(j)))
+                return false;
+        }
+        return true;
+    }
+
+    @Override
+    public Path normalize() {
+        byte[] resolved = getResolved();
+        if (resolved == path)    // no change
+            return this;
+        if (resolved.length == 0)
+            return null;
+        return new ZipPath(zfs, resolved, true);
+    }
+
+    private ZipPath checkPath(Path path) {
+        if (path == null)
+            throw new NullPointerException();
+        if (!(path instanceof ZipPath))
+            throw new ProviderMismatchException();
+        return (ZipPath) path;
+    }
+
+    // create offset list if not already created
+    private void initOffsets() {
+        if (offsets == null) {
+            int count, index;
+            // count names
+            count = 0;
+            index = 0;
+            while (index < path.length) {
+                byte c = path[index++];
+                if (c != '/') {
+                    count++;
+                    while (index < path.length && path[index] != '/')
+                        index++;
+                }
+            }
+            // populate offsets
+            int[] result = new int[count];
+            count = 0;
+            index = 0;
+            while (index < path.length) {
+                byte c = path[index];
+                if (c == '/') {
+                    index++;
+                } else {
+                    result[count++] = index++;
+                    while (index < path.length && path[index] != '/')
+                        index++;
+                }
+            }
+            synchronized (this) {
+                if (offsets == null)
+                    offsets = result;
+            }
+        }
+    }
+
+    // resolved path for locating zip entry inside the zip file,
+    // the result path does not contain ./ and .. components
+    private volatile byte[] resolved = null;
+    byte[] getResolvedPath() {
+        byte[] r = resolved;
+        if (r == null) {
+            if (isAbsolute())
+                r = getResolved();
+            else
+                r = toAbsolutePath().getResolvedPath();
+            if (r[0] == '/')
+                r = Arrays.copyOfRange(r, 1, r.length);
+            resolved = r;
+        }
+        return resolved;
+    }
+
+    // removes redundant slashs, replace "\" to zip separator "/"
+    // and check for invalid characters
+    private byte[] normalize(byte[] path) {
+        if (path.length == 0)
+            return path;
+        byte prevC = 0;
+        for (int i = 0; i < path.length; i++) {
+            byte c = path[i];
+            if (c == '\\')
+                return normalize(path, i);
+            if (c == (byte)'/' && prevC == '/')
+                return normalize(path, i - 1);
+            if (c == '\u0000')
+                throw new InvalidPathException(zfs.getString(path),
+                                               "Path: nul character not allowed");
+            prevC = c;
+        }
+        return path;
+    }
+
+    private byte[] normalize(byte[] path, int off) {
+        byte[] to = new byte[path.length];
+        int n = 0;
+        while (n < off) {
+            to[n] = path[n];
+            n++;
+        }
+        int m = n;
+        byte prevC = 0;
+        while (n < path.length) {
+            byte c = path[n++];
+            if (c == (byte)'\\')
+                c = (byte)'/';
+            if (c == (byte)'/' && prevC == (byte)'/')
+                continue;
+            if (c == '\u0000')
+                throw new InvalidPathException(zfs.getString(path),
+                                               "Path: nul character not allowed");
+            to[m++] = c;
+            prevC = c;
+        }
+        if (m > 1 && to[m - 1] == '/')
+            m--;
+        return (m == to.length)? to : Arrays.copyOf(to, m);
+    }
+
+    // Remove DotSlash(./) and resolve DotDot (..) components
+    private byte[] getResolved() {
+        if (path.length == 0)
+            return path;
+        for (int i = 0; i < path.length; i++) {
+            byte c = path[i];
+            if (c == (byte)'.')
+                return resolve0();
+        }
+        return path;
+    }
+
+    // TBD: performance, avoid initOffsets
+    private byte[] resolve0() {
+        byte[] to = new byte[path.length];
+        int nc = getNameCount();
+        int[] lastM = new int[nc];
+        int lastMOff = -1;
+        int m = 0;
+        for (int i = 0; i < nc; i++) {
+            int n = offsets[i];
+            int len = (i == offsets.length - 1)?
+                      (path.length - n):(offsets[i + 1] - n - 1);
+            if (len == 1 && path[n] == (byte)'.')
+                continue;
+            if (len == 2 && path[n] == '.' && path[n + 1] == '.') {
+                if (lastMOff >= 0) {
+                    m = lastM[lastMOff--];  // retreat
+                    continue;
+                }
+                if (path[0] == '/') {  // "/../xyz" skip
+                    if (m == 0)
+                        to[m++] = '/';
+                } else {               // "../xyz" -> "../xyz"
+                    if (m != 0 && to[m-1] != '/')
+                        to[m++] = '/';
+                    while (len-- > 0)
+                        to[m++] = path[n++];
+                }
+                continue;
+            }
+            if (m == 0 && path[0] == '/' ||   // absolute path
+                m != 0 && to[m-1] != '/') {   // not the first name
+                to[m++] = '/';
+            }
+            lastM[++lastMOff] = m;
+            while (len-- > 0)
+                to[m++] = path[n++];
+        }
+        if (m > 1 && to[m - 1] == '/')
+            m--;
+        return (m == to.length)? to : Arrays.copyOf(to, m);
+    }
+
+    @Override
+    public String toString() {
+        return zfs.getString(path);
+    }
+
+    @Override
+    public int hashCode() {
+        int h = hashcode;
+        if (h == 0)
+            hashcode = h = Arrays.hashCode(path);
+        return h;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return obj != null &&
+               obj instanceof ZipPath &&
+               this.zfs == ((ZipPath)obj).zfs &&
+               compareTo((Path) obj) == 0;
+    }
+
+    @Override
+    public int compareTo(Path other) {
+        final ZipPath o = checkPath(other);
+        int len1 = this.path.length;
+        int len2 = o.path.length;
+
+        int n = Math.min(len1, len2);
+        byte v1[] = this.path;
+        byte v2[] = o.path;
+
+        int k = 0;
+        while (k < n) {
+            int c1 = v1[k] & 0xff;
+            int c2 = v2[k] & 0xff;
+            if (c1 != c2)
+                return c1 - c2;
+            k++;
+        }
+        return len1 - len2;
+    }
+
+    @Override
+    public Path createSymbolicLink(
+            Path target, FileAttribute<?>... attrs) throws IOException {
+        throw new UnsupportedOperationException("Not supported.");
+    }
+
+    @Override
+    public Path createLink(
+            Path existing) throws IOException {
+        throw new UnsupportedOperationException("Not supported.");
+    }
+
+    @Override
+    public Path readSymbolicLink() throws IOException {
+        throw new UnsupportedOperationException("Not supported.");
+    }
+
+    @Override
+    public Path createDirectory(FileAttribute<?>... attrs)
+        throws IOException
+    {
+        zfs.createDirectory(getResolvedPath(), attrs);
+        return this;
+    }
+
+    public final Path createFile(FileAttribute<?>... attrs)
+        throws IOException
+    {
+        OutputStream os = newOutputStream(CREATE_NEW, WRITE);
+        try {
+            os.close();
+        } catch (IOException x) {}
+        return this;
+    }
+
+    @Override
+    public InputStream newInputStream(OpenOption... options)
+            throws IOException {
+        if (options.length > 0) {
+            for (OpenOption opt : options) {
+                if (opt != READ)
+                    throw new UnsupportedOperationException("'" + opt + "' not allowed");
+            }
+        }
+        return zfs.newInputStream(getResolvedPath());
+    }
+
+    private static final DirectoryStream.Filter<Path> acceptAllFilter =
+        new DirectoryStream.Filter<Path>() {
+            @Override public boolean accept(Path entry) { return true; }
+        };
+
+    @Override
+    public final DirectoryStream<Path> newDirectoryStream() throws IOException {
+        return newDirectoryStream(acceptAllFilter);
+    }
+
+    @Override
+    public DirectoryStream<Path> newDirectoryStream(Filter<? super Path> filter)
+        throws IOException
+    {
+        return new ZipDirectoryStream(this, filter);
+    }
+
+    @Override
+    public final DirectoryStream<Path> newDirectoryStream(String glob)
+        throws IOException
+    {
+        // avoid creating a matcher if all entries are required.
+        if (glob.equals("*"))
+            return newDirectoryStream();
+
+        // create a matcher and return a filter that uses it.
+        final PathMatcher matcher = getFileSystem().getPathMatcher("glob:" + glob);
+        DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
+            @Override
+            public boolean accept(Path entry)  {
+                return matcher.matches(entry.getName());
+            }
+        };
+        return newDirectoryStream(filter);
+    }
+
+    @Override
+    public final void delete() throws IOException {
+        zfs.deleteFile(getResolvedPath(), true);
+    }
+
+    @Override
+    public final void deleteIfExists() throws IOException {
+        zfs.deleteFile(getResolvedPath(), false);
+    }
+
+    ZipFileAttributes getAttributes() throws IOException
+    {
+        ZipFileAttributes zfas = zfs.getFileAttributes(getResolvedPath());
+        if (zfas == null)
+            throw new NoSuchFileException(toString());
+        return zfas;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <V extends FileAttributeView> V getFileAttributeView(Class<V> type,
+                                                                LinkOption... options)
+    {
+        return (V)ZipFileAttributeView.get(this, type);
+    }
+
+    @Override
+    public void setAttribute(String attribute,
+                             Object value,
+                             LinkOption... options)
+        throws IOException
+    {
+        String type = null;
+        String attr = null;
+        int colonPos = attribute.indexOf(':');
+        if (colonPos == -1) {
+            type = "basic";
+            attr = attribute;
+        } else {
+            type = attribute.substring(0, colonPos++);
+            attr = attribute.substring(colonPos);
+        }
+        ZipFileAttributeView view = ZipFileAttributeView.get(this, type);
+        if (view == null)
+            throw new UnsupportedOperationException("view <" + view + "> is not supported");
+        view.setAttribute(attr, value);
+    }
+
+    void setTimes(FileTime mtime, FileTime atime, FileTime ctime)
+        throws IOException
+    {
+        zfs.setTimes(getResolvedPath(), mtime, atime, ctime);
+    }
+
+    private Object getAttributesImpl(String attribute, boolean domap)
+        throws IOException
+    {
+        String view = null;
+        String attr = null;
+        int colonPos = attribute.indexOf(':');
+        if (colonPos == -1) {
+            view = "basic";
+            attr = attribute;
+        } else {
+            view = attribute.substring(0, colonPos++);
+            attr = attribute.substring(colonPos);
+        }
+        ZipFileAttributeView zfv = ZipFileAttributeView.get(this, view);
+        if (zfv == null) {
+            throw new UnsupportedOperationException("view not supported");
+        }
+        return zfv.getAttribute(attr, domap);
+    }
+
+    @Override
+    public Object getAttribute(String attribute, LinkOption... options)
+        throws IOException
+    {
+        return getAttributesImpl(attribute, false);
+    }
+
+    @Override
+    public Map<String,?> readAttributes(String attribute, LinkOption... options)
+        throws IOException
+    {
+        return (Map<String, ?>)getAttributesImpl(attribute, true);
+    }
+
+    @Override
+    public FileStore getFileStore() throws IOException {
+        // each ZipFileSystem only has one root (as requested for now)
+        if (exists())
+            return zfs.getFileStore(this);
+        throw new NoSuchFileException(zfs.getString(path));
+    }
+
+    @Override
+    public boolean isSameFile(Path other) throws IOException {
+        if (other == null ||
+            this.getFileSystem() != other.getFileSystem())
+            return false;
+        this.checkAccess();
+        other.checkAccess();
+        return Arrays.equals(this.getResolvedPath(),
+                             ((ZipPath)other).getResolvedPath());
+    }
+
+    public WatchKey register(
+            WatchService watcher,
+            WatchEvent.Kind<?>[] events,
+            WatchEvent.Modifier... modifiers) {
+        if (watcher == null || events == null || modifiers == null) {
+            throw new NullPointerException();
+        }
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public WatchKey register(WatchService watcher, WatchEvent.Kind<?>... events) {
+        return register(watcher, events, new WatchEvent.Modifier[0]);
+    }
+
+    @Override
+    public Iterator<Path> iterator() {
+        return new Iterator<Path>() {
+            private int i = 0;
+
+            @Override
+            public boolean hasNext() {
+                return (i < getNameCount());
+            }
+
+            @Override
+            public Path next() {
+                if (i < getNameCount()) {
+                    Path result = getName(i);
+                    i++;
+                    return result;
+                } else {
+                    throw new NoSuchElementException();
+                }
+            }
+
+            @Override
+            public void remove() {
+                throw new ReadOnlyFileSystemException();
+            }
+        };
+    }
+
+    @Override
+    public SeekableByteChannel newByteChannel(Set<? extends OpenOption> options,
+                                              FileAttribute<?>... attrs)
+        throws IOException
+    {
+        return zfs.newByteChannel(getResolvedPath(), options, attrs);
+    }
+
+
+    FileChannel newFileChannel(Set<? extends OpenOption> options,
+                               FileAttribute<?>... attrs)
+        throws IOException
+    {
+        return zfs.newFileChannel(getResolvedPath(), options, attrs);
+    }
+
+    @Override
+    public SeekableByteChannel newByteChannel(OpenOption... options)
+            throws IOException {
+        Set<OpenOption> set = new HashSet<OpenOption>(options.length);
+        Collections.addAll(set, options);
+        return newByteChannel(set);
+    }
+
+    @Override
+    public void checkAccess(AccessMode... modes) throws IOException {
+        boolean w = false;
+        boolean x = false;
+        for (AccessMode mode : modes) {
+            switch (mode) {
+                case READ:
+                    break;
+                case WRITE:
+                    w = true;
+                    break;
+                case EXECUTE:
+                    x = true;
+                    break;
+                default:
+                    throw new UnsupportedOperationException();
+            }
+        }
+        ZipFileAttributes attrs = zfs.getFileAttributes(getResolvedPath());
+        if (attrs == null && (path.length != 1 || path[0] != '/'))
+            throw new NoSuchFileException(toString());
+        if (w) {
+            if (zfs.isReadOnly())
+                throw new AccessDeniedException(toString());
+        }
+        if (x)
+            throw new AccessDeniedException(toString());
+
+    }
+
+    @Override
+    public boolean exists() {
+        if (path.length == 1 && path[0] == '/')
+            return true;
+        try {
+            return zfs.exists(getResolvedPath());
+        } catch (IOException x) {}
+        return false;
+    }
+
+    @Override
+    public boolean notExists() {
+        return !exists();
+    }
+
+
+    @Override
+    public OutputStream newOutputStream(OpenOption... options)
+        throws IOException
+    {
+        if (options.length == 0)
+            return zfs.newOutputStream(getResolvedPath(),
+                                       CREATE_NEW, WRITE);
+        return zfs.newOutputStream(getResolvedPath(), options);
+    }
+
+    @Override
+    public Path moveTo(Path target, CopyOption... options)
+        throws IOException
+    {
+        if (this.zfs.provider() == target.getFileSystem().provider() &&
+            this.zfs.getZipFile().isSameFile(((ZipPath)target).zfs.getZipFile()))
+        {
+            zfs.copyFile(true,
+                         getResolvedPath(),
+                         ((ZipPath)target).getResolvedPath(),
+                         options);
+        } else {
+            copyToTarget(target, options);
+            delete();
+        }
+        return target;
+    }
+
+    @Override
+    public Path copyTo(Path target, CopyOption... options)
+        throws IOException
+    {
+        if (this.zfs.provider() == target.getFileSystem().provider() &&
+            this.zfs.getZipFile().isSameFile(((ZipPath)target).zfs.getZipFile()))
+        {
+            zfs.copyFile(false,
+                         getResolvedPath(),
+                         ((ZipPath)target).getResolvedPath(),
+                         options);
+        } else {
+            copyToTarget(target, options);
+        }
+        return target;
+    }
+
+    private void copyToTarget(Path target, CopyOption... options)
+        throws IOException
+    {
+        boolean replaceExisting = false;
+        boolean copyAttrs = false;
+        for (CopyOption opt : options) {
+            if (opt == REPLACE_EXISTING)
+                replaceExisting = true;
+            else if (opt == COPY_ATTRIBUTES)
+                copyAttrs = false;
+        }
+        // attributes of source file
+        ZipFileAttributes zfas = getAttributes();
+        // check if target exists
+        boolean exists;
+        if (replaceExisting) {
+            try {
+                target.deleteIfExists();
+                exists = false;
+            } catch (DirectoryNotEmptyException x) {
+                exists = true;
+            }
+        } else {
+            exists = target.exists();
+        }
+        if (exists)
+            throw new FileAlreadyExistsException(target.toString());
+
+        if (zfas.isDirectory()) {
+            // create directory or file
+            target.createDirectory();
+        } else {
+            InputStream is = zfs.newInputStream(getResolvedPath());
+            try {
+                OutputStream os = target.newOutputStream();
+                try {
+                    byte[] buf = new byte[8192];
+                    int n = 0;
+                    while ((n = is.read(buf)) != -1) {
+                        os.write(buf, 0, n);
+                    }
+                } finally {
+                    os.close();
+                }
+            } finally {
+                is.close();
+            }
+        }
+        if (copyAttrs) {
+            BasicFileAttributeView view =
+                target.getFileAttributeView(BasicFileAttributeView.class);
+            try {
+                view.setTimes(zfas.lastModifiedTime(), null, null);
+            } catch (IOException x) {
+                // rollback?
+                try {
+                    target.delete();
+                } catch (IOException ignore) { }
+                throw x;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipUtils.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.regex.PatternSyntaxException;
+
+/**
+ *
+ * @author Xueming Shen
+ */
+
+class ZipUtils {
+
+    /*
+     * Writes a 16-bit short to the output stream in little-endian byte order.
+     */
+    public static void writeShort(OutputStream os, int v) throws IOException {
+        os.write((v >>> 0) & 0xff);
+        os.write((v >>> 8) & 0xff);
+    }
+
+    /*
+     * Writes a 32-bit int to the output stream in little-endian byte order.
+     */
+    public static void writeInt(OutputStream os, long v) throws IOException {
+        os.write((int)((v >>>  0) & 0xff));
+        os.write((int)((v >>>  8) & 0xff));
+        os.write((int)((v >>> 16) & 0xff));
+        os.write((int)((v >>> 24) & 0xff));
+    }
+
+    /*
+     * Writes a 64-bit int to the output stream in little-endian byte order.
+     */
+    public static void writeLong(OutputStream os, long v) throws IOException {
+        os.write((int)((v >>>  0) & 0xff));
+        os.write((int)((v >>>  8) & 0xff));
+        os.write((int)((v >>> 16) & 0xff));
+        os.write((int)((v >>> 24) & 0xff));
+        os.write((int)((v >>> 32) & 0xff));
+        os.write((int)((v >>> 40) & 0xff));
+        os.write((int)((v >>> 48) & 0xff));
+        os.write((int)((v >>> 56) & 0xff));
+    }
+
+    /*
+     * Writes an array of bytes to the output stream.
+     */
+    public static void writeBytes(OutputStream os, byte[] b)
+        throws IOException
+    {
+        os.write(b, 0, b.length);
+    }
+
+    /*
+     * Writes an array of bytes to the output stream.
+     */
+    public static void writeBytes(OutputStream os, byte[] b, int off, int len)
+        throws IOException
+    {
+        os.write(b, off, len);
+    }
+
+    /*
+     * Append a slash at the end, if it does not have one yet
+     */
+    public static byte[] toDirectoryPath(byte[] dir) {
+        if (dir.length != 0 && dir[dir.length - 1] != '/') {
+            dir = Arrays.copyOf(dir, dir.length + 1);
+            dir[dir.length - 1] = '/';
+        }
+        return dir;
+    }
+
+    /*
+     * Converts DOS time to Java time (number of milliseconds since epoch).
+     */
+    public static long dosToJavaTime(long dtime) {
+        Date d = new Date((int)(((dtime >> 25) & 0x7f) + 80),
+                          (int)(((dtime >> 21) & 0x0f) - 1),
+                          (int)((dtime >> 16) & 0x1f),
+                          (int)((dtime >> 11) & 0x1f),
+                          (int)((dtime >> 5) & 0x3f),
+                          (int)((dtime << 1) & 0x3e));
+        return d.getTime();
+    }
+
+    /*
+     * Converts Java time to DOS time.
+     */
+    public static long javaToDosTime(long time) {
+        Date d = new Date(time);
+        int year = d.getYear() + 1900;
+        if (year < 1980) {
+            return (1 << 21) | (1 << 16);
+        }
+        return (year - 1980) << 25 | (d.getMonth() + 1) << 21 |
+               d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 |
+               d.getSeconds() >> 1;
+    }
+
+    private static final String regexMetaChars = ".^$+{[]|()";
+    private static final String globMetaChars = "\\*?[{";
+    private static boolean isRegexMeta(char c) {
+        return regexMetaChars.indexOf(c) != -1;
+    }
+    private static boolean isGlobMeta(char c) {
+        return globMetaChars.indexOf(c) != -1;
+    }
+    private static char EOL = 0;  //TBD
+    private static char next(String glob, int i) {
+        if (i < glob.length()) {
+            return glob.charAt(i);
+        }
+        return EOL;
+    }
+
+    /*
+     * Creates a regex pattern from the given glob expression.
+     *
+     * @throws  PatternSyntaxException
+     */
+    public static String toRegexPattern(String globPattern) {
+        boolean inGroup = false;
+        StringBuilder regex = new StringBuilder("^");
+
+        int i = 0;
+        while (i < globPattern.length()) {
+            char c = globPattern.charAt(i++);
+            switch (c) {
+                case '\\':
+                    // escape special characters
+                    if (i == globPattern.length()) {
+                        throw new PatternSyntaxException("No character to escape",
+                                globPattern, i - 1);
+                    }
+                    char next = globPattern.charAt(i++);
+                    if (isGlobMeta(next) || isRegexMeta(next)) {
+                        regex.append('\\');
+                    }
+                    regex.append(next);
+                    break;
+                case '/':
+                    regex.append(c);
+                    break;
+                case '[':
+                    // don't match name separator in class
+                    regex.append("[[^/]&&[");
+                    if (next(globPattern, i) == '^') {
+                        // escape the regex negation char if it appears
+                        regex.append("\\^");
+                        i++;
+                    } else {
+                        // negation
+                        if (next(globPattern, i) == '!') {
+                            regex.append('^');
+                            i++;
+                        }
+                        // hyphen allowed at start
+                        if (next(globPattern, i) == '-') {
+                            regex.append('-');
+                            i++;
+                        }
+                    }
+                    boolean hasRangeStart = false;
+                    char last = 0;
+                    while (i < globPattern.length()) {
+                        c = globPattern.charAt(i++);
+                        if (c == ']') {
+                            break;
+                        }
+                        if (c == '/') {
+                            throw new PatternSyntaxException("Explicit 'name separator' in class",
+                                    globPattern, i - 1);
+                        }
+                        // TBD: how to specify ']' in a class?
+                        if (c == '\\' || c == '[' ||
+                                c == '&' && next(globPattern, i) == '&') {
+                            // escape '\', '[' or "&&" for regex class
+                            regex.append('\\');
+                        }
+                        regex.append(c);
+
+                        if (c == '-') {
+                            if (!hasRangeStart) {
+                                throw new PatternSyntaxException("Invalid range",
+                                        globPattern, i - 1);
+                            }
+                            if ((c = next(globPattern, i++)) == EOL || c == ']') {
+                                break;
+                            }
+                            if (c < last) {
+                                throw new PatternSyntaxException("Invalid range",
+                                        globPattern, i - 3);
+                            }
+                            regex.append(c);
+                            hasRangeStart = false;
+                        } else {
+                            hasRangeStart = true;
+                            last = c;
+                        }
+                    }
+                    if (c != ']') {
+                        throw new PatternSyntaxException("Missing ']", globPattern, i - 1);
+                    }
+                    regex.append("]]");
+                    break;
+                case '{':
+                    if (inGroup) {
+                        throw new PatternSyntaxException("Cannot nest groups",
+                                globPattern, i - 1);
+                    }
+                    regex.append("(?:(?:");
+                    inGroup = true;
+                    break;
+                case '}':
+                    if (inGroup) {
+                        regex.append("))");
+                        inGroup = false;
+                    } else {
+                        regex.append('}');
+                    }
+                    break;
+                case ',':
+                    if (inGroup) {
+                        regex.append(")|(?:");
+                    } else {
+                        regex.append(',');
+                    }
+                    break;
+                case '*':
+                    if (next(globPattern, i) == '*') {
+                        // crosses directory boundaries
+                        regex.append(".*");
+                        i++;
+                    } else {
+                        // within directory boundary
+                        regex.append("[^/]*");
+                    }
+                    break;
+                case '?':
+                   regex.append("[^/]");
+                   break;
+                default:
+                    if (isRegexMeta(c)) {
+                        regex.append('\\');
+                    }
+                    regex.append(c);
+            }
+        }
+        if (inGroup) {
+            throw new PatternSyntaxException("Missing '}", globPattern, i - 1);
+        }
+        return regex.append('$').toString();
+    }
+}
--- a/jdk/src/share/native/java/lang/System.c	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/native/java/lang/System.c	Wed Jul 05 17:24:21 2017 +0200
@@ -97,14 +97,20 @@
     } else ((void) 0)
 
 #ifndef VENDOR /* Third party may overwrite this. */
-#define VENDOR "Sun Microsystems Inc."
-#define VENDOR_URL "http://java.sun.com/"
+#define VENDOR "Oracle Corporation"
+#define VENDOR_URL "http://java.oracle.com/"
 #define VENDOR_URL_BUG "http://java.sun.com/cgi-bin/bugreport.cgi"
 #endif
 
 #define JAVA_MAX_SUPPORTED_VERSION 51
 #define JAVA_MAX_SUPPORTED_MINOR_VERSION 0
 
+#ifdef JAVA_SPECIFICATION_VENDOR /* Third party may NOT overwrite this. */
+  #error "ERROR: No override of JAVA_SPECIFICATION_VENDOR is allowed"
+#else
+  #define JAVA_SPECIFICATION_VENDOR "Oracle Corporation"
+#endif
+
 static int fmtdefault; // boolean value
 jobject fillI18nProps(JNIEnv *env, jobject props, char *baseKey,
                       char *platformDispVal, char *platformFmtVal,
@@ -185,7 +191,8 @@
             JDK_MAJOR_VERSION "." JDK_MINOR_VERSION);
     PUTPROP(props, "java.specification.name",
             "Java Platform API Specification");
-    PUTPROP(props, "java.specification.vendor", "Sun Microsystems Inc.");
+    PUTPROP(props, "java.specification.vendor",
+            JAVA_SPECIFICATION_VENDOR);
 
     PUTPROP(props, "java.version", RELEASE);
     PUTPROP(props, "java.vendor", VENDOR);
@@ -239,7 +246,7 @@
     /* Printing properties */
     /* Note: java.awt.printerjob is an implementation private property which
      * just happens to have a java.* name because it is referenced in
-     * a java.awt class. It is the mechanism by which the Sun implementation
+     * a java.awt class. It is the mechanism by which the implementation
      * finds the appropriate class in the JRE for the platform.
      * It is explicitly not designed to be overridden by clients as
      * a way of replacing the implementation class, and in any case
@@ -267,7 +274,7 @@
     /* Java2D properties */
     /* Note: java.awt.graphicsenv is an implementation private property which
      * just happens to have a java.* name because it is referenced in
-     * a java.awt class. It is the mechanism by which the Sun implementation
+     * a java.awt class. It is the mechanism by which the implementation
      * finds the appropriate class in the JRE for the platform.
      * It is explicitly not designed to be overridden by clients as
      * a way of replacing the implementation class, and in any case
--- a/jdk/src/share/sample/nio/file/Chmod.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/sample/nio/file/Chmod.java	Wed Jul 05 17:24:21 2017 +0200
@@ -285,18 +285,12 @@
         }
 
         @Override
-        public FileVisitResult preVisitDirectory(FileRef dir) {
+        public FileVisitResult preVisitDirectory(FileRef dir, BasicFileAttributes attrs) {
             chmod(dir, changer);
             return CONTINUE;
         }
 
         @Override
-        public FileVisitResult preVisitDirectoryFailed(FileRef dir, IOException exc) {
-            System.err.println("WARNING: " + exc);
-            return CONTINUE;
-        }
-
-        @Override
         public FileVisitResult visitFile(FileRef file, BasicFileAttributes attrs) {
             chmod(file, changer);
             return CONTINUE;
--- a/jdk/src/share/sample/nio/file/Copy.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/sample/nio/file/Copy.java	Wed Jul 05 17:24:21 2017 +0200
@@ -85,7 +85,7 @@
         }
 
         @Override
-        public FileVisitResult preVisitDirectory(Path dir) {
+        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
             // before visiting entries in a directory we copy the directory
             // (okay if directory already exists).
             CopyOption[] options = (preserve) ?
@@ -104,19 +104,9 @@
         }
 
         @Override
-        public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
-            System.err.format("Unable to copy: %s: %s%n", dir, exc);
-            return CONTINUE;
-        }
-
-        @Override
         public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
-            if (attrs.isDirectory()) {
-                System.err.println("cycle detected: " + file);
-            } else {
-                copyFile(file, target.resolve(source.relativize(file)),
-                         prompt, preserve);
-            }
+            copyFile(file, target.resolve(source.relativize(file)),
+                     prompt, preserve);
             return CONTINUE;
         }
 
@@ -137,7 +127,11 @@
 
         @Override
         public FileVisitResult visitFileFailed(Path file, IOException exc) {
-            System.err.format("Unable to copy: %s: %s%n", file, exc);
+            if (exc instanceof FileSystemLoopException) {
+                System.err.println("cycle detected: " + file);
+            } else {
+                System.err.format("Unable to copy: %s: %s%n", file, exc);
+            }
             return CONTINUE;
         }
     }
--- a/jdk/src/share/sample/nio/file/WatchDir.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/share/sample/nio/file/WatchDir.java	Wed Jul 05 17:24:21 2017 +0200
@@ -78,12 +78,10 @@
         // register directory and sub-directories
         Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
             @Override
-            public FileVisitResult preVisitDirectory(Path dir) {
-                try {
-                    register(dir);
-                } catch (IOException x) {
-                    throw new IOError(x);
-                }
+            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
+                throws IOException
+            {
+                register(dir);
                 return FileVisitResult.CONTINUE;
             }
         });
--- a/jdk/src/solaris/classes/java/lang/UNIXProcess.java.linux	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/solaris/classes/java/lang/UNIXProcess.java.linux	Wed Jul 05 17:24:21 2017 +0200
@@ -176,7 +176,13 @@
             }});
     }
 
-    synchronized void processExited(int exitcode) {
+    void processExited(int exitcode) {
+        synchronized (this) {
+            this.exitcode = exitcode;
+            hasExited = true;
+            notifyAll();
+        }
+
         if (stdout instanceof ProcessPipeInputStream)
             ((ProcessPipeInputStream) stdout).processExited();
 
@@ -185,10 +191,6 @@
 
         if (stdin instanceof ProcessPipeOutputStream)
             ((ProcessPipeOutputStream) stdin).processExited();
-
-        this.exitcode = exitcode;
-        hasExited = true;
-        notifyAll();
     }
 
     public OutputStream getOutputStream() {
--- a/jdk/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java	Wed Jul 05 17:24:21 2017 +0200
@@ -64,7 +64,10 @@
             accessor.setFile(fd, null);
             accessor.setFiles(fd, null, null);
         } else {
-            accessor.setDirectory(fd, directory);
+            // Fix 6987233: add the trailing slash if it's absent
+            accessor.setDirectory(fd, directory +
+                    (directory.endsWith(File.separator) ?
+                     "" : File.separator));
             accessor.setFile(fd, filenames[0]);
             accessor.setFiles(fd, directory, filenames);
         }
--- a/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java	Wed Jul 05 17:24:21 2017 +0200
@@ -705,12 +705,8 @@
             throw new IllegalStateException("Attempt to resize uncreated window");
         }
         insLog.fine("Setting bounds on " + this + " to (" + x + ", " + y + "), " + width + "x" + height);
-        if (width <= 0) {
-            width = 1;
-        }
-        if (height <= 0) {
-            height = 1;
-        }
+        width = Math.max(MIN_SIZE, width);
+        height = Math.max(MIN_SIZE, height);
         XToolkit.awtLock();
         try {
              XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), getWindow(), x,y,width,height);
--- a/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java	Wed Jul 05 17:24:21 2017 +0200
@@ -763,12 +763,8 @@
     }
 
     private void checkShellRectSize(Rectangle shellRect) {
-        if (shellRect.width < 0) {
-            shellRect.width = 1;
-        }
-        if (shellRect.height < 0) {
-            shellRect.height = 1;
-        }
+        shellRect.width = Math.max(MIN_SIZE, shellRect.width);
+        shellRect.height = Math.max(MIN_SIZE, shellRect.height);
     }
 
     private void checkShellRectPos(Rectangle shellRect) {
--- a/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFrame.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFrame.java	Wed Jul 05 17:24:21 2017 +0200
@@ -28,9 +28,12 @@
 import sun.awt.EmbeddedFrame;
 import java.awt.*;
 import java.awt.AWTKeyStroke;
+import java.util.logging.Logger;
 
 public class XEmbeddedFrame extends EmbeddedFrame {
 
+    private static final Logger log = Logger.getLogger(XEmbeddedFrame.class.getName());
+
     long handle;
     public XEmbeddedFrame() {
     }
@@ -70,6 +73,21 @@
         this(handle, supportsXEmbed, false);
     }
 
+    /*
+     * The method shouldn't be called in case of active XEmbed.
+     */
+    public boolean traverseIn(boolean direction) {
+        XEmbeddedFramePeer peer = (XEmbeddedFramePeer)getPeer();
+        if (peer != null) {
+            if (peer.supportsXEmbed() && peer.isXEmbedActive()) {
+                log.fine("The method shouldn't be called when XEmbed is active!");
+            } else {
+                return super.traverseIn(direction);
+            }
+        }
+        return false;
+    }
+
     protected boolean traverseOut(boolean direction) {
         XEmbeddedFramePeer xefp = (XEmbeddedFramePeer) getPeer();
         if (direction == FORWARD) {
@@ -81,6 +99,20 @@
         return true;
     }
 
+    /*
+     * The method shouldn't be called in case of active XEmbed.
+     */
+    public void synthesizeWindowActivation(boolean doActivate) {
+        XEmbeddedFramePeer peer = (XEmbeddedFramePeer)getPeer();
+        if (peer != null) {
+            if (peer.supportsXEmbed() && peer.isXEmbedActive()) {
+                log.fine("The method shouldn't be called when XEmbed is active!");
+            } else {
+                peer.synthesizeFocusInOut(doActivate);
+            }
+        }
+    }
+
     public void registerAccelerator(AWTKeyStroke stroke) {
         XEmbeddedFramePeer xefp = (XEmbeddedFramePeer) getPeer();
         if (xefp != null) {
--- a/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java	Wed Jul 05 17:24:21 2017 +0200
@@ -35,6 +35,8 @@
 import sun.awt.EmbeddedFrame;
 import sun.awt.SunToolkit;
 
+import static sun.awt.X11.XConstants.*;
+
 public class XEmbeddedFramePeer extends XFramePeer {
 
     private static final PlatformLogger xembedLog = PlatformLogger.getLogger("sun.awt.X11.xembed.XEmbeddedFramePeer");
@@ -305,4 +307,20 @@
         EmbeddedFrame frame = (EmbeddedFrame)target;
         frame.notifyModalBlocked(blocker, blocked);
     }
+
+    public void synthesizeFocusInOut(boolean doFocus) {
+        XFocusChangeEvent xev = new XFocusChangeEvent();
+
+        XToolkit.awtLock();
+        try {
+            xev.set_type(doFocus ? FocusIn : FocusOut);
+            xev.set_window(getFocusProxy().getWindow());
+            xev.set_mode(NotifyNormal);
+            XlibWrapper.XSendEvent(XToolkit.getDisplay(), getFocusProxy().getWindow(), false,
+                                   NoEventMask, xev.pData);
+        } finally {
+            XToolkit.awtUnlock();
+            xev.dispose();
+        }
+    }
 }
--- a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1482,8 +1482,19 @@
         try {
             if (numberOfButtons == 0) {
                 numberOfButtons = getNumberOfButtonsImpl();
+                numberOfButtons = (numberOfButtons > MAX_BUTTONS_SUPPORTED)? MAX_BUTTONS_SUPPORTED : numberOfButtons;
+                //4th and 5th buttons are for wheel and shouldn't be reported as buttons.
+                //If we have more than 3 physical buttons and a wheel, we report N-2 buttons.
+                //If we have 3 physical buttons and a wheel, we report 3 buttons.
+                //If we have 1,2,3 physical buttons, we report it as is i.e. 1,2 or 3 respectively.
+                if (numberOfButtons >=5) {
+                    numberOfButtons -= 2;
+                } else if (numberOfButtons == 4 || numberOfButtons ==5){
+                    numberOfButtons = 3;
+                }
             }
-            return (numberOfButtons > MAX_BUTTONS_SUPPORTED)? MAX_BUTTONS_SUPPORTED : numberOfButtons;
+            //Assume don't have to re-query the number again and again.
+            return numberOfButtons;
         } finally {
             awtUnlock();
         }
--- a/jdk/src/solaris/classes/sun/nio/fs/LinuxFileStore.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxFileStore.java	Wed Jul 05 17:24:21 2017 +0200
@@ -156,9 +156,4 @@
             return supportsFileAttributeView(UserDefinedFileAttributeView.class);
         return super.supportsFileAttributeView(name);
     }
-
-    @Override
-    boolean isLoopback() {
-        return false;
-    }
 }
--- a/jdk/src/solaris/classes/sun/nio/fs/SolarisFileStore.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisFileStore.java	Wed Jul 05 17:24:21 2017 +0200
@@ -108,9 +108,4 @@
             return supportsFileAttributeView(UserDefinedFileAttributeView.class);
         return super.supportsFileAttributeView(name);
     }
-
-    @Override
-    boolean isLoopback() {
-        return type().equals("lofs");
-    }
 }
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixFileStore.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileStore.java	Wed Jul 05 17:24:21 2017 +0200
@@ -76,12 +76,6 @@
      */
     abstract UnixMountEntry findMountEntry() throws IOException;
 
-    /**
-     * Returns true if this file store represents a loopback file system that
-     * will have the same device ID as underlying file system.
-     */
-    abstract boolean isLoopback();
-
     UnixPath file() {
         return file;
     }
@@ -169,22 +163,13 @@
         if (!(ob instanceof UnixFileStore))
             return false;
         UnixFileStore other = (UnixFileStore)ob;
-        if (dev != other.dev)
-            return false;
-        // deviceIDs are equal but they may not be equal if one or both of
-        // them is a loopback file system
-        boolean thisIsLoopback = isLoopback();
-        if (thisIsLoopback != other.isLoopback())
-            return false;  // one, but not both, are lofs
-        if (!thisIsLoopback)
-            return true;    // neither is lofs
-        // both are lofs so compare mount points
-        return Arrays.equals(this.entry.dir(), other.entry.dir());
+        return (this.dev == other.dev) &&
+               Arrays.equals(this.entry.dir(), other.entry.dir());
     }
 
     @Override
     public int hashCode() {
-        return (int)(dev ^ (dev >>> 32));
+        return (int)(dev ^ (dev >>> 32)) ^ Arrays.hashCode(entry.dir());
     }
 
     @Override
--- a/jdk/src/solaris/native/java/io/io_util_md.c	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/solaris/native/java/io/io_util_md.c	Wed Jul 05 17:24:21 2017 +0200
@@ -83,8 +83,6 @@
             close(devnull);
         }
     } else if (JVM_Close(fd) == -1) {
-            SET_FD(this, fd, fid); // restore fd
-            printf("JVM_Close returned -1\n");
-            JNU_ThrowIOExceptionWithLastError(env, "close failed");
+        JNU_ThrowIOExceptionWithLastError(env, "close failed");
     }
 }
--- a/jdk/src/solaris/native/java/net/Inet6AddressImpl.c	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/solaris/native/java/net/Inet6AddressImpl.c	Wed Jul 05 17:24:21 2017 +0200
@@ -124,7 +124,7 @@
 static int initialized = 0;
 
 /*
- * Find an internet address for a given hostname.  Not this this
+ * Find an internet address for a given hostname.  Note that this
  * code only works for addresses of type INET. The translation
  * of %d.%d.%d.%d to an address (int) occurs in java now, so the
  * String "host" shouldn't *ever* be a %d.%d.%d.%d string
@@ -200,7 +200,7 @@
          */
         if (isspace((unsigned char)hostname[0])) {
             JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
-                            (char *)hostname);
+                            hostname);
             JNU_ReleaseStringPlatformChars(env, host, hostname);
             return NULL;
         }
@@ -210,8 +210,7 @@
 
         if (error) {
             /* report error */
-            JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
-                            (char *)hostname);
+            ThrowUnknownHostExceptionWithGaiError(env, hostname, error);
             JNU_ReleaseStringPlatformChars(env, host, hostname);
             return NULL;
         } else {
@@ -407,7 +406,7 @@
             addr |= ((caddr[1] <<16) & 0xff0000);
             addr |= ((caddr[2] <<8) & 0xff00);
             addr |= (caddr[3] & 0xff);
-            memset((char *) &him4, 0, sizeof(him4));
+            memset((void *) &him4, 0, sizeof(him4));
             him4.sin_addr.s_addr = (uint32_t) htonl(addr);
             him4.sin_family = AF_INET;
             sa = (struct sockaddr *) &him4;
@@ -417,7 +416,7 @@
              * For IPv6 address construct a sockaddr_in6 structure.
              */
             (*env)->GetByteArrayRegion(env, addrArray, 0, 16, caddr);
-            memset((char *) &him6, 0, sizeof(him6));
+            memset((void *) &him6, 0, sizeof(him6));
             memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr) );
             him6.sin6_family = AF_INET6;
             sa = (struct sockaddr *) &him6 ;
@@ -579,8 +578,8 @@
                                                          ifArray, ttl);
     }
 
-    memset((char *) caddr, 0, 16);
-    memset((char *) &him6, 0, sizeof(him6));
+    memset((void *) caddr, 0, 16);
+    memset((void *) &him6, 0, sizeof(him6));
     (*env)->GetByteArrayRegion(env, addrArray, 0, 16, caddr);
     memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr) );
     him6.sin6_family = AF_INET6;
@@ -600,8 +599,8 @@
      * for it.
      */
     if (!(IS_NULL(ifArray))) {
-      memset((char *) caddr, 0, 16);
-      memset((char *) &inf6, 0, sizeof(inf6));
+      memset((void *) caddr, 0, 16);
+      memset((void *) &inf6, 0, sizeof(inf6));
       (*env)->GetByteArrayRegion(env, ifArray, 0, 16, caddr);
       memcpy((void *)&(inf6.sin6_addr), caddr, sizeof(struct in6_addr) );
       inf6.sin6_family = AF_INET6;
--- a/jdk/src/solaris/native/java/net/net_util_md.c	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/solaris/native/java/net/net_util_md.c	Wed Jul 05 17:24:21 2017 +0200
@@ -61,6 +61,7 @@
 
 getaddrinfo_f getaddrinfo_ptr = NULL;
 freeaddrinfo_f freeaddrinfo_ptr = NULL;
+gai_strerror_f gai_strerror_ptr = NULL;
 getnameinfo_f getnameinfo_ptr = NULL;
 
 /*
@@ -342,11 +343,14 @@
     freeaddrinfo_ptr = (freeaddrinfo_f)
         JVM_FindLibraryEntry(RTLD_DEFAULT, "freeaddrinfo");
 
+    gai_strerror_ptr = (gai_strerror_f)
+        JVM_FindLibraryEntry(RTLD_DEFAULT, "gai_strerror");
+
     getnameinfo_ptr = (getnameinfo_f)
         JVM_FindLibraryEntry(RTLD_DEFAULT, "getnameinfo");
 
     if (freeaddrinfo_ptr == NULL || getnameinfo_ptr == NULL) {
-        /* Wee need all 3 of them */
+        /* We need all 3 of them */
         getaddrinfo_ptr = NULL;
     }
 
@@ -355,6 +359,35 @@
 #endif /* AF_INET6 */
 }
 
+void ThrowUnknownHostExceptionWithGaiError(JNIEnv *env,
+                                           const char* hostname,
+                                           int gai_error)
+{
+    int size;
+    char *buf;
+    const char *format = "%s: %s";
+    const char *error_string =
+        (gai_strerror_ptr == NULL) ? NULL : (*gai_strerror_ptr)(gai_error);
+    if (error_string == NULL)
+        error_string = "unknown error";
+
+    size = strlen(format) + strlen(hostname) + strlen(error_string) + 2;
+    buf = (char *) malloc(size);
+    if (buf) {
+        jstring s;
+        sprintf(buf, format, hostname, error_string);
+        s = JNU_NewStringPlatform(env, buf);
+        if (s != NULL) {
+            jobject x = JNU_NewObjectByName(env,
+                                            "java/net/UnknownHostException",
+                                            "(Ljava/lang/String;)V", s);
+            if (x != NULL)
+                (*env)->Throw(env, x);
+        }
+        free(buf);
+    }
+}
+
 void
 NET_AllocSockaddr(struct sockaddr **him, int *len) {
 #ifdef AF_INET6
@@ -1173,19 +1206,26 @@
     }
 
     /*
-     * SOL_SOCKET/{SO_SNDBUF,SO_RCVBUF} - On Solaris need to
-     * ensure that value is <= max_buf as otherwise we get
-     * an invalid argument.
+     * SOL_SOCKET/{SO_SNDBUF,SO_RCVBUF} - On Solaris we may need to clamp
+     * the value when it exceeds the system limit.
      */
 #ifdef __solaris__
     if (level == SOL_SOCKET) {
         if (opt == SO_SNDBUF || opt == SO_RCVBUF) {
             int sotype, arglen;
             int *bufsize, maxbuf;
+            int ret;
+
+            /* Attempt with the original size */
+            ret = setsockopt(fd, level, opt, arg, len);
+            if ((ret == 0) || (ret == -1 && errno != ENOBUFS))
+                return ret;
+
+            /* Exceeded system limit so clamp and retry */
 
             if (!init_max_buf) {
-                tcp_max_buf = getParam("/dev/tcp", "tcp_max_buf", 64*1024);
-                udp_max_buf = getParam("/dev/udp", "udp_max_buf", 64*1024);
+                tcp_max_buf = getParam("/dev/tcp", "tcp_max_buf", 1024*1024);
+                udp_max_buf = getParam("/dev/udp", "udp_max_buf", 2048*1024);
                 init_max_buf = 1;
             }
 
--- a/jdk/src/solaris/native/java/net/net_util_md.h	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/solaris/native/java/net/net_util_md.h	Wed Jul 05 17:24:21 2017 +0200
@@ -84,11 +84,13 @@
 
 /* needed from libsocket on Solaris 8 */
 
-typedef int (*getaddrinfo_f)(const char *nodename, const char  *servname,
-     const struct addrinfo *hints, struct addrinfo **res);
+typedef int (*getaddrinfo_f)(const char *nodename, const char *servname,
+    const struct addrinfo *hints, struct addrinfo **res);
 
 typedef void (*freeaddrinfo_f)(struct addrinfo *);
 
+typedef const char * (*gai_strerror_f)(int ecode);
+
 typedef int (*getnameinfo_f)(const struct sockaddr *, size_t,
     char *, size_t, char *, size_t, int);
 
@@ -96,6 +98,10 @@
 extern freeaddrinfo_f freeaddrinfo_ptr;
 extern getnameinfo_f getnameinfo_ptr;
 
+void ThrowUnknownHostExceptionWithGaiError(JNIEnv *env,
+                                           const char* hostname,
+                                           int gai_error);
+
 /* do we have address translation support */
 
 extern jboolean NET_addrtransAvailable();
--- a/jdk/src/solaris/native/sun/awt/awt_InputMethod.c	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/solaris/native/sun/awt/awt_InputMethod.c	Wed Jul 05 17:24:21 2017 +0200
@@ -1473,6 +1473,10 @@
 static void DestroyXIMCallback(XIM im, XPointer client_data, XPointer call_data) {
     /* mark that XIM server was destroyed */
     X11im = NULL;
+    JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+    /* free the old pX11IMData and set it to null. this also avoids crashing
+     * the jvm if the XIM server reappears */
+    X11InputMethodData *pX11IMData = getX11InputMethodData(env, currentX11InputMethodInstance);
 }
 
 /*
--- a/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java	Wed Jul 05 17:24:21 2017 +0200
@@ -556,24 +556,26 @@
 
         Component target = (Component)getTarget();
         Window window = SunToolkit.getContainingWindow(target);
-        if (window != null && !window.isOpaque()) {
-            // Non-opaque windows do not support heavyweight children.
-            // Redirect all painting to the Window's Graphics instead.
-            // The caller is responsible for calling the
-            // WindowPeer.updateWindow() after painting has finished.
-            int x = 0, y = 0;
-            for (Component c = target; c != window; c = c.getParent()) {
-                x += c.getX();
-                y += c.getY();
-            }
-
+        if (window != null) {
             Graphics g =
                 ((WWindowPeer)window.getPeer()).getTranslucentGraphics();
+            // getTranslucentGraphics() returns non-null value for non-opaque windows only
+            if (g != null) {
+                // Non-opaque windows do not support heavyweight children.
+                // Redirect all painting to the Window's Graphics instead.
+                // The caller is responsible for calling the
+                // WindowPeer.updateWindow() after painting has finished.
+                int x = 0, y = 0;
+                for (Component c = target; c != window; c = c.getParent()) {
+                    x += c.getX();
+                    y += c.getY();
+                }
 
-            g.translate(x, y);
-            g.clipRect(0, 0, target.getWidth(), target.getHeight());
+                g.translate(x, y);
+                g.clipRect(0, 0, target.getWidth(), target.getHeight());
 
-            return g;
+                return g;
+            }
         }
 
         SurfaceData surfaceData = this.surfaceData;
--- a/jdk/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java	Wed Jul 05 17:24:21 2017 +0200
@@ -191,9 +191,20 @@
     public void activateEmbeddingTopLevel() {
     }
 
-    public void synthesizeWindowActivation(boolean doActivate) {
-        ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(doActivate);
+    public void synthesizeWindowActivation(final boolean doActivate) {
+        if (!doActivate || EventQueue.isDispatchThread()) {
+            ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(doActivate);
+        } else {
+            // To avoid focus concurrence b/w IE and EmbeddedFrame
+            // activation is postponed by means of posting it to EDT.
+            EventQueue.invokeLater(new Runnable() {
+                    public void run() {
+                        ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(true);
+                    }
+                });
+        }
     }
+
     public void registerAccelerator(AWTKeyStroke stroke) {}
     public void unregisterAccelerator(AWTKeyStroke stroke) {}
 
--- a/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java	Wed Jul 05 17:24:21 2017 +0200
@@ -595,16 +595,6 @@
     }
 
     @Override
-    public Graphics getGraphics() {
-        synchronized (getStateLock()) {
-            if (!isOpaque) {
-                return getTranslucentGraphics();
-            }
-        }
-        return super.getGraphics();
-    }
-
-    @Override
     public void setBackground(Color c) {
         super.setBackground(c);
         synchronized (getStateLock()) {
--- a/jdk/src/windows/lib/tzmappings	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/windows/lib/tzmappings	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,4 @@
 #
-# 
 # This file describes mapping information between Windows and Java
 # time zones.
 # Format: Each line should include a colon separated fields of Windows
@@ -11,7 +10,7 @@
 #                            NOTE
 # This table format is not a public interface of any Java
 # platforms. No applications should depend on this file in any form.
-# 
+#
 # This table has been generated by a program and should not be edited
 # manually.
 #
@@ -84,8 +83,8 @@
 Ekaterinburg Standard Time:10,11::Asia/Yekaterinburg:
 West Asia:10,11:UZ:Asia/Tashkent:
 West Asia Standard Time:10,11:UZ:Asia/Tashkent:
-Central Asia:12,13::Asia/Dhaka:
-Central Asia Standard Time:12,13::Asia/Dhaka:
+Central Asia:12,13::Asia/Almaty:
+Central Asia Standard Time:12,13::Asia/Almaty:
 N. Central Asia Standard Time:12,13::Asia/Novosibirsk:
 Bangkok:14,15::Asia/Bangkok:
 Bangkok Standard Time:14,15::Asia/Bangkok:
@@ -167,22 +166,27 @@
 Greenwich Standard Time:88,89::GMT:
 Argentina Standard Time:900,900::America/Buenos_Aires:
 Azerbaijan Standard Time:901,901:AZ:Asia/Baku:
-Central Brazilian Standard Time:902,902:BR:America/Manaus:
-Central Standard Time (Mexico):903,903::America/Mexico_City:
-Georgian Standard Time:904,904:GE:Asia/Tbilisi:
-Jordan Standard Time:905,905:JO:Asia/Amman:
-Mauritius Standard Time:906,906:MU:Indian/Mauritius:
-Middle East Standard Time:907,907:LB:Asia/Beirut:
-Montevideo Standard Time:908,908:UY:America/Montevideo:
-Morocco Standard Time:909,909:MA:Africa/Casablanca:
-Mountain Standard Time (Mexico):910,910:MX:America/Chihuahua:
-Namibia Standard Time:911,911:NA:Africa/Windhoek:
-Pacific Standard Time (Mexico):912,912:MX:America/Tijuana:
-Pakistan Standard Time:913,913::Asia/Karachi:
-UTC:914,914::UTC:
-Venezuela Standard Time:915,915::America/Caracas:
-Kamchatka Standard Time:916,916:RU:Asia/Kamchatka:
-Paraguay Standard Time:917,917:PY:America/Asuncion:
-Western Brazilian Standard Time:918,918:BR:America/Rio_Branco:
-Ulaanbaatar Standard Time:919,919::Asia/Ulaanbaatar:
-Armenian Standard Time:920,920:AM:Asia/Yerevan:
+Bangladesh Standard Time:902,902::Asia/Dhaka:
+Central Brazilian Standard Time:903,903:BR:America/Manaus:
+Central Standard Time (Mexico):904,904::America/Mexico_City:
+Georgian Standard Time:905,905:GE:Asia/Tbilisi:
+Jordan Standard Time:906,906:JO:Asia/Amman:
+Kamchatka Standard Time:907,907:RU:Asia/Kamchatka:
+Mauritius Standard Time:908,908:MU:Indian/Mauritius:
+Middle East Standard Time:909,909:LB:Asia/Beirut:
+Montevideo Standard Time:910,910:UY:America/Montevideo:
+Morocco Standard Time:911,911:MA:Africa/Casablanca:
+Mountain Standard Time (Mexico):912,912:MX:America/Chihuahua:
+Namibia Standard Time:913,913:NA:Africa/Windhoek:
+Pacific Standard Time (Mexico):914,914:MX:America/Tijuana:
+Pakistan Standard Time:915,915::Asia/Karachi:
+Paraguay Standard Time:916,916:PY:America/Asuncion:
+Syria Standard Time:917,917:SY:Asia/Damascus:
+UTC:918,918::UTC:
+UTC+12:919,919::GMT+1200:
+UTC-02:920,920::GMT-0200:
+UTC-11:921,921::GMT-1100:
+Ulaanbaatar Standard Time:922,922::Asia/Ulaanbaatar:
+Venezuela Standard Time:923,923::America/Caracas:
+Western Brazilian Standard Time:924,924:BR:America/Rio_Branco:
+Armenian Standard Time:925,925:AM:Asia/Yerevan:
--- a/jdk/src/windows/native/java/io/io_util_md.c	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/windows/native/java/io/io_util_md.c	Wed Jul 05 17:24:21 2017 +0200
@@ -531,7 +531,6 @@
     SET_FD(this, -1, fid);
 
     if (CloseHandle(h) == 0) { /* Returns zero on failure */
-        SET_FD(this, fd, fid); // restore fd
         JNU_ThrowIOExceptionWithLastError(env, "close failed");
     }
     return 0;
--- a/jdk/src/windows/native/sun/net/spi/DefaultProxySelector.c	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/windows/native/sun/net/spi/DefaultProxySelector.c	Wed Jul 05 17:24:21 2017 +0200
@@ -250,6 +250,10 @@
           return proxy;
         }
       }
+    } else {
+      /* ProxyEnable == 0 or Query failed      */
+      /* close the handle to the registry key  */
+      RegCloseKey(hKey);
     }
   }
 
--- a/jdk/src/windows/native/sun/windows/awt_Component.cpp	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp	Wed Jul 05 17:24:21 2017 +0200
@@ -2329,6 +2329,19 @@
     MSG msg;
     InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);
 
+    AwtWindow *toplevel = GetContainer();
+    if (toplevel && !toplevel->IsSimpleWindow()) {
+        /*
+         * The frame should be focused by click in case it is
+         * the active window but not the focused window. See 6886678.
+         */
+        if (toplevel->GetHWnd() == ::GetActiveWindow() &&
+            toplevel->GetHWnd() != AwtComponent::GetFocusedWindow())
+        {
+            toplevel->AwtSetActiveWindow();
+        }
+    }
+
     SendMouseEvent(java_awt_event_MouseEvent_MOUSE_PRESSED, now, x, y,
                    GetJavaModifiers(), clickCount, JNI_FALSE,
                    GetButton(button), &msg);
--- a/jdk/src/windows/native/sun/windows/awt_Desktop.cpp	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/windows/native/sun/windows/awt_Desktop.cpp	Wed Jul 05 17:24:21 2017 +0200
@@ -59,15 +59,17 @@
                     FORMAT_MESSAGE_FROM_SYSTEM  |
                     FORMAT_MESSAGE_IGNORE_INSERTS,
                     NULL,
-                    GetLastError(),
+                    (int)retval,
                     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
                     (LPTSTR)&buffer,
                     0,
                     NULL );
 
-        jstring errmsg = JNU_NewStringPlatform(env, buffer, len);
-        LocalFree(buffer);
-        return errmsg;
+        if (buffer) {
+            jstring errmsg = JNU_NewStringPlatform(env, buffer);
+            LocalFree(buffer);
+            return errmsg;
+        }
     }
 
     return NULL;
--- a/jdk/src/windows/native/sun/windows/awt_DesktopProperties.cpp	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/windows/native/sun/windows/awt_DesktopProperties.cpp	Wed Jul 05 17:24:21 2017 +0200
@@ -505,7 +505,8 @@
     SetIntegerProperty(TEXT("win.drag.width"), cxdrag);
     SetIntegerProperty(TEXT("win.drag.height"), cydrag);
     SetIntegerProperty(TEXT("DnD.gestureMotionThreshold"), max(cxdrag, cydrag)/2);
-    SetIntegerProperty(TEXT("awt.mouse.numButtons"), GetSystemMetrics(SM_CMOUSEBUTTONS));
+    SetIntegerProperty(TEXT("awt.mouse.numButtons"), AwtToolkit::GetNumberOfButtons());
+
     SetIntegerProperty(TEXT("awt.multiClickInterval"), GetDoubleClickTime());
 
     // BEGIN cross-platform properties
--- a/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp	Wed Jul 05 17:24:21 2017 +0200
@@ -133,6 +133,8 @@
 
 static LPCTSTR szAwtToolkitClassName = TEXT("SunAwtToolkit");
 
+static const int MOUSE_BUTTONS_WINDOWS_SUPPORTED = 5; //three standard buttons + XBUTTON1 + XBUTTON2.
+
 UINT AwtToolkit::GetMouseKeyState()
 {
     static BOOL mbSwapped = ::GetSystemMetrics(SM_SWAPBUTTON);
@@ -2310,5 +2312,9 @@
 
 JNIEXPORT jint JNICALL Java_sun_awt_windows_WToolkit_getNumberOfButtonsImpl
 (JNIEnv *, jobject self) {
-    return GetSystemMetrics(SM_CMOUSEBUTTONS);
+    return AwtToolkit::GetNumberOfButtons();
 }
+
+UINT AwtToolkit::GetNumberOfButtons() {
+    return MOUSE_BUTTONS_WINDOWS_SUPPORTED;
+}
--- a/jdk/src/windows/native/sun/windows/awt_Toolkit.h	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.h	Wed Jul 05 17:24:21 2017 +0200
@@ -185,6 +185,7 @@
     BOOL IsDynamicLayoutActive();
     BOOL areExtraMouseButtonsEnabled();
     void setExtraMouseButtonsEnabled(BOOL enable);
+    static UINT GetNumberOfButtons();
 
     INLINE BOOL localPump() { return m_localPump; }
     INLINE BOOL VerifyComponents() { return FALSE; } // TODO: Use new DebugHelper class to set this flag
--- a/jdk/test/ProblemList.txt	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/ProblemList.txt	Wed Jul 05 17:24:21 2017 +0200
@@ -165,6 +165,12 @@
 #  very small tests and could greatly benefit from a samevm test run.
 #  So a large batch of beans tests are currently run with othervm mode.
 
+# Filed 6986807
+java/beans/Introspector/TestTypeResolver.java   		generic-all
+
+# Filed 6986813
+java/beans/Introspector/memory/Test4508780.java			generic-all
+
 # Linux, some kind of problems with X11 display
 java/beans/PropertyChangeSupport/Test4682386.java		generic-all
 java/beans/PropertyChangeSupport/TestSynchronization.java	generic-all
@@ -493,6 +499,9 @@
 
 # jdk_security
 
+# Filed 6986868
+sun/security/tools/jarsigner/crl.sh				generic-all
+
 # Filed 6951285, not sure how often this fails, last was Linux 64bit Fedora 9
 sun/security/krb5/auto/MaxRetries.java				generic-all
 
@@ -689,10 +698,22 @@
 
 # jdk_tools
 
+# Filed 6952105
+com/sun/jdi/SuspendThreadTest.java				generic-all
+
+# Filed 6986875
+sun/tools/jps/jps-Vvml.sh					generic-all
+
+# Filed 6979016
+sun/tools/jconsole/ResourceCheckTest.sh				generic-all
+
 ############################################################################
 
 # jdk_util
 
+# Filed 6933803
+java/util/concurrent/ThreadPoolExecutor/CoreThreadTimeOut.java	generic-all
+
 # Fails with assertion error on windows
 #   11 separate stacktraces created... file reuse problem?
 java/util/zip/ZipFile/ReadLongZipFileName.java			generic-all
--- a/jdk/test/com/sun/security/sasl/ntlm/NTLMTest.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/com/sun/security/sasl/ntlm/NTLMTest.java	Wed Jul 05 17:24:21 2017 +0200
@@ -31,8 +31,6 @@
 import javax.security.auth.callback.*;
 import java.util.*;
 
-import com.sun.security.ntlm.NTLMException;
-
 public class NTLMTest {
 
     private static final String MECH = "NTLM";
@@ -95,19 +93,13 @@
             checkVersion("LM/NTLM", "LMv2");
             throw new Exception("Should not succeed");
         } catch (SaslException se) {
-            NTLMException ne = (NTLMException)se.getCause();
-            if (ne.errorCode() != NTLMException.AUTH_FAILED) {
-                throw new Exception("Failed false");
-            }
+            // OK
         }
         try {
             checkVersion("LMv2/NTLMv2", "LM");
             throw new Exception("Should not succeed");
         } catch (SaslException se) {
-            NTLMException ne = (NTLMException)se.getCause();
-            if (ne.errorCode() != NTLMException.AUTH_FAILED) {
-                throw new Exception("Failed false");
-            }
+            // OK
         }
 
     }
--- a/jdk/test/com/sun/servicetag/JavaServiceTagTest.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/com/sun/servicetag/JavaServiceTagTest.java	Wed Jul 05 17:24:21 2017 +0200
@@ -124,8 +124,9 @@
             throw new RuntimeException("Unexpected platform_arch: " +
                 st.getPlatformArch());
         }
+        String vendor = System.getProperty("java.vendor");
         if (!st.getProductVendor().
-                equals("Sun Microsystems")) {
+                equals(vendor)) {
             throw new RuntimeException("Unexpected product_vendor: " +
                 st.getProductVendor());
         }
--- a/jdk/test/com/sun/servicetag/JavaServiceTagTest1.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/com/sun/servicetag/JavaServiceTagTest1.java	Wed Jul 05 17:24:21 2017 +0200
@@ -196,8 +196,10 @@
             throw new RuntimeException("Unexpected platform_arch: " +
                 st.getPlatformArch());
         }
+
+        String vendor = System.getProperty("java.vendor");
         if (!st.getProductVendor().
-                equals("Sun Microsystems")) {
+                equals(vendor)) {
             throw new RuntimeException("Unexpected product_vendor: " +
                 st.getProductVendor());
         }
--- a/jdk/test/com/sun/servicetag/Util.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/com/sun/servicetag/Util.java	Wed Jul 05 17:24:21 2017 +0200
@@ -162,6 +162,8 @@
         for (ServiceTag st : svcTags) {
             ServiceTag st1 = stMap.get(st.getInstanceURN());
             if (!matches(st, st1)) {
+                System.err.println(st);
+                System.err.println(st1);
                 throw new RuntimeException("ServiceTag in the registry " +
                     "does not match the one in the map");
             }
--- a/jdk/test/com/sun/servicetag/environ.properties	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/com/sun/servicetag/environ.properties	Wed Jul 05 17:24:21 2017 +0200
@@ -4,6 +4,6 @@
 osVersion=5.10
 osArchitecture=sparc
 systemModel=Sun-Fire-V440
-systemManufacturer=Sun Microsystems
-cpuManufacturer=Sun Microsystems
+systemManufacturer=Oracle Corporation
+cpuManufacturer=Oracle Corporation
 serialNumber=BEL078932
--- a/jdk/test/com/sun/servicetag/missing-environ-field.xml	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/com/sun/servicetag/missing-environ-field.xml	Wed Jul 05 17:24:21 2017 +0200
@@ -19,7 +19,7 @@
 <product_parent_urn>urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3</product_parent_urn>
 <product_parent>Java Platform Standard Edition 6 (Java SE 6)</product_parent>
 <product_defined_inst_id>id=1.6.0-internal-b00 sparc,dir=/myjdk/solaris-sparc</product_defined_inst_id>
-<product_vendor>Sun Microsystems</product_vendor>
+<product_vendor>Oracle Corporation</product_vendor>
 <platform_arch>sparc</platform_arch>
 <timestamp>2007-11-12 06:15:11 GMT</timestamp>
 <container>global</container>
@@ -34,7 +34,7 @@
 <product_parent_urn>urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3</product_parent_urn>
 <product_parent>Java Platform Standard Edition 6 (Java SE 6)</product_parent>
 <product_defined_inst_id>id=1.6.0_05-b01 sparc,dir=/myjdk/solaris-i586</product_defined_inst_id>
-<product_vendor>Sun Microsystems</product_vendor>
+<product_vendor>Oracle Corporation</product_vendor>
 <platform_arch>i386</platform_arch>
 <timestamp>2007-11-12 06:15:11 GMT</timestamp>
 <container>global</container>
--- a/jdk/test/com/sun/servicetag/newer-registry-version.xml	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/com/sun/servicetag/newer-registry-version.xml	Wed Jul 05 17:24:21 2017 +0200
@@ -20,7 +20,7 @@
 <product_parent_urn>urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3</product_parent_urn>
 <product_parent>Java Platform Standard Edition 6 (Java SE 6)</product_parent>
 <product_defined_inst_id>id=1.6.0-internal-b00 sparc,dir=/myjdk/solaris-sparc</product_defined_inst_id>
-<product_vendor>Sun Microsystems</product_vendor>
+<product_vendor>Oracle Corporation</product_vendor>
 <platform_arch>sparc</platform_arch>
 <timestamp>2007-11-13 00:49:01 GMT</timestamp>
 <container>global</container>
--- a/jdk/test/com/sun/servicetag/registration.xml	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/com/sun/servicetag/registration.xml	Wed Jul 05 17:24:21 2017 +0200
@@ -7,8 +7,8 @@
 <osVersion>5.10</osVersion>
 <osArchitecture>sparc</osArchitecture>
 <systemModel>Sun-Fire-V440</systemModel>
-<systemManufacturer>Sun Microsystems</systemManufacturer>
-<cpuManufacturer>Sun Microsystems</cpuManufacturer>
+<systemManufacturer>Oracle Corporation</systemManufacturer>
+<cpuManufacturer>Oracle Corporation</cpuManufacturer>
 <serialNumber>BEL078932</serialNumber>
 </environment>
 <registry urn="urn:st:9543ffaa-a4f1-4f77-b2d1-f561922d4e4a" version="1.0">
@@ -20,7 +20,7 @@
 <product_parent_urn>urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3</product_parent_urn>
 <product_parent>Java Platform Standard Edition 6 (Java SE 6)</product_parent>
 <product_defined_inst_id>id=1.6.0-internal-b00 sparc,dir=/myjdk/solaris-sparc</product_defined_inst_id>
-<product_vendor>Sun Microsystems</product_vendor>
+<product_vendor>Oracle Corporation</product_vendor>
 <platform_arch>sparc</platform_arch>
 <timestamp>2007-11-13 00:49:01 GMT</timestamp>
 <container>global</container>
@@ -35,7 +35,7 @@
 <product_parent_urn>urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3</product_parent_urn>
 <product_parent>Java Platform Standard Edition 6 (Java SE 6)</product_parent>
 <product_defined_inst_id>id=1.6.0_05-b01 i386,dir=/myjdk/solaris-i586</product_defined_inst_id>
-<product_vendor>Sun Microsystems</product_vendor>
+<product_vendor>Oracle Corporation</product_vendor>
 <platform_arch>i386</platform_arch>
 <timestamp>2007-11-13 00:49:01 GMT</timestamp>
 <container>global</container>
@@ -50,7 +50,7 @@
 <product_parent_urn>urn:uuid:596ffcfa-63d5-11d7-9886-ac816a682f92</product_parent_urn>
 <product_parent>Solaris Operating System</product_parent>
 <product_defined_inst_id/>
-<product_vendor>Sun Microsystems</product_vendor>
+<product_vendor>Oracle Corporation</product_vendor>
 <platform_arch>sparc</platform_arch>
 <timestamp>2007-11-13 00:49:01 GMT</timestamp>
 <container>global</container>
--- a/jdk/test/com/sun/servicetag/servicetag1.properties	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/com/sun/servicetag/servicetag1.properties	Wed Jul 05 17:24:21 2017 +0200
@@ -5,7 +5,7 @@
 product_parent_urn=urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3
 product_parent=Java Platform Standard Edition 6 (Java SE 6)
 product_defined_inst_id=id=1.6.0-internal-b00 sparc,dir=/myjdk/solaris-sparc
-product_vendor=Sun Microsystems
+product_vendor=Oracle Corporation
 platform_arch=sparc
 timestamp=2007-11-12 05:19:40 GMT
 container=global
--- a/jdk/test/com/sun/servicetag/servicetag2.properties	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/com/sun/servicetag/servicetag2.properties	Wed Jul 05 17:24:21 2017 +0200
@@ -5,7 +5,7 @@
 product_parent_urn=urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3
 product_parent=Java Platform Standard Edition 6 (Java SE 6)
 product_defined_inst_id=id=1.6.0_05-b01 i386,dir=/myjdk/solaris-i586
-product_vendor=Sun Microsystems
+product_vendor=Oracle Corporation
 platform_arch=i386
 timestamp=2007-11-12 06:12:21 GMT
 container=global
--- a/jdk/test/com/sun/servicetag/servicetag3.properties	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/com/sun/servicetag/servicetag3.properties	Wed Jul 05 17:24:21 2017 +0200
@@ -5,7 +5,7 @@
 product_parent_urn=urn:uuid:596ffcfa-63d5-11d7-9886-ac816a682f92
 product_parent=Solaris Operating System
 product_defined_inst_id=
-product_vendor=Sun Microsystems
+product_vendor=Oracle Corporation
 platform_arch=sparc
 timestamp=2007-06-20 22:07:11 GMT
 container=global
--- a/jdk/test/com/sun/servicetag/servicetag4.properties	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/com/sun/servicetag/servicetag4.properties	Wed Jul 05 17:24:21 2017 +0200
@@ -5,7 +5,7 @@
 product_parent_urn=urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3
 product_parent=Java Platform Standard Edition 6 (Java SE 6)
 product_defined_inst_id=id=1.6.0_05-b01 amd64,dir=/myjdk/linux-amd64
-product_vendor=Sun Microsystems
+product_vendor=Oracle Corporation
 platform_arch=x64
 timestamp=2007-12-12 05:19:40 GMT
 container=global
--- a/jdk/test/com/sun/servicetag/servicetag5.properties	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/com/sun/servicetag/servicetag5.properties	Wed Jul 05 17:24:21 2017 +0200
@@ -5,7 +5,7 @@
 product_parent_urn=urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3
 product_parent=Java Platform Standard Edition 6 (Java SE 6)
 product_defined_inst_id=id=1.6.0_06-b06 i386,dir=/w/mchung/bundles/jdk1.6.0_05/jre
-product_vendor=Sun Microsystems
+product_vendor=Oracle Corporation
 platform_arch=x86
 timestamp=2007-11-29 17:59:42 GMT
 container=global
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/demo/zipfs/Basic.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along 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.nio.file.*;
+import java.nio.file.attribute.*;
+import java.nio.file.spi.FileSystemProvider;
+import java.util.*;
+import java.net.URI;
+import java.io.IOException;
+
+/**
+ * Basic test for zip provider
+ */
+
+public class Basic {
+    public static void main(String[] args) throws Exception {
+        Path zipfile = Paths.get(args[0]);
+
+        // Test: zip should should be returned in provider list
+        boolean found = false;
+
+        for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
+            if (provider.getScheme().equalsIgnoreCase("zip")) {
+                found = true;
+                break;
+            }
+        }
+        if (!found)
+            throw new RuntimeException("'zip' provider not installed");
+
+        // Test: FileSystems#newFileSystem(FileRef)
+        Map<String,?> env = new HashMap<String,Object>();
+        FileSystems.newFileSystem(zipfile, env, null).close();
+
+        // Test: FileSystems#newFileSystem(URI)
+        URI uri = URI.create("zip" + zipfile.toUri().toString().substring(4));
+        FileSystem fs = FileSystems.newFileSystem(uri, env, null);
+
+        // Test: exercise toUri method
+        String expected = uri.toString() + "#/foo";
+        String actual = fs.getPath("/foo").toUri().toString();
+        if (!actual.equals(expected)) {
+            throw new RuntimeException("toUri returned '" + actual +
+                "', expected '" + expected + "'");
+        }
+
+        // Test: exercise directory iterator and retrieval of basic attributes
+        Files.walkFileTree(fs.getPath("/"), new FileTreePrinter());
+
+        // Test: DirectoryStream
+        found = false;
+        DirectoryStream<Path> stream = fs.getPath("/").newDirectoryStream();
+        try {
+            for (Path entry: stream) {
+                found = entry.toString().equals("/META-INF/");
+                if (found) break;
+            }
+        } finally {
+            stream.close();
+        }
+
+        if (!found)
+            throw new RuntimeException("Expected file not found");
+
+        // Test: copy file from zip file to current (scratch) directory
+        Path source = fs.getPath("/META-INF/services/java.nio.file.spi.FileSystemProvider");
+        if (source.exists()) {
+            Path target = Paths.get(source.getName().toString());
+            source.copyTo(target, StandardCopyOption.REPLACE_EXISTING);
+            try {
+                long s1 = Attributes.readBasicFileAttributes(source).size();
+                long s2 = Attributes.readBasicFileAttributes(target).size();
+                if (s2 != s1)
+                    throw new RuntimeException("target size != source size");
+            } finally {
+                target.delete();
+            }
+        }
+
+        // Test: FileStore
+        FileStore store = fs.getPath("/").getFileStore();
+        if (!store.supportsFileAttributeView("basic"))
+            throw new RuntimeException("BasicFileAttributeView should be supported");
+
+        // Test: ClosedFileSystemException
+        fs.close();
+        if (fs.isOpen())
+            throw new RuntimeException("FileSystem should be closed");
+        try {
+            fs.getPath("/missing").checkAccess(AccessMode.READ);
+        } catch (ClosedFileSystemException x) { }
+    }
+
+    // FileVisitor that pretty prints a file tree
+    static class FileTreePrinter extends SimpleFileVisitor<Path> {
+        private int indent = 0;
+
+        private void indent() {
+            StringBuilder sb = new StringBuilder(indent);
+            for (int i=0; i<indent; i++) sb.append(" ");
+            System.out.print(sb);
+        }
+
+        @Override
+        public FileVisitResult preVisitDirectory(Path dir,
+                                                 BasicFileAttributes attrs)
+        {
+            if (dir.getName() != null) {
+                indent();
+                System.out.println(dir.getName() + "/");
+                indent++;
+            }
+            return FileVisitResult.CONTINUE;
+        }
+
+        @Override
+        public FileVisitResult visitFile(Path file,
+                                         BasicFileAttributes attrs)
+        {
+            indent();
+            System.out.print(file.getName());
+            if (attrs.isRegularFile())
+                System.out.format(" (%d)", attrs.size());
+            System.out.println();
+            return FileVisitResult.CONTINUE;
+        }
+
+        @Override
+        public FileVisitResult postVisitDirectory(Path dir, IOException exc)
+            throws IOException
+        {
+            if (exc != null)
+                super.postVisitDirectory(dir, exc);
+            if (dir.getName() != null)
+                indent--;
+            return FileVisitResult.CONTINUE;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/demo/zipfs/PathOps.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,416 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along 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.nio.file.*;
+import java.net.*;
+import java.util.*;
+import java.io.IOException;
+
+/**
+ * Tests path operations for zip provider.
+ */
+
+public class PathOps {
+
+    static final java.io.PrintStream out = System.out;
+    static FileSystem fs;
+
+    private String input;
+    private Path path;
+    private Exception exc;
+
+    private PathOps(String s) {
+        out.println();
+        input = s;
+        try {
+            path = fs.getPath(s);
+            out.format("%s -> %s", s, path);
+        } catch (Exception x) {
+            exc = x;
+            out.format("%s -> %s", s, x);
+        }
+        out.println();
+    }
+
+    Path path() {
+        return path;
+    }
+
+    void fail() {
+        throw new RuntimeException("PathOps failed");
+    }
+
+    void checkPath() {
+        if (path == null) {
+            throw new InternalError("path is null");
+        }
+    }
+
+    void check(Object result, String expected) {
+        out.format("\tExpected: %s\n", expected);
+        out.format("\tActual: %s\n",  result);
+        if (result == null) {
+            if (expected == null) return;
+        } else {
+            // compare string representations
+            if (expected != null && result.toString().equals(expected.toString()))
+                return;
+        }
+        fail();
+    }
+
+    void check(Object result, boolean expected) {
+        check(result, Boolean.toString(expected));
+    }
+
+    PathOps root(String expected) {
+        out.println("check root");
+        checkPath();
+        check(path.getRoot(), expected);
+        return this;
+    }
+
+    PathOps parent(String expected) {
+        out.println("check parent");
+        checkPath();
+        check(path.getParent(), expected);
+        return this;
+    }
+
+    PathOps name(String expected) {
+        out.println("check name");
+        checkPath();
+        check(path.getName(), expected);
+        return this;
+    }
+
+    PathOps element(int index, String expected) {
+        out.format("check element %d\n", index);
+        checkPath();
+        check(path.getName(index), expected);
+        return this;
+    }
+
+    PathOps subpath(int startIndex, int endIndex, String expected) {
+        out.format("test subpath(%d,%d)\n", startIndex, endIndex);
+        checkPath();
+        check(path.subpath(startIndex, endIndex), expected);
+        return this;
+    }
+
+    PathOps starts(String prefix) {
+        out.format("test startsWith with %s\n", prefix);
+        checkPath();
+        Path s = fs.getPath(prefix);
+        check(path.startsWith(s), true);
+        return this;
+    }
+
+    PathOps notStarts(String prefix) {
+        out.format("test not startsWith with %s\n", prefix);
+        checkPath();
+        Path s = fs.getPath(prefix);
+        check(path.startsWith(s), false);
+        return this;
+    }
+
+    PathOps ends(String suffix) {
+        out.format("test endsWith %s\n", suffix);
+        checkPath();
+        Path s = fs.getPath(suffix);
+        check(path.endsWith(s), true);
+        return this;
+    }
+
+    PathOps notEnds(String suffix) {
+        out.format("test not endsWith %s\n", suffix);
+        checkPath();
+        Path s = fs.getPath(suffix);
+        check(path.endsWith(s), false);
+        return this;
+    }
+
+    PathOps absolute() {
+        out.println("check path is absolute");
+        checkPath();
+        check(path.isAbsolute(), true);
+        return this;
+    }
+
+    PathOps notAbsolute() {
+        out.println("check path is not absolute");
+        checkPath();
+        check(path.isAbsolute(), false);
+        return this;
+    }
+
+    PathOps resolve(String other, String expected) {
+        out.format("test resolve %s\n", other);
+        checkPath();
+        check(path.resolve(other), expected);
+        return this;
+    }
+
+    PathOps relativize(String other, String expected) {
+        out.format("test relativize %s\n", other);
+        checkPath();
+        Path that = fs.getPath(other);
+        check(path.relativize(that), expected);
+        return this;
+    }
+
+    PathOps normalize(String expected) {
+        out.println("check normalized path");
+        checkPath();
+        check(path.normalize(), expected);
+        return this;
+    }
+
+    PathOps string(String expected) {
+        out.println("check string representation");
+        checkPath();
+        check(path, expected);
+        return this;
+    }
+
+    PathOps invalid() {
+        if (!(exc instanceof InvalidPathException)) {
+            out.println("InvalidPathException not thrown as expected");
+            fail();
+        }
+        return this;
+    }
+
+    static PathOps test(String s) {
+        return new PathOps(s);
+    }
+
+    // -- PathOpss --
+
+    static void header(String s) {
+        out.println();
+        out.println();
+        out.println("-- " + s + " --");
+    }
+
+    static void doPathOpTests() {
+        header("Path operations");
+
+        // all components
+        test("/a/b/c")
+            .root("/")
+            .parent("/a/b")
+            .name("c");
+
+        // root component only
+        test("/")
+            .root("/")
+            .parent(null)
+            .name(null);
+
+        // no root component
+        test("a/b")
+            .root(null)
+            .parent("a")
+            .name("b");
+
+        // name component only
+        test("foo")
+            .root(null)
+            .parent(null)
+            .name("foo");
+
+        // startsWith
+        test("/")
+            .starts("/")
+            .notStarts("/foo");
+        test("/foo")
+            .starts("/")
+            .starts("/foo")
+            .notStarts("/f");
+        test("/foo/bar")
+            .starts("/")
+            .starts("/foo")
+            .starts("/foo/bar")
+            .notStarts("/f")
+            .notStarts("foo")
+            .notStarts("foo/bar");
+        test("foo")
+            .starts("foo")
+            .notStarts("f");
+        test("foo/bar")
+            .starts("foo")
+            .starts("foo/bar")
+            .notStarts("f")
+            .notStarts("/foo")
+            .notStarts("/foo/bar");
+
+        // endsWith
+        test("/")
+            .ends("/")
+            .notEnds("foo")
+            .notEnds("/foo");
+        test("/foo")
+            .ends("foo")
+            .ends("/foo")
+            .notEnds("/");
+        test("/foo/bar")
+            .ends("bar")
+            .ends("foo/bar")
+            .ends("/foo/bar")
+            .notEnds("/bar");
+        test("foo")
+            .ends("foo");
+        test("foo/bar")
+            .ends("bar")
+            .ends("foo/bar");
+
+        // elements
+        test("a/b/c")
+            .element(0,"a")
+            .element(1,"b")
+            .element(2,"c");
+
+        // isAbsolute
+        test("/")
+            .absolute();
+        test("/tmp")
+            .absolute();
+        test("tmp")
+            .notAbsolute();
+
+        // resolve
+        test("/tmp")
+            .resolve("foo", "/tmp/foo")
+            .resolve("/foo", "/foo");
+        test("tmp")
+            .resolve("foo", "tmp/foo")
+            .resolve("/foo", "/foo");
+
+        // relativize
+        test("/a/b/c")
+            .relativize("/a/b/c", null)
+            .relativize("/a/b/c/d/e", "d/e")
+            .relativize("/a/x", "../../x");
+
+        // normalize
+        test("/")
+            .normalize("/");
+        test("foo")
+            .normalize("foo");
+        test("/foo")
+            .normalize("/foo");
+        test(".")
+            .normalize(null);
+        test("..")
+            .normalize("..");
+        test("/..")
+            .normalize("/");
+        test("/../..")
+            .normalize("/");
+        test("foo/.")
+            .normalize("foo");
+        test("./foo")
+            .normalize("foo");
+        test("foo/..")
+            .normalize(null);
+        test("../foo")
+            .normalize("../foo");
+        test("../../foo")
+            .normalize("../../foo");
+        test("foo/bar/..")
+            .normalize("foo");
+        test("foo/bar/gus/../..")
+            .normalize("foo");
+        test("/foo/bar/gus/../..")
+            .normalize("/foo");
+
+        // invalid
+        test("foo\u0000bar")
+            .invalid();
+        test("\u0000foo")
+            .invalid();
+        test("bar\u0000")
+            .invalid();
+        test("//foo\u0000bar")
+            .invalid();
+        test("//\u0000foo")
+            .invalid();
+        test("//bar\u0000")
+            .invalid();
+
+        // normalization
+        test("//foo//bar")
+            .string("/foo/bar")
+            .root("/")
+            .parent("/foo")
+            .name("bar");
+    }
+
+    static void npes() {
+        header("NullPointerException");
+
+        Path path = fs.getPath("foo");
+
+        try {
+            path.resolve((String)null);
+            throw new RuntimeException("NullPointerException not thrown");
+        } catch (NullPointerException npe) {
+        }
+
+        try {
+            path.relativize(null);
+            throw new RuntimeException("NullPointerException not thrown");
+        } catch (NullPointerException npe) {
+        }
+
+        try {
+            path.compareTo(null);
+            throw new RuntimeException("NullPointerException not thrown");
+        } catch (NullPointerException npe) {
+        }
+
+        try {
+            path.startsWith(null);
+            throw new RuntimeException("NullPointerException not thrown");
+        } catch (NullPointerException npe) {
+        }
+
+        try {
+            path.endsWith(null);
+            throw new RuntimeException("NullPointerException not thrown");
+        } catch (NullPointerException npe) {
+        }
+
+    }
+
+    public static void main(String[] args) throws Throwable {
+
+        Path zipfile = Paths.get(args[0]);
+        Map<String,?> env = new HashMap<String,Object>();
+        fs = FileSystems.newFileSystem(zipfile, env, null);
+        npes();
+        doPathOpTests();
+        fs.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/demo/zipfs/ZipFSTester.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,633 @@
+/*
+ * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along 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.io.*;
+import java.nio.*;
+import java.nio.channels.*;
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.net.*;
+import java.util.*;
+
+import static java.nio.file.StandardOpenOption.*;
+import static java.nio.file.StandardCopyOption.*;
+
+/*
+ * Tests various zipfs operations.
+ */
+
+public class ZipFSTester {
+
+    public static void main(String[] args) throws Throwable {
+        FileSystem fs = null;
+        try {
+            fs = newZipFileSystem(Paths.get(args[0]), new HashMap<String, Object>());
+            test(fs);
+            test2(fs);   // more tests
+        } finally {
+            if (fs != null)
+                fs.close();
+        }
+    }
+
+    static void test(FileSystem fs)
+        throws Exception
+    {
+        Random rdm = new Random();
+
+        // clone a fs and test on it
+        Path tmpfsPath = getTempPath();
+        Map<String, Object> env = new HashMap<String, Object>();
+        env.put("createNew", true);
+        FileSystem fs0 = newZipFileSystem(tmpfsPath, env);
+        z2zcopy(fs, fs0, "/", 0);
+        fs0.close();                // sync to file
+
+        fs = newZipFileSystem(tmpfsPath, new HashMap<String, Object>());
+
+        try {
+            // prepare a src
+            Path src = getTempPath();
+            String tmpName = src.toString();
+            OutputStream os = src.newOutputStream();
+            byte[] bits = new byte[12345];
+            rdm.nextBytes(bits);
+            os.write(bits);
+            os.close();
+
+            // copyin
+            Path dst = getPathWithParents(fs, tmpName);
+            src.copyTo(dst);
+            checkEqual(src, dst);
+
+            // copy
+            Path dst2 = getPathWithParents(fs, "/xyz" + rdm.nextInt(100) +
+                                           "/efg" + rdm.nextInt(100) + "/foo.class");
+            dst.copyTo(dst2);
+            //dst.moveTo(dst2);
+            checkEqual(src, dst2);
+
+            // delete
+            dst.delete();
+            if (dst.exists())
+                throw new RuntimeException("Failed!");
+
+            // moveout
+            Path dst3 = Paths.get(tmpName + "_Tmp");
+            dst2.moveTo(dst3);
+            checkEqual(src, dst3);
+
+            // delete
+            if (dst2.exists())
+                throw new RuntimeException("Failed!");
+            dst3.delete();
+            if (dst3.exists())
+                throw new RuntimeException("Failed!");
+
+            // newInputStream on dir
+            Path parent = dst2.getParent();
+            try {
+                parent.newInputStream();
+                throw new RuntimeException("Failed");
+            } catch (FileSystemException e) {
+                e.printStackTrace();    // expected fse
+            }
+
+            // rmdirs
+            try {
+                rmdirs(parent);
+            } catch (IOException x) {
+                x.printStackTrace();
+            }
+
+            // newFileChannel() copy in, out and verify via fch
+            fchCopy(src, dst);    // in
+            checkEqual(src, dst);
+            Path tmp = Paths.get(tmpName + "_Tmp");
+            fchCopy(dst, tmp);   //  out
+            checkEqual(src, tmp);
+            tmp.delete();
+
+            // test channels
+            channel(fs, dst);
+            dst.delete();
+            src.delete();
+        } finally {
+            if (fs != null)
+                fs.close();
+            if (tmpfsPath.exists())
+                tmpfsPath.delete();
+        }
+    }
+
+    static void test2(FileSystem fs) throws Exception {
+
+        Path fs1Path = getTempPath();
+        Path fs2Path = getTempPath();
+        Path fs3Path = getTempPath();
+
+        if (fs1Path.exists())
+            fs1Path.delete();
+        if (fs2Path.exists())
+            fs2Path.delete();
+        if (fs3Path.exists())
+            fs3Path.delete();
+
+        // create a new filesystem, copy everything from fs
+        Map<String, Object> env = new HashMap<String, Object>();
+        env.put("createNew", true);
+        FileSystem fs0 = newZipFileSystem(fs1Path, env);
+
+        final FileSystem fs2 = newZipFileSystem(fs2Path, env);
+        final FileSystem fs3 = newZipFileSystem(fs3Path, env);
+
+        System.out.println("copy src: fs -> fs0...");
+        z2zcopy(fs, fs0, "/", 0);   // copy fs -> fs1
+        fs0.close();                // dump to file
+
+        System.out.println("open fs0 as fs1");
+        env = new HashMap<String, Object>();
+        final FileSystem fs1 = newZipFileSystem(fs1Path, env);
+
+        System.out.println("listing...");
+        final ArrayList<String> files = new ArrayList<>();
+        final ArrayList<String> dirs = new ArrayList<>();
+        list(fs1.getPath("/"), files, dirs);
+
+        Thread t0 = new Thread(new Runnable() {
+            public void run() {
+                List<String> list = new ArrayList<>(dirs);
+                Collections.shuffle(list);
+                for (String path : list) {
+                    try {
+                        z2zcopy(fs1, fs2, path, 0);
+                    } catch (Exception x) {
+                        x.printStackTrace();
+                    }
+                }
+            }
+
+        });
+
+        Thread t1 = new Thread(new Runnable() {
+            public void run() {
+                List<String> list = new ArrayList<>(dirs);
+                Collections.shuffle(list);
+                for (String path : list) {
+                    try {
+                        z2zcopy(fs1, fs2, path, 1);
+                    } catch (Exception x) {
+                        x.printStackTrace();
+                    }
+                }
+            }
+
+        });
+
+        Thread t2 = new Thread(new Runnable() {
+            public void run() {
+                List<String> list = new ArrayList<>(dirs);
+                Collections.shuffle(list);
+                for (String path : list) {
+                    try {
+                        z2zcopy(fs1, fs2, path, 2);
+                    } catch (Exception x) {
+                        x.printStackTrace();
+                    }
+                }
+            }
+
+        });
+
+        Thread t3 = new Thread(new Runnable() {
+            public void run() {
+                List<String> list = new ArrayList<>(files);
+                Collections.shuffle(list);
+                while (!list.isEmpty()) {
+                    Iterator<String> itr = list.iterator();
+                    while (itr.hasNext()) {
+                        String path = itr.next();
+                        try {
+                            if (fs2.getPath(path).exists()) {
+                                z2zmove(fs2, fs3, path);
+                                itr.remove();
+                            }
+                        } catch (FileAlreadyExistsException x){
+                            itr.remove();
+                        } catch (Exception x) {
+                            x.printStackTrace();
+                        }
+                    }
+                }
+            }
+
+        });
+
+        System.out.println("copying/removing...");
+        t0.start(); t1.start(); t2.start(); t3.start();
+        t0.join(); t1.join(); t2.join(); t3.join();
+
+        System.out.println("closing: fs1, fs2");
+        fs1.close();
+        fs2.close();
+
+        int failed = 0;
+        System.out.println("checkEqual: fs vs fs3");
+        for (String path : files) {
+            try {
+                checkEqual(fs.getPath(path), fs3.getPath(path));
+            } catch (IOException x) {
+                //x.printStackTrace();
+                failed++;
+            }
+        }
+        System.out.println("closing: fs3");
+        fs3.close();
+
+        System.out.println("opening: fs3 as fs4");
+        FileSystem fs4 = newZipFileSystem(fs3Path, env);
+
+
+        ArrayList<String> files2 = new ArrayList<>();
+        ArrayList<String> dirs2 = new ArrayList<>();
+        list(fs4.getPath("/"), files2, dirs2);
+
+        System.out.println("checkEqual: fs vs fs4");
+        for (String path : files2) {
+            checkEqual(fs.getPath(path), fs4.getPath(path));
+        }
+        System.out.println("walking: fs4");
+        walk(fs4.getPath("/"));
+        System.out.println("closing: fs4");
+        fs4.close();
+
+        System.out.printf("failed=%d%n", failed);
+
+        fs1Path.delete();
+        fs2Path.delete();
+        fs3Path.delete();
+    }
+
+    private static FileSystem newZipFileSystem(Path path, Map<String, ?> env)
+        throws IOException
+    {
+        return FileSystems.newFileSystem(
+                   URI.create("zip" +
+                               path.toUri().toString().substring(4)),
+                   env,
+                   null);
+    }
+
+    private static Path getTempPath() throws IOException
+    {
+        File tmp = File.createTempFile("testzipfs_", "zip");
+        tmp.delete();    // we need a clean path, no file
+        return tmp.toPath();
+    }
+
+    private static void list(Path path, List<String> files, List<String> dirs )
+        throws IOException
+    {
+        if (Attributes.readBasicFileAttributes(path).isDirectory()) {
+            DirectoryStream<Path> ds = path.newDirectoryStream();
+            for (Path child : ds)
+                list(child, files, dirs);
+            ds.close();
+            dirs.add(path.toString());
+        } else {
+            files.add(path.toString());
+        }
+    }
+
+    private static void z2zcopy(FileSystem src, FileSystem dst, String path,
+                                int method)
+        throws IOException
+    {
+        Path srcPath = src.getPath(path);
+        Path dstPath = dst.getPath(path);
+
+        if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) {
+            if (!dstPath.exists()) {
+                try {
+                    mkdirs(dstPath);
+                } catch (FileAlreadyExistsException x) {}
+            }
+            DirectoryStream<Path> ds = srcPath.newDirectoryStream();
+            for (Path child : ds) {
+                z2zcopy(src, dst,
+                        path + (path.endsWith("/")?"":"/") + child.getName(),
+                        method);
+            }
+            ds.close();
+        } else {
+            try {
+                if (dstPath.exists())
+                    return;
+                switch (method) {
+                case 0:
+                    srcPath.copyTo(dstPath);
+                    break;
+                case 1:
+                    chCopy(srcPath, dstPath);
+                    break;
+                case 2:
+                    //fchCopy(srcPath, dstPath);
+                    streamCopy(srcPath, dstPath);
+                    break;
+                }
+            } catch (FileAlreadyExistsException x) {}
+        }
+    }
+
+    private static void z2zmove(FileSystem src, FileSystem dst, String path)
+        throws IOException
+    {
+        Path srcPath = src.getPath(path);
+        Path dstPath = dst.getPath(path);
+
+        if (Boolean.TRUE.equals(srcPath.getAttribute("isDirectory"))) {
+            if (!dstPath.exists())
+                mkdirs(dstPath);
+            DirectoryStream<Path> ds = srcPath.newDirectoryStream();
+            for (Path child : ds) {
+                z2zmove(src, dst,
+                        path + (path.endsWith("/")?"":"/") + child.getName());
+            }
+            ds.close();
+        } else {
+            //System.out.println("moving..." + path);
+            Path parent = dstPath.getParent();
+            if (parent != null && parent.notExists())
+                mkdirs(parent);
+            srcPath.moveTo(dstPath);
+        }
+    }
+
+    private static void walk(Path path) throws IOException
+    {
+        Files.walkFileTree(
+            path,
+            new SimpleFileVisitor<Path>() {
+                private int indent = 0;
+                private void indent() {
+                    int n = 0;
+                    while (n++ < indent)
+                        System.out.printf(" ");
+                }
+
+                @Override
+                public FileVisitResult visitFile(Path file,
+                                                 BasicFileAttributes attrs)
+                {
+                    indent();
+                    System.out.printf("%s%n", file.getName().toString());
+                    return FileVisitResult.CONTINUE;
+                }
+
+                @Override
+                public FileVisitResult preVisitDirectory(Path dir,
+                                                         BasicFileAttributes attrs)
+                {
+                    indent();
+                    System.out.printf("[%s]%n", dir.toString());
+                    indent += 2;
+                    return FileVisitResult.CONTINUE;
+                }
+
+                @Override
+                public FileVisitResult postVisitDirectory(Path dir,
+                                                          IOException ioe)
+                    throws IOException
+                {
+                    indent -= 2;
+                    return FileVisitResult.CONTINUE;
+                }
+        });
+    }
+
+    private static void mkdirs(Path path) throws IOException {
+        path = path.toAbsolutePath();
+        Path parent = path.getParent();
+        if (parent != null) {
+            if (parent.notExists())
+                mkdirs(parent);
+        }
+        path.createDirectory();
+    }
+
+    private static void rmdirs(Path path) throws IOException {
+        while (path != null && path.getNameCount() != 0) {
+            path.delete();
+            path = path.getParent();
+        }
+    }
+
+    // check the content of two paths are equal
+    private static void checkEqual(Path src, Path dst) throws IOException
+    {
+        //System.out.printf("checking <%s> vs <%s>...%n",
+        //                  src.toString(), dst.toString());
+
+        //streams
+        InputStream isSrc = src.newInputStream();
+        InputStream isDst = dst.newInputStream();
+        byte[] bufSrc = new byte[8192];
+        byte[] bufDst = new byte[8192];
+
+        try {
+            int nSrc = 0;
+            while ((nSrc = isSrc.read(bufSrc)) != -1) {
+                int nDst = 0;
+                while (nDst < nSrc) {
+                    int n = isDst.read(bufDst, nDst, nSrc - nDst);
+                    if (n == -1) {
+                        System.out.printf("checking <%s> vs <%s>...%n",
+                                          src.toString(), dst.toString());
+                        throw new RuntimeException("CHECK FAILED!");
+                    }
+                    nDst += n;
+                }
+                while (--nSrc >= 0) {
+                    if (bufSrc[nSrc] != bufDst[nSrc]) {
+                        System.out.printf("checking <%s> vs <%s>...%n",
+                                          src.toString(), dst.toString());
+                        throw new RuntimeException("CHECK FAILED!");
+                    }
+                    nSrc--;
+                }
+            }
+        } finally {
+            isSrc.close();
+            isDst.close();
+        }
+
+        // channels
+        SeekableByteChannel chSrc = src.newByteChannel();
+        SeekableByteChannel chDst = dst.newByteChannel();
+        if (chSrc.size() != chDst.size()) {
+            System.out.printf("src[%s].size=%d, dst[%s].size=%d%n",
+                              chSrc.toString(), chSrc.size(),
+                              chDst.toString(), chDst.size());
+            throw new RuntimeException("CHECK FAILED!");
+        }
+        ByteBuffer bbSrc = ByteBuffer.allocate(8192);
+        ByteBuffer bbDst = ByteBuffer.allocate(8192);
+
+        try {
+            int nSrc = 0;
+            while ((nSrc = chSrc.read(bbSrc)) != -1) {
+                int nDst = chDst.read(bbDst);
+                if (nSrc != nDst) {
+                    System.out.printf("checking <%s> vs <%s>...%n",
+                                      src.toString(), dst.toString());
+                    throw new RuntimeException("CHECK FAILED!");
+                }
+                while (--nSrc >= 0) {
+                    if (bbSrc.get(nSrc) != bbDst.get(nSrc)) {
+                        System.out.printf("checking <%s> vs <%s>...%n",
+                                          src.toString(), dst.toString());
+                        throw new RuntimeException("CHECK FAILED!");
+                    }
+                    nSrc--;
+                }
+                bbSrc.flip();
+                bbDst.flip();
+            }
+        } catch (IOException x) {
+            x.printStackTrace();
+        } finally {
+            chSrc.close();
+            chDst.close();
+        }
+    }
+
+    private static void fchCopy(Path src, Path dst) throws IOException
+    {
+        Set<OpenOption> read = new HashSet<>();
+        read.add(READ);
+        Set<OpenOption> openwrite = new HashSet<>();
+        openwrite.add(CREATE_NEW);
+        openwrite.add(WRITE);
+
+        FileChannel srcFc = src.getFileSystem()
+                               .provider()
+                               .newFileChannel(src, read);
+        FileChannel dstFc = dst.getFileSystem()
+                               .provider()
+                               .newFileChannel(dst, openwrite);
+
+        try {
+            ByteBuffer bb = ByteBuffer.allocate(8192);
+            while (srcFc.read(bb) >= 0) {
+                bb.flip();
+                dstFc.write(bb);
+                bb.clear();
+            }
+        } finally {
+            srcFc.close();
+            dstFc.close();
+        }
+    }
+
+    private static void chCopy(Path src, Path dst) throws IOException
+    {
+        Set<OpenOption> read = new HashSet<>();
+        read.add(READ);
+        Set<OpenOption> openwrite = new HashSet<>();
+        openwrite.add(CREATE_NEW);
+        openwrite.add(WRITE);
+
+        SeekableByteChannel srcCh = src.newByteChannel(read);
+        SeekableByteChannel dstCh = dst.newByteChannel(openwrite);
+
+        try {
+            ByteBuffer bb = ByteBuffer.allocate(8192);
+            while (srcCh.read(bb) >= 0) {
+                bb.flip();
+                dstCh.write(bb);
+                bb.clear();
+            }
+        } finally {
+            srcCh.close();
+            dstCh.close();
+        }
+    }
+
+    private static void streamCopy(Path src, Path dst) throws IOException
+    {
+        InputStream isSrc = src.newInputStream();
+        OutputStream osDst = dst.newOutputStream();
+        byte[] buf = new byte[8192];
+        try {
+            int n = 0;
+            while ((n = isSrc.read(buf)) != -1) {
+                osDst.write(buf, 0, n);
+            }
+        } finally {
+            isSrc.close();
+            osDst.close();
+        }
+    }
+
+    static void channel(FileSystem fs, Path path)
+        throws Exception
+    {
+        System.out.println("test ByteChannel...");
+        SeekableByteChannel sbc = path.newByteChannel();
+        Set<OpenOption> read = new HashSet<>();
+        read.add(READ);
+        System.out.printf("   sbc[0]: pos=%d, size=%d%n", sbc.position(), sbc.size());
+        ByteBuffer bb = ByteBuffer.allocate((int)sbc.size());
+        int n = sbc.read(bb);
+        System.out.printf("   sbc[1]: read=%d, pos=%d, size=%d%n",
+                          n, sbc.position(), sbc.size());
+        ByteBuffer bb2 = ByteBuffer.allocate((int)sbc.size());
+        int N = 120;
+        sbc.close();
+
+        // sbc.position(pos) is not supported in current version
+        // try the FileChannel
+        sbc = fs.provider().newFileChannel(path, read);
+        sbc.position(N);
+        System.out.printf("   sbc[2]: pos=%d, size=%d%n",
+                          sbc.position(), sbc.size());
+        bb2.limit(100);
+        n = sbc.read(bb2);
+        System.out.printf("   sbc[3]: read=%d, pos=%d, size=%d%n",
+                          n, sbc.position(), sbc.size());
+        System.out.printf("   sbc[4]: bb[%d]=%d, bb1[0]=%d%n",
+                          N, bb.get(N) & 0xff, bb2.get(0) & 0xff);
+        sbc.close();
+    }
+
+    // create parents if does not exist
+    static Path getPathWithParents(FileSystem fs, String name)
+        throws Exception
+    {
+        Path path = fs.getPath(name);
+        Path parent = path.getParent();
+        if (parent != null && parent.notExists())
+            mkdirs(parent);
+        return path;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/demo/zipfs/basic.sh	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,73 @@
+#
+# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+# 
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+# 
+# You should have received a copy of the GNU General Public License version
+# 2 along 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 6990846
+# @summary Test ZipFileSystem demo
+# @build Basic PathOps ZipFSTester
+# @run shell basic.sh
+
+if [ -z "${TESTJAVA}" ]; then
+    echo "Test must be run with jtreg"
+    exit 0
+fi
+
+ZIPFS="${TESTJAVA}/demo/nio/zipfs/zipfs.jar"
+if [ ! -r "${ZIPFS}" ]; then
+    echo "${ZIPFS} not found"
+    exit 0
+fi
+
+OS=`uname -s`
+case "$OS" in
+    Windows_* )
+        CLASSPATH="${TESTCLASSES};${ZIPFS}"
+        ;;
+    * )
+        CLASSPATH="${TESTCLASSES}:${ZIPFS}"
+        ;;
+esac
+export CLASSPATH
+
+failures=0
+
+go() {
+    echo ""
+    ${TESTJAVA}/bin/java $1 $2 $3 2>&1
+    if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+}
+
+# Run the tests
+
+go Basic "${ZIPFS}"
+go PathOps "${ZIPFS}"
+go ZipFSTester "${ZIPFS}"
+
+#
+# Results
+#
+
+if [ $failures -gt 0 ];
+then echo "$failures tests failed";
+else echo "All tests passed";
+fi
+exit $failures
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Focus/FocusOwnerFrameOnClick/FocusOwnerFrameOnClick.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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      FocusOwnerFrameOnClick.java %W% %E%
+  @bug       6886678
+  @summary   Tests that clicking an owner frame switches focus from its owned window.
+  @author    Anton Tarasov: area=awt.focus
+  @library   ../../regtesthelpers
+  @build     Util
+  @run       main FocusOwnerFrameOnClick
+*/
+
+import java.awt.*;
+import java.awt.event.*;
+import java.applet.Applet;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.lang.reflect.InvocationTargetException;
+import test.java.awt.regtesthelpers.Util;
+
+public class FocusOwnerFrameOnClick extends Applet {
+    Robot robot;
+    Frame frame = new Frame("Frame");
+    Window window = new Window(frame);
+    Button fButton = new Button("fButton");
+    Button wButton = new Button("wButton");
+
+    AtomicBoolean focused = new AtomicBoolean(false);
+
+    public static void main(String[] args) {
+        FocusOwnerFrameOnClick app = new FocusOwnerFrameOnClick();
+        app.init();
+        app.start();
+    }
+
+    public void init() {
+        robot = Util.createRobot();
+
+        frame.setLayout(new FlowLayout());
+        frame.setSize(200, 200);
+        frame.add(fButton);
+
+        window.setLocation(300, 0);
+        window.add(wButton);
+        window.pack();
+    }
+
+    public void start() {
+        frame.setVisible(true);
+        Util.waitForIdle(robot);
+
+        window.setVisible(true);
+        Util.waitForIdle(robot);
+
+        if (!wButton.hasFocus()) {
+            if (!Util.trackFocusGained(wButton, new Runnable() {
+                    public void run() {
+                        Util.clickOnComp(wButton, robot);
+                    }
+                }, 2000, false))
+            {
+                throw new TestErrorException("wButton didn't gain focus on showing");
+            }
+        }
+
+        Runnable clickAction = new Runnable() {
+                public void run() {
+                    Point loc = fButton.getLocationOnScreen();
+                    Dimension dim = fButton.getSize();
+
+                    robot.mouseMove(loc.x, loc.y + dim.height + 20);
+                    robot.delay(50);
+                    robot.mousePress(InputEvent.BUTTON1_MASK);
+                    robot.delay(50);
+                    robot.mouseRelease(InputEvent.BUTTON1_MASK);
+                }
+            };
+
+        if (!Util.trackWindowGainedFocus(frame, clickAction, 2000, true)) {
+            throw new TestFailedException("The frame wasn't focused on click");
+        }
+
+        System.out.println("Test passed.");
+    }
+}
+
+/**
+ * Thrown when the behavior being verified is found wrong.
+ */
+class TestFailedException extends RuntimeException {
+    TestFailedException(String msg) {
+        super("Test failed: " + msg);
+    }
+}
+
+/**
+ * Thrown when an error not related to the behavior being verified is encountered.
+ */
+class TestErrorException extends RuntimeException {
+    TestErrorException(String msg) {
+        super("Unexpected error: " + msg);
+    }
+}
--- a/jdk/test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Extra.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Extra.java	Wed Jul 05 17:24:21 2017 +0200
@@ -21,16 +21,15 @@
     static final int SHIFT = 1;
     static final int CTRL = 2;
     static final int ALT = 3;
-    static CheckingModifierAdapter adapterTest1;
-    static CheckingModifierAdapter adapterTest2;
-    static CheckingModifierAdapter adapterTest3;
-    static CheckingModifierAdapter adapterTest4;
+    static CheckingModifierAdapterExtra adapterTest1;
+    static CheckingModifierAdapterExtra adapterTest2;
+    static CheckingModifierAdapterExtra adapterTest3;
+    static CheckingModifierAdapterExtra adapterTest4;
 
     static boolean debug = true; //dump all errors (debug) or throw first(under jtreg) exception
     static boolean autorun = false; //use robot or manual run
     static int testModifier = NONE;
 
-    static int [] mouseButtons;
     static int [] mouseButtonDownMasks;
 
     //an arrays representing a modifiersEx of extra mouse buttons while using ALT/CTRL/SHIFT or none of them
@@ -39,7 +38,6 @@
     static int [] modifiersExStandardCTRL;
     static int [] modifiersExStandardALT;
 
-    //    final static int [] mouseButtons = new int [] {MouseEvent.BUTTON1_MASK, MouseEvent.BUTTON2_MASK, MouseEvent.BUTTON3_MASK};
     // BUTTON1, 2, 3 press-release.
     final static int  modifiersStandard = 0; //InputEvent.BUTTON_DOWN_MASK;
 
@@ -56,7 +54,7 @@
 
         if (modifiersEx != curStandardExModifiers[index]){
 //            System.out.println(">>>>>>>>>>>>>>> Pressed. modifiersEx "+modifiersEx +" : "+!= curStandardExModifiers");
-            MessageLogger.reportError("Test failed :  Pressed. modifiersEx != curStandardExModifiers");
+            MessageLogger.reportError("Test failed :  Pressed. modifiersEx != curStandardExModifiers. Got: " + modifiersEx + " , Expected: " + curStandardExModifiers[index]);
         }
 
      //check event.paramString() output
@@ -168,7 +166,7 @@
         }
 
         if (modifiersEx != curStandardExModifiers[index]){
-            MessageLogger.reportError("Test failed :  Released. modifiersEx != curStandardExModifiers");
+            MessageLogger.reportError("Test failed :  Released. modifiersEx != curStandardExModifiers. Got: " + modifiersEx + " , Expected: " + curStandardExModifiers[index]);
         }
 
      //check event.paramString() output
@@ -191,7 +189,7 @@
         }
 
         if (modifiersEx != curStandardExModifiers[index]){
-            MessageLogger.reportError("Test failed :  Clicked. modifiersEx != curStandardExModifiers");
+            MessageLogger.reportError("Test failed :  Clicked. modifiersEx != curStandardExModifiers. Got: " + modifiersEx + " , Expected: " + curStandardExModifiers[index]);
         }
 
      //check event.paramString() output
@@ -275,11 +273,11 @@
         this.addMouseListener(adapterTest1);
         robot.delay(1000);
         robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
-        for (int i = 3; i< mouseButtons.length; i++){
-            System.out.println("testNONE() => " +mouseButtons[i] );
-            robot.mousePress(mouseButtons[i]);
+        for (int i = 3; i< mouseButtonDownMasks.length; i++){
+            System.out.println("testNONE() => " +mouseButtonDownMasks[i] );
+            robot.mousePress(mouseButtonDownMasks[i]);
             robot.delay(100);
-            robot.mouseRelease(mouseButtons[i]);
+            robot.mouseRelease(mouseButtonDownMasks[i]);
         }
         robot.delay(1000);
         this.removeMouseListener(adapterTest1);
@@ -289,12 +287,12 @@
         this.addMouseListener(adapterTest2);
         robot.delay(1000);
         robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
-        for (int i = 3; i< mouseButtons.length; i++){
+        for (int i = 3; i< mouseButtonDownMasks.length; i++){
             robot.keyPress(KeyEvent.VK_SHIFT);
-            System.out.println("testSHIFT() => " +mouseButtons[i] );
-            robot.mousePress(mouseButtons[i]);
+            System.out.println("testSHIFT() => " +mouseButtonDownMasks[i] );
+            robot.mousePress(mouseButtonDownMasks[i]);
             robot.delay(100);
-            robot.mouseRelease(mouseButtons[i]);
+            robot.mouseRelease(mouseButtonDownMasks[i]);
             robot.keyRelease(KeyEvent.VK_SHIFT);
         }
         robot.delay(1000);
@@ -305,12 +303,12 @@
         this.addMouseListener(adapterTest3);
         robot.delay(1000);
         robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
-        for (int i = 3; i< mouseButtons.length; i++){
+        for (int i = 3; i< mouseButtonDownMasks.length; i++){
             robot.keyPress(KeyEvent.VK_CONTROL);
-            System.out.println("testCTRL() => " +mouseButtons[i] );
-            robot.mousePress(mouseButtons[i]);
+            System.out.println("testCTRL() => " +mouseButtonDownMasks[i] );
+            robot.mousePress(mouseButtonDownMasks[i]);
             robot.delay(100);
-            robot.mouseRelease(mouseButtons[i]);
+            robot.mouseRelease(mouseButtonDownMasks[i]);
             robot.keyRelease(KeyEvent.VK_CONTROL);
         }
         robot.delay(1000);
@@ -321,12 +319,12 @@
         this.addMouseListener(adapterTest4);
         robot.delay(1000);
         robot.mouseMove(getLocationOnScreen().x + getWidth()/2, getLocationOnScreen().y + getHeight()/2);
-        for (int i = 3; i< mouseButtons.length; i++){
+        for (int i = 3; i< mouseButtonDownMasks.length; i++){
             robot.keyPress(KeyEvent.VK_ALT);
-            System.out.println("testALT() => " +mouseButtons[i] );
-            robot.mousePress(mouseButtons[i]);
+            System.out.println("testALT() => " +mouseButtonDownMasks[i] );
+            robot.mousePress(mouseButtonDownMasks[i]);
             robot.delay(100);
-            robot.mouseRelease(mouseButtons[i]);
+            robot.mouseRelease(mouseButtonDownMasks[i]);
             robot.keyRelease(KeyEvent.VK_ALT);
         }
         robot.delay(1000);
@@ -368,52 +366,52 @@
     }
 
     public static void initAdapters(){
-        adapterTest1 = new CheckingModifierAdapter(NONE);
-        adapterTest2 = new CheckingModifierAdapter(SHIFT);
-        adapterTest3 = new CheckingModifierAdapter(CTRL);
-        adapterTest4 = new CheckingModifierAdapter(ALT);
+        adapterTest1 = new CheckingModifierAdapterExtra(NONE);
+        adapterTest2 = new CheckingModifierAdapterExtra(SHIFT);
+        adapterTest3 = new CheckingModifierAdapterExtra(CTRL);
+        adapterTest4 = new CheckingModifierAdapterExtra(ALT);
     }
 
     public static void initVars(){
-        int [] tmp = new int [MouseInfo.getNumberOfButtons()];
-        for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
-            tmp[i] = InputEvent.getMaskForButton(i+1);
-            //            System.out.println("TEST: "+tmp[i]);
+        //Init the array of the mouse button masks. It will be used for generating mouse events.
+        mouseButtonDownMasks = new int [MouseInfo.getNumberOfButtons()];
+        for (int i = 0; i < mouseButtonDownMasks.length; i++){
+            mouseButtonDownMasks[i] = InputEvent.getMaskForButton(i+1);
+            System.out.println("MouseArray [i] == "+mouseButtonDownMasks[i]);
         }
 
-        mouseButtons = Arrays.copyOf(tmp, tmp.length);
-
-        for (int i = 0; i < mouseButtons.length; i++){
-            System.out.println("MouseArray [i] == "+mouseButtons[i]);
-        }
-
-        mouseButtonDownMasks = Arrays.copyOf(tmp, tmp.length);
-
         // So we need to get the number of extra buttons on the mouse:  "MouseInfo.getNumberOfButtons() - 3"
         // and multyply on 3 because each button will generate three events : PRESS, RELEASE and CLICK.
-        tmp = new int [(MouseInfo.getNumberOfButtons()-3)*3];
+        int [] tmp = new int [(MouseInfo.getNumberOfButtons()-3)*3];
+
+        //Fill array of expected results for the case when mouse buttons are only used (no-modifier keys)
         Arrays.fill(tmp, 0);
-
         for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){
             tmp[i] = mouseButtonDownMasks[j];
         }
         modifiersExStandard = Arrays.copyOf(tmp, tmp.length);
 
+        //Fill array of expected results for the case when mouse buttons are only used with SHIFT modifier key
         Arrays.fill(tmp, InputEvent.SHIFT_DOWN_MASK);
-        for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){
-            tmp[i] = tmp[j] | mouseButtonDownMasks[j];
+        for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){
+            System.out.println("modifiersExStandardSHIFT FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]);
+            tmp[i] = tmp[i] | mouseButtonDownMasks[j];
         }
         modifiersExStandardSHIFT = Arrays.copyOf(tmp, tmp.length);
 
+        //Fill array of expected results for the case when mouse buttons are only used with CTRL modifier key
         Arrays.fill(tmp, InputEvent.CTRL_DOWN_MASK);
-        for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){
-            tmp[i] = tmp[j] | mouseButtonDownMasks[j];
+        for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){
+            System.out.println("modifiersExStandardCTRL FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]);
+            tmp[i] = tmp[i] | mouseButtonDownMasks[j];
         }
         modifiersExStandardCTRL = Arrays.copyOf(tmp, tmp.length);
 
+        //Fill array of expected results for the case when mouse buttons are only used with ALT modifier key
         Arrays.fill(tmp, InputEvent.ALT_DOWN_MASK);
-        for (int i = 0, j = 3; i < MouseInfo.getNumberOfButtons(); i = i + 3, j++){
-            tmp[i] = tmp[j] | mouseButtonDownMasks[j];
+        for (int i = 0, j = 3; i < tmp.length; i = i + 3, j++){
+            System.out.println("modifiersExStandardALT FILLING : " + tmp[i] + " + " + mouseButtonDownMasks[j]);
+            tmp[i] = tmp[i] | mouseButtonDownMasks[j];
         }
         modifiersExStandardALT = Arrays.copyOf(tmp, tmp.length);
     }
@@ -436,9 +434,9 @@
 /* A class that invoke appropriate verification
  * routine with current modifier.
  */
-class CheckingModifierAdapter extends MouseAdapter{
+class CheckingModifierAdapterExtra extends MouseAdapter{
     int modifier;
-    public CheckingModifierAdapter(int modifier){
+    public CheckingModifierAdapterExtra(int modifier){
         this.modifier = modifier;
     }
 
--- a/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java	Wed Jul 05 17:24:21 2017 +0200
@@ -90,7 +90,7 @@
         int [] buttonMasks = new int[MouseInfo.getNumberOfButtons()]; // = InputEvent.getButtonDownMasks();
         for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
             buttonMasks[i] = InputEvent.getMaskForButton(i+1);
-            System.out.println("TEST: "+buttonMasks[i]);
+            System.out.println("TEST: buttonMasks["+ i +"] = " + buttonMasks[i]);
         }
 
         for (int i = 0; i < MouseInfo.getNumberOfButtons(); i++){
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/image/GetSamplesTest.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along 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     6735275
+ * @summary Test verifies that SampleModel.getSamples() throws an appropriate
+ *           exception if coordinates are not in bounds.
+ *
+ * @run     main GetSamplesTest
+ */
+
+import java.awt.image.BandedSampleModel;
+import java.awt.image.ComponentSampleModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.MultiPixelPackedSampleModel;
+import java.awt.image.PixelInterleavedSampleModel;
+import java.awt.image.SampleModel;
+import java.awt.image.SinglePixelPackedSampleModel;
+import java.util.Vector;
+
+public class GetSamplesTest {
+
+    public static int width = 100;
+    public static int height = 100;
+    public static int dataType = DataBuffer.TYPE_BYTE;
+    public static int numBands = 4;
+
+    public static void main(String[] args) {
+        Vector<Class<? extends SampleModel>> classes = new Vector<Class<? extends SampleModel>>();
+
+        classes.add(ComponentSampleModel.class);
+        classes.add(MultiPixelPackedSampleModel.class);
+        classes.add(SinglePixelPackedSampleModel.class);
+        classes.add(BandedSampleModel.class);
+        classes.add(PixelInterleavedSampleModel.class);
+
+        for (Class<? extends SampleModel> c : classes) {
+            doTest(c);
+        }
+    }
+    private static void doTest(Class<? extends SampleModel> c) {
+        System.out.println("Test for: " + c.getName());
+        SampleModel sm = createSampleModel(c);
+
+        DataBuffer db = sm.createDataBuffer();
+
+        int[] iArray = new int[ width * height + numBands];
+        float[] fArray = new float[ width * height + numBands];
+        double[] dArray = new double[ width * height + numBands];
+
+        boolean iOk = false;
+        boolean fOk = false;
+        boolean dOk = false;
+
+        try {
+            sm.getSamples(Integer.MAX_VALUE, 0, 1, 1, 0, iArray, db);
+        } catch (ArrayIndexOutOfBoundsException e) {
+            System.out.println(e.getMessage());
+            iOk = true;
+        }
+
+        try {
+            sm.getSamples(Integer.MAX_VALUE, 0, 1, 1, 0, fArray, db);
+        } catch (ArrayIndexOutOfBoundsException e) {
+            System.out.println(e.getMessage());
+            fOk = true;
+        }
+
+        try {
+            sm.getSamples(0, Integer.MAX_VALUE, 1, 1, 0, dArray, db);
+        } catch (ArrayIndexOutOfBoundsException e) {
+            System.out.println(e.getMessage());
+            dOk = true;
+        }
+        if (!iOk || !fOk || !dOk) {
+            throw new RuntimeException("Test for " + c.getSimpleName() +
+                    " failed: iOk=" + iOk + "; fOk=" + fOk + "; dOk=" + dOk);
+        }
+    }
+
+    private static SampleModel createSampleModel(Class<? extends SampleModel> cls) {
+        SampleModel res = null;
+
+        if (cls == ComponentSampleModel.class) {
+            res = new ComponentSampleModel(dataType, width, height, 4, width * 4, new int[] { 0, 1, 2, 3 } );
+        } else if (cls == MultiPixelPackedSampleModel.class) {
+            res = new MultiPixelPackedSampleModel(dataType, width, height, 4);
+        } else if (cls == SinglePixelPackedSampleModel.class) {
+            res = new SinglePixelPackedSampleModel(dataType, width, height,
+                    new int[]{ 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff });
+        } else if (cls == BandedSampleModel.class) {
+            res = new BandedSampleModel(dataType, width, height, numBands);
+        } else if (cls == PixelInterleavedSampleModel.class) {
+            res = new PixelInterleavedSampleModel(dataType, width, height, 4, width * 4, new int[] { 0, 1, 2, 3 });
+        } else {
+            throw new RuntimeException("Unknown class " + cls);
+        }
+        return res;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/Introspector/6976577/Test6976577.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along 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 6976577
+ * @summary Tests public methods in non-public beans
+ * @author Sergey Malenkov
+ */
+
+import test.Accessor;
+
+import java.beans.EventSetDescriptor;
+import java.beans.IndexedPropertyDescriptor;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Method;
+
+public class Test6976577 {
+
+    public static void main(String[] args) throws Exception {
+        Class<?> bt = Accessor.getBeanType();
+        Class<?> lt = Accessor.getListenerType();
+
+        // test PropertyDescriptor
+        PropertyDescriptor pd = new PropertyDescriptor("boolean", bt);
+        test(pd.getReadMethod());
+        test(pd.getWriteMethod());
+
+        // test IndexedPropertyDescriptor
+        IndexedPropertyDescriptor ipd = new IndexedPropertyDescriptor("indexed", bt);
+        test(ipd.getReadMethod());
+        test(ipd.getWriteMethod());
+        test(ipd.getIndexedReadMethod());
+        test(ipd.getIndexedWriteMethod());
+
+        // test EventSetDescriptor
+        EventSetDescriptor esd = new EventSetDescriptor(bt, "test", lt, "process");
+        test(esd.getAddListenerMethod());
+        test(esd.getRemoveListenerMethod());
+        test(esd.getGetListenerMethod());
+        test(esd.getListenerMethods());
+    }
+
+    private static void test(Method... methods) {
+        for (Method method : methods) {
+            if (method == null) {
+                throw new Error("public method is not found");
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/Introspector/6976577/test/Accessor.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,81 @@
+package test;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.EventListener;
+import java.util.TooManyListenersException;
+
+public class Accessor {
+
+    public static Class<?> getBeanType() {
+        return Bean.class;
+    }
+
+    public static Class<?> getListenerType() {
+        return TestListener.class;
+    }
+}
+
+interface TestEvent {
+}
+
+interface TestListener extends EventListener {
+    void process(TestEvent event);
+}
+
+class Bean {
+
+    private boolean b;
+    private int[] indexed;
+    private TestListener listener;
+    private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
+
+    public void addPropertyChangeListener(PropertyChangeListener listener) {
+        this.pcs.addPropertyChangeListener(listener);
+    }
+
+    public void addTestListener(TestListener listener) throws TooManyListenersException {
+        if (listener != null) {
+            if (this.listener != null) {
+                throw new TooManyListenersException();
+            }
+            this.listener = listener;
+        }
+    }
+
+    public void removeTestListener(TestListener listener) {
+        if (this.listener == listener) {
+            this.listener = null;
+        }
+    }
+
+    public TestListener[] getTestListeners() {
+        return (this.listener != null)
+                ? new TestListener[] { this.listener }
+                : new TestListener[0];
+    }
+
+    public boolean isBoolean() {
+        return this.b;
+    }
+
+    public void setBoolean(boolean b) {
+        this.b = b;
+    }
+
+    public int[] getIndexed() {
+        return this.indexed;
+    }
+
+    public void setIndexed(int[] values) {
+        this.indexed = values;
+    }
+
+    public int getIndexed(int index) {
+        return this.indexed[index];
+    }
+
+    public void setIndexed(int index, int value) {
+        this.indexed[index] = value;
+    }
+}
--- a/jdk/test/java/lang/ProcessBuilder/Basic.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/java/lang/ProcessBuilder/Basic.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1825,6 +1825,64 @@
         } catch (Throwable t) { unexpected(t); }
 
         //----------------------------------------------------------------
+        // Check that subprocesses which create subprocesses of their
+        // own do not cause parent to hang waiting for file
+        // descriptors to be closed.
+        //----------------------------------------------------------------
+        try {
+            if (Unix.is()
+                && new File("/bin/bash").exists()
+                && new File("/bin/sleep").exists()) {
+                final String[] cmd = { "/bin/bash", "-c", "(/bin/sleep 6666)" };
+                final ProcessBuilder pb = new ProcessBuilder(cmd);
+                final Process p = pb.start();
+                final InputStream stdout = p.getInputStream();
+                final InputStream stderr = p.getErrorStream();
+                final OutputStream stdin = p.getOutputStream();
+                final Thread reader = new Thread() {
+                    public void run() {
+                        try { stdout.read(); }
+                        catch (IOException e) {
+                            // e.printStackTrace();
+                            if (EnglishUnix.is() &&
+                                ! (e.getMessage().matches(".*Bad file descriptor.*")))
+                                unexpected(e);
+                        }
+                        catch (Throwable t) { unexpected(t); }}};
+                reader.setDaemon(true);
+                reader.start();
+                Thread.sleep(100);
+                p.destroy();
+                // Subprocess is now dead, but file descriptors remain open.
+                check(p.waitFor() != 0);
+                check(p.exitValue() != 0);
+                stdout.close();
+                stderr.close();
+                stdin.close();
+                //----------------------------------------------------------
+                // There remain unsolved issues with asynchronous close.
+                // Here's a highly non-portable experiment to demonstrate:
+                //----------------------------------------------------------
+                if (Boolean.getBoolean("wakeupJeff!")) {
+                    System.out.println("wakeupJeff!");
+                    // Initialize signal handler for INTERRUPT_SIGNAL.
+                    new FileInputStream("/bin/sleep").getChannel().close();
+                    // Send INTERRUPT_SIGNAL to every thread in this java.
+                    String[] wakeupJeff = {
+                        "/bin/bash", "-c",
+                        "/bin/ps --noheaders -Lfp $PPID | " +
+                        "/usr/bin/perl -nale 'print $F[3]' | " +
+                        // INTERRUPT_SIGNAL == 62 on my machine du jour.
+                        "/usr/bin/xargs kill -62"
+                    };
+                    new ProcessBuilder(wakeupJeff).start().waitFor();
+                    // If wakeupJeff worked, reader probably got EBADF.
+                    reader.join();
+                }
+            }
+        } catch (Throwable t) { unexpected(t); }
+
+        //----------------------------------------------------------------
         // Attempt to start process with insufficient permissions fails.
         //----------------------------------------------------------------
         try {
--- a/jdk/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java	Wed Jul 05 17:24:21 2017 +0200
@@ -29,7 +29,9 @@
 
 import java.nio.channels.*;
 import java.net.*;
+import static java.net.StandardSocketOption.*;
 import java.io.IOException;
+import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import java.util.concurrent.atomic.AtomicReference;
@@ -39,6 +41,7 @@
     public static void main(String[] args) throws Exception {
         testBind();
         testAccept();
+        testSocketOptions();
     }
 
     static void testBind() throws Exception {
@@ -131,4 +134,39 @@
         }
 
     }
+
+    static void testSocketOptions() throws Exception {
+        System.out.println("-- socket options --");
+        AsynchronousServerSocketChannel ch = AsynchronousServerSocketChannel.open();
+        try {
+            // check supported options
+            Set<SocketOption<?>> options = ch.supportedOptions();
+            if (!options.contains(SO_REUSEADDR))
+                throw new RuntimeException("SO_REUSEADDR should be supported");
+            if (!options.contains(SO_RCVBUF))
+                throw new RuntimeException("SO_RCVBUF should be supported");
+
+            // allowed to change when not bound
+            ch.setOption(SO_RCVBUF, 256*1024);     // can't check
+            int before = ch.getOption(SO_RCVBUF);
+            int after = ch.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
+            if (after < before)
+                 throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
+            ch.setOption(SO_REUSEADDR, true);
+            checkOption(ch, SO_REUSEADDR, true);
+            ch.setOption(SO_REUSEADDR, false);
+            checkOption(ch, SO_REUSEADDR, false);
+        } finally {
+            ch.close();
+        }
+    }
+
+    static void checkOption(AsynchronousServerSocketChannel ch,
+                            SocketOption name, Object expectedValue)
+        throws IOException
+    {
+        Object value = ch.getOption(name);
+        if (!value.equals(expectedValue))
+            throw new RuntimeException("value not as expected");
+    }
 }
--- a/jdk/test/java/nio/channels/AsynchronousSocketChannel/Basic.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/java/nio/channels/AsynchronousSocketChannel/Basic.java	Wed Jul 05 17:24:21 2017 +0200
@@ -121,8 +121,20 @@
         AsynchronousSocketChannel ch = AsynchronousSocketChannel.open()
             .setOption(SO_RCVBUF, 128*1024)
             .setOption(SO_SNDBUF, 128*1024)
-            .setOption(SO_REUSEADDR, true)
-            .bind(new InetSocketAddress(0));
+            .setOption(SO_REUSEADDR, true);
+
+        // check SO_SNDBUF/SO_RCVBUF limits
+        int before, after;
+        before = ch.getOption(SO_SNDBUF);
+        after = ch.setOption(SO_SNDBUF, Integer.MAX_VALUE).getOption(SO_SNDBUF);
+        if (after < before)
+            throw new RuntimeException("setOption caused SO_SNDBUF to decrease");
+        before = ch.getOption(SO_RCVBUF);
+        after = ch.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
+        if (after < before)
+            throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
+
+        ch.bind(new InetSocketAddress(0));
 
         // default values
         if ((Boolean)ch.getOption(SO_KEEPALIVE))
--- a/jdk/test/java/nio/channels/DatagramChannel/SocketOptionTests.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/java/nio/channels/DatagramChannel/SocketOptionTests.java	Wed Jul 05 17:24:21 2017 +0200
@@ -68,8 +68,17 @@
         checkOption(dc, SO_BROADCAST, true);
         dc.setOption(SO_BROADCAST, false);
         checkOption(dc, SO_BROADCAST, false);
-        dc.setOption(SO_SNDBUF, 16*1024);       // can't check
-        dc.setOption(SO_RCVBUF, 16*1024);       // can't check
+        dc.setOption(SO_SNDBUF, 128*1024);       // can't check
+        dc.setOption(SO_RCVBUF, 128*1024);       // can't check
+        int before, after;
+        before = dc.getOption(SO_SNDBUF);
+        after = dc.setOption(SO_SNDBUF, Integer.MAX_VALUE).getOption(SO_SNDBUF);
+        if (after < before)
+            throw new RuntimeException("setOption caused SO_SNDBUF to decrease");
+        before = dc.getOption(SO_RCVBUF);
+        after = dc.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
+        if (after < before)
+            throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
         dc.setOption(SO_REUSEADDR, true);
         checkOption(dc, SO_REUSEADDR, true);
         dc.setOption(SO_REUSEADDR, false);
--- a/jdk/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java	Wed Jul 05 17:24:21 2017 +0200
@@ -56,6 +56,10 @@
 
         // allowed to change when not bound
         ssc.setOption(SO_RCVBUF, 256*1024);     // can't check
+        int before = ssc.getOption(SO_RCVBUF);
+        int after = ssc.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
+        if (after < before)
+            throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
         ssc.setOption(SO_REUSEADDR, true);
         checkOption(ssc, SO_REUSEADDR, true);
         ssc.setOption(SO_REUSEADDR, false);
--- a/jdk/test/java/nio/channels/SocketChannel/SocketOptionTests.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/java/nio/channels/SocketChannel/SocketOptionTests.java	Wed Jul 05 17:24:21 2017 +0200
@@ -70,6 +70,15 @@
         checkOption(sc, SO_KEEPALIVE, false);
         sc.setOption(SO_SNDBUF, 128*1024);      // can't check
         sc.setOption(SO_RCVBUF, 256*1024);      // can't check
+        int before, after;
+        before = sc.getOption(SO_SNDBUF);
+        after = sc.setOption(SO_SNDBUF, Integer.MAX_VALUE).getOption(SO_SNDBUF);
+        if (after < before)
+            throw new RuntimeException("setOption caused SO_SNDBUF to decrease");
+        before = sc.getOption(SO_RCVBUF);
+        after = sc.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
+        if (after < before)
+            throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
         sc.setOption(SO_REUSEADDR, true);
         checkOption(sc, SO_REUSEADDR, true);
         sc.setOption(SO_REUSEADDR, false);
--- a/jdk/test/java/nio/file/FileStore/Basic.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/java/nio/file/FileStore/Basic.java	Wed Jul 05 17:24:21 2017 +0200
@@ -22,7 +22,7 @@
  */
 
 /* @test
- * @bug 4313887 6873621
+ * @bug 4313887 6873621 6979526
  * @summary Unit test for java.nio.file.FileStore
  * @library ..
  */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/MaxDepth.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along 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.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Unit test for Files.walkFileTree to test maxDepth parameter
+ */
+
+public class MaxDepth {
+    public static void main(String[] args) throws Exception {
+        final Path top = Paths.get(args[0]);
+
+        for (int i=0; i<5; i++) {
+            Set<FileVisitOption> opts = Collections.emptySet();
+            final int maxDepth = i;
+            Files.walkFileTree(top, opts, maxDepth, new SimpleFileVisitor<Path>() {
+                // compute depth based on relative path to top directory
+                private int depth(Path file) {
+                    Path rp = file.relativize(top);
+                    return (rp == null) ? 0 : rp.getNameCount();
+                }
+
+                @Override
+                public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+                    int d = depth(dir);
+                    if (d == maxDepth)
+                        throw new RuntimeException("Should not open directories at maxDepth");
+                    if (d > maxDepth)
+                        throw new RuntimeException("Too deep");
+                    return FileVisitResult.CONTINUE;
+                }
+
+                @Override
+                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+                    int d = depth(file);
+                    if (d > maxDepth)
+                        throw new RuntimeException("Too deep");
+                    return FileVisitResult.CONTINUE;
+                }
+            });
+        }
+    }
+}
--- a/jdk/test/java/nio/file/Files/Misc.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/java/nio/file/Files/Misc.java	Wed Jul 05 17:24:21 2017 +0200
@@ -30,6 +30,7 @@
 
 import java.nio.file.*;
 import java.nio.file.attribute.Attributes;
+import java.nio.file.attribute.BasicFileAttributes;
 import java.io.IOException;
 import java.util.*;
 
@@ -117,25 +118,25 @@
 
         SimpleFileVisitor<Path> visitor = new SimpleFileVisitor<Path>() { };
         boolean ranTheGauntlet = false;
-        try { visitor.preVisitDirectory(null);
+        BasicFileAttributes attrs = Attributes.readBasicFileAttributes(Paths.get("."));
+
+        try { visitor.preVisitDirectory(null, attrs);
         } catch (NullPointerException x0) {
-        try { visitor.preVisitDirectoryFailed(null, new IOException());
+        try { visitor.preVisitDirectory(dir, null);
         } catch (NullPointerException x1) {
-        try { visitor.preVisitDirectoryFailed(dir, null);
+        try { visitor.visitFile(null, attrs);
         } catch (NullPointerException x2) {
-        try { visitor.visitFile(null, Attributes.readBasicFileAttributes(Paths.get(".")));
+        try {  visitor.visitFile(dir, null);
         } catch (NullPointerException x3) {
-        try {  visitor.visitFile(dir, null);
+        try { visitor.visitFileFailed(null, new IOException());
         } catch (NullPointerException x4) {
-        try { visitor.visitFileFailed(null, new IOException());
+        try { visitor.visitFileFailed(dir, null);
         } catch (NullPointerException x5) {
-        try { visitor.visitFileFailed(dir, null);
+        try { visitor.postVisitDirectory(null, new IOException());
         } catch (NullPointerException x6) {
-        try { visitor.postVisitDirectory(null, new IOException());
-        } catch (NullPointerException x7) {
             // if we get here then all visit* methods threw NPE as expected
             ranTheGauntlet = true;
-        }}}}}}}}
+        }}}}}}}
         if (!ranTheGauntlet)
             throw new RuntimeException("A visit method did not throw NPE");
     }
--- a/jdk/test/java/nio/file/Files/PrintFileTree.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/java/nio/file/Files/PrintFileTree.java	Wed Jul 05 17:24:21 2017 +0200
@@ -56,29 +56,34 @@
 
         final boolean reportCycles = printCycles;
         Files.walkFileTree(dir, options, Integer.MAX_VALUE, new FileVisitor<FileRef>() {
-            public FileVisitResult preVisitDirectory(FileRef dir) {
+            @Override
+            public FileVisitResult preVisitDirectory(FileRef dir, BasicFileAttributes attrs) {
                 System.out.println(dir);
                 return FileVisitResult.CONTINUE;
             }
-            public FileVisitResult preVisitDirectoryFailed(FileRef dir, IOException exc) {
-                exc.printStackTrace();
-                return FileVisitResult.CONTINUE;
-            }
+            @Override
             public FileVisitResult visitFile(FileRef file, BasicFileAttributes attrs) {
                 if (!attrs.isDirectory() || reportCycles)
                     System.out.println(file);
                 return FileVisitResult.CONTINUE;
             }
-            public FileVisitResult postVisitDirectory(FileRef dir, IOException exc) {
-                if (exc != null) {
-                    exc.printStackTrace();
-                    return FileVisitResult.TERMINATE;
-                }
+            @Override
+            public FileVisitResult postVisitDirectory(FileRef dir, IOException exc)
+                throws IOException
+            {
+                if (exc != null)
+                    throw exc;
                 return FileVisitResult.CONTINUE;
             }
-            public FileVisitResult visitFileFailed(FileRef file, IOException exc) {
-                exc.printStackTrace();
-                return FileVisitResult.TERMINATE;
+            @Override
+            public FileVisitResult visitFileFailed(FileRef file, IOException exc)
+                throws IOException
+            {
+                if (reportCycles && (exc instanceof FileSystemLoopException)) {
+                    System.out.println(file);
+                    return FileVisitResult.CONTINUE;
+                }
+                throw exc;
             }
         });
     }
--- a/jdk/test/java/nio/file/Files/SkipSiblings.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/java/nio/file/Files/SkipSiblings.java	Wed Jul 05 17:24:21 2017 +0200
@@ -54,32 +54,28 @@
     public static void main(String[] args) throws Exception {
         Path dir = Paths.get(args[0]);
 
-        Files.walkFileTree(dir, new FileVisitor<Path>() {
-            public FileVisitResult preVisitDirectory(Path dir) {
+        Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
+            @Override
+            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
                 check(dir);
                 if (skip(dir))
                     return FileVisitResult.SKIP_SIBLINGS;
                 return FileVisitResult.CONTINUE;
             }
-            public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
-                throw new RuntimeException(exc);
-            }
-
+            @Override
             public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
                 check(file);
                 if (skip(file))
                     return FileVisitResult.SKIP_SIBLINGS;
                 return FileVisitResult.CONTINUE;
             }
+            @Override
             public FileVisitResult postVisitDirectory(Path dir, IOException x) {
                 if (x != null)
                     throw new RuntimeException(x);
                 check(dir);
                 return FileVisitResult.CONTINUE;
             }
-            public FileVisitResult visitFileFailed(Path file, IOException x) {
-                throw new RuntimeException(x);
-            }
         });
     }
 }
--- a/jdk/test/java/nio/file/Files/TerminateWalk.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/java/nio/file/Files/TerminateWalk.java	Wed Jul 05 17:24:21 2017 +0200
@@ -49,22 +49,19 @@
     public static void main(String[] args) throws Exception {
         Path dir = Paths.get(args[0]);
 
-        Files.walkFileTree(dir, new FileVisitor<Path>() {
-            public FileVisitResult preVisitDirectory(Path dir) {
+        Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
+            @Override
+            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
                 return maybeTerminate();
             }
-            public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
-                return maybeTerminate();
-            }
+            @Override
             public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
                 return maybeTerminate();
             }
+            @Override
             public FileVisitResult postVisitDirectory(Path dir, IOException x) {
                 return maybeTerminate();
             }
-            public FileVisitResult visitFileFailed(Path file, IOException x) {
-                return maybeTerminate();
-            }
         });
     }
 }
--- a/jdk/test/java/nio/file/Files/WalkWithSecurity.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/java/nio/file/Files/WalkWithSecurity.java	Wed Jul 05 17:24:21 2017 +0200
@@ -116,7 +116,7 @@
         }
 
         @Override
-        public FileVisitResult preVisitDirectory(Path dir) {
+        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
             System.out.println(dir);
             count++;
             return FileVisitResult.CONTINUE;
--- a/jdk/test/java/nio/file/Files/walk_file_tree.sh	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/java/nio/file/Files/walk_file_tree.sh	Wed Jul 05 17:24:21 2017 +0200
@@ -22,9 +22,9 @@
 #
 
 # @test
-# @bug 4313887
+# @bug 4313887 6907737
 # @summary Unit test for walkFileTree method
-# @build CreateFileTree PrintFileTree SkipSiblings TerminateWalk
+# @build CreateFileTree PrintFileTree SkipSiblings TerminateWalk MaxDepth
 # @run shell walk_file_tree.sh
 
 # if TESTJAVA isn't set then we assume an interactive run.
@@ -84,6 +84,10 @@
 $JAVA TerminateWalk "$ROOT"
 if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
 
+# test maxDepth
+$JAVA MaxDepth "$ROOT"
+if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+
 # clean-up
 rm -r "$ROOT"
 
--- a/jdk/test/java/nio/file/TestUtil.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/java/nio/file/TestUtil.java	Wed Jul 05 17:24:21 2017 +0200
@@ -44,15 +44,10 @@
         return createTemporaryDirectory(System.getProperty("java.io.tmpdir"));
     }
 
-    static void removeAll(Path dir) {
+    static void removeAll(Path dir) throws IOException {
         Files.walkFileTree(dir, new FileVisitor<Path>() {
             @Override
-            public FileVisitResult preVisitDirectory(Path dir) {
-                return FileVisitResult.CONTINUE;
-            }
-            @Override
-            public FileVisitResult preVisitDirectoryFailed(Path dir, IOException exc) {
-                System.err.format("Error occured accessing directory %s\n", dir, exc);
+            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
                 return FileVisitResult.CONTINUE;
             }
             @Override
--- a/jdk/test/java/util/Collection/BiggernYours.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/java/util/Collection/BiggernYours.java	Wed Jul 05 17:24:21 2017 +0200
@@ -174,6 +174,11 @@
                 public int size() {return randomize(super.size());}});
 
         testCollections(
+            new ConcurrentLinkedDeque(),
+            new ConcurrentLinkedDeque() {
+                public int size() {return randomize(super.size());}});
+
+        testCollections(
             new ConcurrentLinkedQueue(),
             new ConcurrentLinkedQueue() {
                 public int size() {return randomize(super.size());}});
--- a/jdk/test/java/util/Collection/IteratorAtEnd.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/java/util/Collection/IteratorAtEnd.java	Wed Jul 05 17:24:21 2017 +0200
@@ -48,6 +48,7 @@
         testCollection(new PriorityQueue());
         testCollection(new LinkedBlockingQueue());
         testCollection(new ArrayBlockingQueue(100));
+        testCollection(new ConcurrentLinkedDeque());
         testCollection(new ConcurrentLinkedQueue());
         testCollection(new LinkedTransferQueue());
 
--- a/jdk/test/java/util/Collection/MOAT.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/java/util/Collection/MOAT.java	Wed Jul 05 17:24:21 2017 +0200
@@ -75,6 +75,7 @@
         testCollection(new ArrayBlockingQueue<Integer>(20));
         testCollection(new LinkedBlockingQueue<Integer>(20));
         testCollection(new LinkedBlockingDeque<Integer>(20));
+        testCollection(new ConcurrentLinkedDeque<Integer>());
         testCollection(new ConcurrentLinkedQueue<Integer>());
         testCollection(new LinkedTransferQueue<Integer>());
         testCollection(new ConcurrentSkipListSet<Integer>());
@@ -431,8 +432,9 @@
         q.poll();
         equal(q.size(), 4);
         checkFunctionalInvariants(q);
-        if ((q instanceof LinkedBlockingQueue) ||
-            (q instanceof LinkedBlockingDeque) ||
+        if ((q instanceof LinkedBlockingQueue)   ||
+            (q instanceof LinkedBlockingDeque)   ||
+            (q instanceof ConcurrentLinkedDeque) ||
             (q instanceof ConcurrentLinkedQueue)) {
             testQueueIteratorRemove(q);
         }
--- a/jdk/test/java/util/Collections/RacingCollections.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/java/util/Collections/RacingCollections.java	Wed Jul 05 17:24:21 2017 +0200
@@ -235,6 +235,7 @@
             new ArrayList<Queue<Integer>>(newConcurrentDeques());
         list.add(new LinkedBlockingQueue<Integer>(10));
         list.add(new LinkedTransferQueue<Integer>());
+        list.add(new ConcurrentLinkedQueue<Integer>());
         return list;
     }
 
@@ -248,6 +249,7 @@
     private static List<Deque<Integer>> newConcurrentDeques() {
         List<Deque<Integer>> list = new ArrayList<Deque<Integer>>();
         list.add(new LinkedBlockingDeque<Integer>(10));
+        list.add(new ConcurrentLinkedDeque<Integer>());
         return list;
     }
 
--- a/jdk/test/java/util/Deque/ChorusLine.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/java/util/Deque/ChorusLine.java	Wed Jul 05 17:24:21 2017 +0200
@@ -129,6 +129,7 @@
         deqs.add(new ArrayDeque<Integer>());
         deqs.add(new LinkedList<Integer>());
         deqs.add(new LinkedBlockingDeque<Integer>());
+        deqs.add(new ConcurrentLinkedDeque<Integer>());
 
         equal(deqs);
 
--- a/jdk/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java	Wed Jul 05 17:24:21 2017 +0200
@@ -55,6 +55,7 @@
 
     Collection<Queue<Integer>> concurrentQueues() {
         List<Queue<Integer>> queues = new ArrayList<Queue<Integer>>();
+        queues.add(new ConcurrentLinkedDeque<Integer>());
         queues.add(new ConcurrentLinkedQueue<Integer>());
         queues.add(new ArrayBlockingQueue<Integer>(items, false));
         //queues.add(new ArrayBlockingQueue<Integer>(count, true));
@@ -105,7 +106,7 @@
         final Queue<Integer> queue;
         final CyclicBarrier barrier;
         int items;
-        Stage (Queue<Integer> q, CyclicBarrier b, int items) {
+        Stage(Queue<Integer> q, CyclicBarrier b, int items) {
             queue = q;
             barrier = b;
             this.items = items;
--- a/jdk/test/java/util/concurrent/ConcurrentQueues/GCRetention.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/java/util/concurrent/ConcurrentQueues/GCRetention.java	Wed Jul 05 17:24:21 2017 +0200
@@ -40,6 +40,7 @@
 
 import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedDeque;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.LinkedBlockingDeque;
 import java.util.concurrent.LinkedBlockingQueue;
@@ -62,6 +63,7 @@
 
     Collection<Queue<Boolean>> queues() {
         List<Queue<Boolean>> queues = new ArrayList<Queue<Boolean>>();
+        queues.add(new ConcurrentLinkedDeque<Boolean>());
         queues.add(new ConcurrentLinkedQueue<Boolean>());
         queues.add(new ArrayBlockingQueue<Boolean>(count, false));
         queues.add(new ArrayBlockingQueue<Boolean>(count, true));
--- a/jdk/test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java	Wed Jul 05 17:24:21 2017 +0200
@@ -48,6 +48,7 @@
         test(new LinkedBlockingQueue(20));
         test(new LinkedBlockingDeque());
         test(new LinkedBlockingDeque(20));
+        test(new ConcurrentLinkedDeque());
         test(new ConcurrentLinkedQueue());
         test(new LinkedTransferQueue());
         // Other concurrent queues (e.g. ArrayBlockingQueue) do not
--- a/jdk/test/java/util/concurrent/ConcurrentQueues/OfferRemoveLoops.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/java/util/concurrent/ConcurrentQueues/OfferRemoveLoops.java	Wed Jul 05 17:24:21 2017 +0200
@@ -55,6 +55,7 @@
         testQueue(new LinkedBlockingDeque());
         testQueue(new ArrayBlockingQueue(10));
         testQueue(new PriorityBlockingQueue(10));
+        testQueue(new ConcurrentLinkedDeque());
         testQueue(new ConcurrentLinkedQueue());
         testQueue(new LinkedTransferQueue());
     }
--- a/jdk/test/java/util/concurrent/ConcurrentQueues/RemovePollRace.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/java/util/concurrent/ConcurrentQueues/RemovePollRace.java	Wed Jul 05 17:24:21 2017 +0200
@@ -41,6 +41,7 @@
 
 import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedDeque;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.LinkedBlockingDeque;
@@ -62,6 +63,7 @@
 
     Collection<Queue<Boolean>> concurrentQueues() {
         List<Queue<Boolean>> queues = new ArrayList<Queue<Boolean>>();
+        queues.add(new ConcurrentLinkedDeque<Boolean>());
         queues.add(new ConcurrentLinkedQueue<Boolean>());
         queues.add(new ArrayBlockingQueue<Boolean>(count, false));
         queues.add(new ArrayBlockingQueue<Boolean>(count, true));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JComboBox/6632953/bug6632953.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along 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 6632953
+ * @summary MetalComboBoxUI.getBaseline(JComponent, int, int) throws IAE for valid width/height
+ * @author Alexander Potochkin
+ */
+
+import javax.swing.JComboBox;
+import javax.swing.plaf.metal.MetalComboBoxUI;
+
+public class bug6632953 {
+
+    public static void main(String... args) throws Exception {
+        MetalComboBoxUI ui = new MetalComboBoxUI();
+        ui.installUI(new JComboBox());
+        ui.getBaseline(new JComboBox(), 0, 0);
+        ui.getBaseline(new JComboBox(), 1, 1);
+        ui.getBaseline(new JComboBox(), 2, 2);
+        ui.getBaseline(new JComboBox(), 3, 3);
+        ui.getBaseline(new JComboBox(), 4, 4);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JScrollBar/6542335/bug6542335.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along 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 6542335
+   @summary different behavior on knob of scroll bar between 1.4.2 and 5.0
+   @author  Alexander Potochkin
+   @run main bug6542335
+*/
+
+import sun.awt.SunToolkit;
+
+import javax.swing.*;
+import javax.swing.plaf.basic.BasicScrollBarUI;
+import java.awt.*;
+import java.awt.event.InputEvent;
+
+public class bug6542335 {
+    private static JScrollBar sb;
+    private static MyScrollBarUI ui;
+
+    public static void main(String[] args) throws Exception {
+        Robot robot = new Robot();
+        robot.setAutoDelay(10);
+
+        SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            public void run() {
+                final JFrame frame = new JFrame("bug6542335");
+                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+                sb = new JScrollBar(0, 0, 1, 0, 1);
+
+                ui = new MyScrollBarUI();
+                sb.setUI(ui);
+
+                sb.setPreferredSize(new Dimension(200, 17));
+                DefaultBoundedRangeModel rangeModel = new DefaultBoundedRangeModel();
+                rangeModel.setMaximum(100);
+                rangeModel.setMinimum(0);
+                rangeModel.setExtent(50);
+                rangeModel.setValue(50);
+
+                sb.setModel(rangeModel);
+                frame.add(sb);
+
+                frame.setSize(200, 100);
+                frame.setVisible(true);
+            }
+        });
+
+        Rectangle thumbBounds = new Rectangle(ui.getThumbBounds());
+
+        toolkit.realSync();
+        Point l = sb.getLocationOnScreen();
+        robot.mouseMove(l.x + (int) (0.75 * sb.getWidth()), l.y + sb.getHeight()/2);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+        toolkit.realSync();
+
+        if (!thumbBounds.equals(ui.getThumbBounds())) {
+            throw new RuntimeException("Test failed");
+        }
+    }
+
+    static class MyScrollBarUI extends BasicScrollBarUI {
+        public Rectangle getThumbBounds() {
+            return super.getThumbBounds();
+        }
+    }
+}
--- a/jdk/test/javax/swing/JTable/Test6888156.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/javax/swing/JTable/Test6888156.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -71,14 +71,14 @@
         table = new JTable(model);
     }
 
-    public void test(final LookAndFeel laf) throws Exception {
+    public void test(final String laf) throws Exception {
         SwingUtilities.invokeAndWait(new Runnable() {
             @Override public void run() {
                 try {
+                    System.out.println(laf);
                     UIManager.setLookAndFeel(laf);
-                } catch (UnsupportedLookAndFeelException e) {
-                    System.err.println(laf.getDescription() +
-                                       " is unsupported; continuing");
+                } catch (Exception e) {
+                    System.err.println(laf + " is unsupported; continuing");
                     return;
                 }
                 SwingUtilities.updateComponentTreeUI(table);
@@ -92,8 +92,10 @@
 
     public static void main(String[] args) throws Exception {
         Test6888156 t = new Test6888156();
-        t.test(new javax.swing.plaf.nimbus.NimbusLookAndFeel());
-        t.test(new com.sun.java.swing.plaf.gtk.GTKLookAndFeel());
+        t.test("javax.swing.plaf.nimbus.NimbusLookAndFeel");
+        t.test("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
+        for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) {
+            t.test(laf.getClassName());
+        }
     }
 }
-
--- a/jdk/test/javax/swing/JTextArea/6940863/bug6940863.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/javax/swing/JTextArea/6940863/bug6940863.java	Wed Jul 05 17:24:21 2017 +0200
@@ -56,6 +56,7 @@
     public static void main(String[] args) throws Exception {
         if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) {
             System.out.println("The test is suitable only for Windows OS. Skipped");
+            return;
         }
 
         UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
--- a/jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedCharEncoding.sh	Wed Jul 05 17:23:40 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-#
-# Copyright (c) 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.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along 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 6502503
- # @run shell/timeout=140 ChunkedCharEncoding.sh
- # @summary Http URL connection don't work when default encoding is Cp037: HTTP Transfer-Encoding:chunked
-
-OS=`uname -s`
-case "$OS" in
-  SunOS | Linux )
-    PS=":"
-    FS="/"
-    ;;
-  CYGWIN* )
-    PS=";"
-    FS="/"
-    ;;
-  Windows* )
-    PS=";"
-    FS="\\"
-    ;;
-  * )
-    echo "Unrecognized system!"
-    exit 1;
-    ;;
-esac
-
-# compile
-${TESTJAVA}${FS}bin${FS}javac -d . ${TESTSRC}${FS}TestAvailable.java
-
-# run with CP037 encoding specified. 
-${TESTJAVA}${FS}bin${FS}java -Dfile.encoding=Cp037 TestAvailable 2>&1 
-
-result=$?
-if [ "$result" -ne "0" ]; then
-    exit 1
-fi
-
-# no failures, exit.
-exit 0
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/www/http/HttpClient/StreamingRetry.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along 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 6672144
+ * @summary HttpURLConnection.getInputStream sends POST request after failed chunked send
+ */
+
+import java.net.HttpURLConnection;
+import java.net.ServerSocket;
+import java.net.URL;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public class StreamingRetry implements Runnable {
+    static final int ACCEPT_TIMEOUT = 20 * 1000; // 20 seconds
+    ServerSocket ss;
+
+    public static void main(String[] args) throws IOException {
+        (new StreamingRetry()).instanceMain();
+    }
+
+    void instanceMain() throws IOException {
+        test();
+        if (failed > 0) throw new RuntimeException("Some tests failed");
+    }
+
+    void test() throws IOException {
+        ss = new ServerSocket(0);
+        ss.setSoTimeout(ACCEPT_TIMEOUT);
+        int port = ss.getLocalPort();
+
+        (new Thread(this)).start();
+
+        try {
+            URL url = new URL("http://localhost:" + port + "/");
+            HttpURLConnection uc = (HttpURLConnection) url.openConnection();
+            uc.setDoOutput(true);
+            uc.setChunkedStreamingMode(4096);
+            OutputStream os = uc.getOutputStream();
+            os.write("Hello there".getBytes());
+
+            InputStream is = uc.getInputStream();
+            is.close();
+        } catch (IOException expected) {
+            //expected.printStackTrace();
+        } finally {
+            ss.close();
+        }
+    }
+
+    // Server
+    public void run() {
+        try {
+            (ss.accept()).close();
+            (ss.accept()).close();
+            ss.close();
+            fail("The server shouldn't accept a second connection");
+         } catch (IOException e) {
+            //OK, the clien will close the server socket if successfull
+        }
+    }
+
+    volatile int failed = 0;
+    void fail() {failed++; Thread.dumpStack();}
+    void fail(String msg) {System.err.println(msg); fail();}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/www/protocol/http/6550798/TestCache.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along 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.net.*;
+import java.io.*;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.PrintStream;
+import java.io.InputStream;
+import java.io.File;
+import java.net.CacheRequest;
+import java.net.CacheResponse;
+import java.net.ResponseCache;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.List;
+import java.util.Iterator;
+import java.util.StringTokenizer;
+import java.util.jar.JarInputStream;
+import java.util.jar.JarFile;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
+import java.security.PrivilegedActionException;
+import java.security.Principal;
+import java.security.cert.Certificate;
+import javax.net.ssl.SSLPeerUnverifiedException;
+
+public class TestCache extends java.net.ResponseCache {
+    private boolean inCacheHandler = false;
+    private boolean _downloading = false;
+
+    public static volatile boolean fail = false;
+
+    public static void reset() {
+        // Set system wide cache handler
+        System.out.println("install deploy cache handler");
+        ResponseCache.setDefault(new TestCache());
+    }
+
+    public synchronized CacheResponse get(final URI uri, String rqstMethod,
+            Map requestHeaders) throws IOException {
+        System.out.println("get: " + uri);
+        Thread.currentThread().dumpStack();
+        return null;
+    }
+
+    public synchronized CacheRequest put(URI uri, URLConnection conn)
+    throws IOException {
+        System.out.println("put: " + uri);
+        Thread.currentThread().dumpStack();
+        URL url = uri.toURL();
+        return new DeployCacheRequest(url, conn);
+
+    }
+}
+
+class DeployByteArrayOutputStream extends java.io.ByteArrayOutputStream {
+
+    private URL _url;
+    private URLConnection _conn;
+
+    DeployByteArrayOutputStream(URL url, URLConnection conn) {
+        _url = url;
+        _conn = conn;
+    }
+
+
+    public void close() throws IOException {
+
+        System.out.println("contentLength: " + _conn.getContentLength());
+        System.out.println("byte array size: " + size());
+        if ( _conn.getContentLength() == size()) {
+            System.out.println("correct content length");
+        } else {
+            System.out.println("wrong content length");
+            System.out.println("TEST FAILED");
+            TestCache.fail = true;
+        }
+        super.close();
+    }
+}
+
+class DeployCacheRequest extends java.net.CacheRequest {
+
+    private URL _url;
+    private URLConnection _conn;
+    private boolean _downloading = false;
+
+    DeployCacheRequest(URL url, URLConnection conn) {
+        System.out.println("DeployCacheRequest ctor for: " + url);
+        _url = url;
+        _conn = conn;
+    }
+
+    public void abort() {
+        System.out.println("abort called");
+    }
+
+    public OutputStream getBody() throws IOException {
+        System.out.println("getBody called");
+        return new DeployByteArrayOutputStream(_url, _conn);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/www/protocol/http/6550798/test.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along 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 6550798
+ * @summary Using InputStream.skip with ResponseCache will cause partial data to be cached
+ * @run main/othervm test
+ */
+
+import java.net.*;
+import com.sun.net.httpserver.*;
+import java.io.*;
+
+public class test {
+
+    final static int LEN = 16 * 1024;
+
+    public static void main(String[] args)  throws Exception {
+
+        TestCache.reset();
+        HttpServer s = HttpServer.create (new InetSocketAddress(0), 10);
+        s.createContext ("/", new HttpHandler () {
+            public void handle (HttpExchange e) {
+                try {
+                    byte[] buf = new byte [LEN];
+                    OutputStream o = e.getResponseBody();
+                    e.sendResponseHeaders(200, LEN);
+                    o.write (buf);
+                    e.close();
+                } catch (IOException ex) {
+                    ex.printStackTrace();
+                    TestCache.fail = true;
+                }
+            }
+        });
+        s.start();
+
+        System.out.println("http request with cache hander");
+        URL u = new URL("http://127.0.0.1:"+s.getAddress().getPort()+"/f");
+        URLConnection conn = u.openConnection();
+
+        InputStream is = null;
+        try {
+            // this calls into TestCache.get
+            byte[] buf = new byte[8192];
+            is = new BufferedInputStream(conn.getInputStream());
+
+            is.skip(1000);
+
+            while (is.read(buf) != -1) {
+            }
+        } finally {
+            if (is != null) {
+                // this calls into TestCache.put
+                // TestCache.put will check if the resource
+                // should be cached
+                is.close();
+            }
+            s.stop(0);
+        }
+
+        if (TestCache.fail) {
+            System.out.println ("TEST FAILED");
+            throw new RuntimeException ();
+        } else {
+            System.out.println ("TEST OK");
+        }
+    }
+}
--- a/jdk/test/sun/security/tools/jarsigner/crl.sh	Wed Jul 05 17:23:40 2017 +0200
+++ b/jdk/test/sun/security/tools/jarsigner/crl.sh	Wed Jul 05 17:24:21 2017 +0200
@@ -63,7 +63,15 @@
 $KT -alias b -dname CN=b -keyalg rsa -genkey -validity 300
 $KT -alias b -gencrl -id 5:1 -id 6:2 -file crl3
 
-$TESTJAVA${FS}bin${FS}jrunscript -e 'println(new File("crl1").toURI())' > uri
+cat > ToURI.java <<EOF
+class ToURI {
+    public static void main(String[] args) throws Exception {
+        System.out.println(new java.io.File("crl1").toURI());
+    }
+}
+EOF
+$TESTJAVA${FS}bin${FS}javac ToURI.java
+$TESTJAVA${FS}bin${FS}java ToURI > uri
 $KT -alias c -dname CN=c -keyalg rsa -genkey -validity 300 \
     -ext crl=uri:`cat uri`
 
--- a/langtools/.hgtags	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/.hgtags	Wed Jul 05 17:24:21 2017 +0200
@@ -87,3 +87,4 @@
 32da0f38d2fe96c558492b8707b40da24643d41e jdk7-b110
 8bec624274ef8535720cff553374347c2f4f5fb2 jdk7-b111
 fd2579b80b83bf5d4289426016c7d29174ba5dd9 jdk7-b112
+6dbd2d869b0573fa5b799a23cccff47d20c12696 jdk7-b113
--- a/langtools/make/netbeans/langtools/build.xml	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/make/netbeans/langtools/build.xml	Wed Jul 05 17:24:21 2017 +0200
@@ -31,44 +31,44 @@
 -->
 
 <project name="langtools-netbeans" default="build" basedir="../../..">
-    
-    <property name="langtools.properties" 
+
+    <property name="langtools.properties"
         location="make/netbeans/langtools/nbproject/private/langtools.properties"/>
-    
-    <!-- 
+
+    <!--
         Instead of importing the main build file, we could call it when needed.
         That would reduce the list of Ant targets that get displayed for this
-        file, but it also complicates the interface between the project build 
+        file, but it also complicates the interface between the project build
         file and the main build file. For example, some imported targets
         would have to be reclared, properties would have to be restructured,
-        and it would be harder to run results (e.g. in properties) from nested 
+        and it would be harder to run results (e.g. in properties) from nested
         targets.
      -->
-    <import file="../../build.xml"/> 
-    
+    <import file="../../build.xml"/>
+
     <!-- Build project. (action: build; F11)
         If langtools.tool.name is set, then just build that tool; otherwise
         build all tools.
     -->
-    
-    <target name="build" depends="-get-tool-if-set,-build-tool,-build-all" 
+
+    <target name="build" depends="-get-tool-if-set,-build-tool,-build-all"
         description="Build one or all langtools tools"
         />
-        
+
     <target name="-build-tool" if="langtools.tool.name">
         <echo level="info" message="Building ${langtools.tool.name}"/>
         <echo level="verbose" message="(Unset langtools.tool.name to build all tools)"/>
         <antcall target="build-${langtools.tool.name}"/>
     </target>
-    
+
     <target name="-build-all" unless="langtools.tool.name">
         <echo level="info" message="Building all tools"/>
         <echo level="verbose" message="(Set langtools.tool.name to build a single tool)"/>
         <antcall target="build-all-tools"/>
     </target>
-    
+
     <!-- Compile a single file. (action: compile.single; F9) -->
-    
+
     <target name="compile-single" depends="build-bootstrap-javac">
         <fail unless="includes">Must set property 'includes'</fail>
         <javac fork="true" executable="${build.bootstrap.dir}/bin/javac"
@@ -78,38 +78,38 @@
                sourcepath=""
                includeAntRuntime="no"
                target="${javac.target}"
-               debug="${javac.debug}" 
+               debug="${javac.debug}"
                debuglevel="${javac.debuglevel}"/>
     </target>
-    
-    <!-- Run tool. (action: run; F6) 
+
+    <!-- Run tool. (action: run; F6)
         Use langtools.tool.name and langtools.tool.args properties if set; otherwise prompt
         the user.
     -->
-    
-    <target name="run" depends="-check-target.java.home,build,-def-run,-get-tool-and-args" 
+
+    <target name="run" depends="-check-target.java.home,build,-def-run,-get-tool-and-args"
             description="run tool">
         <echo level="info" message="Run ${langtools.tool.name} with args ${langtools.tool.args}"/>
         <run mainclass="com.sun.tools.${langtools.tool.name}.Main" args="${langtools.tool.args}"/>
     </target>
-    
+
     <!-- Run a selected class. (action: run.single;  shift-F6) -->
-    
+
     <target name="run-single" depends="-check-target.java.home,-def-run">
         <fail unless="run.classname">Must set property 'run.classname' </fail>
         <echo level="info" message="run ${run.classname}"/>
         <run mainclass="${run.classname}" args=""/>
     </target>
-    
+
     <!-- Test project, and display results if tests failed. (action: test; Alt-F6)
         If langtools.tool.name is set, then just test that tool; otherwise
         test all tools.
     -->
-    
-    <target name="jtreg" depends="-get-tool-if-set,-jtreg-tool,-jtreg-all" 
+
+    <target name="jtreg" depends="-get-tool-if-set,-jtreg-tool,-jtreg-all"
         description="Test one or all langtools tools"
         />
-    
+
     <target name="-jtreg-tool" if="langtools.tool.name">
         <echo level="info" message="Testing ${langtools.tool.name}"/>
         <echo level="verbose" message="(Unset langtools.tool.name to test all tools)"/>
@@ -118,7 +118,7 @@
             <target name="-show-jtreg"/>
         </antcall>
     </target>
-    
+
     <target name="-jtreg-all" unless="langtools.tool.name">
         <echo level="info" message="Testing all tools"/>
         <echo level="verbose" message="(Set langtools.tool.name to test a single tool)"/>
@@ -127,36 +127,36 @@
             <target name="-show-jtreg"/>
         </antcall>
     </target>
-    
+
     <target name="-show-jtreg" if="netbeans.home" unless="jtreg.passed">
         <nbbrowse file="${jtreg.report}/report.html"/>
         <fail>Some tests failed; see report for details.</fail>
     </target>
-    
+
     <!-- Debug tool in NetBeans. -->
-    
+
     <target name="debug" depends="-check-target.java.home,-def-run,-def-start-debugger,-get-tool-and-args,build" if="netbeans.home">
         <echo level="info" message="Debug ${langtools.tool.name} with args ${langtools.tool.args}"/>
         <start-debugger/>
         <run mainclass="com.sun.tools.${langtools.tool.name}.Main" args="${langtools.tool.args}" jpda.jvmargs="${jpda.jvmargs}"/>
     </target>
-    
+
     <!-- Debug a selected class . -->
     <target name="debug-single" depends="-check-target.java.home,-def-start-debugger,-def-run">
         <fail unless="debug.classname">Must set property 'debug.classname'</fail>
         <start-debugger/>
         <run mainclass="${debug.classname}" default.args="" jpda.jvmargs="${jpda.jvmargs}"/>
     </target>
-    
+
     <!-- Debug a jtreg test. -->
     <target name="debug-jtreg" depends="-check-target.java.home,-def-start-debugger,-def-jtreg">
         <fail unless="jtreg.tests">Must set property 'jtreg.tests'</fail>
         <start-debugger/>
         <jtreg-tool name="debug" samevm="false" tests="${jtreg.tests}" jpda.jvmargs="${jpda.jvmargs}"/>
     </target>
-    
+
     <!-- Update a class being debugged. -->
-    
+
     <target name="debug-fix" if="langtools.tool.name">
         <fail unless="class">Must set property 'class'
         </fail>
@@ -169,16 +169,16 @@
             </fileset>
         </nbjpdareload>
     </target>
-    
+
     <!-- Generate javadoc for one or all tools. (action: javadoc; Alt-F6)
         If langtools.tool.name is set, then just test that tool; otherwise
         test all tools.
     -->
-    
-    <target name="javadoc" depends="-javadoc-tool,-javadoc-all" 
+
+    <target name="javadoc" depends="-javadoc-tool,-javadoc-all"
         description="Generate javadoc for one or all langtools tools"
         />
-        
+
     <target name="-javadoc-tool" if="langtools.tool.name">
         <echo level="info" message="Generate javadoc for ${langtools.tool.name}"/>
         <echo level="verbose" message="(Unset langtools.tool.name to generate javadoc for all tools)"/>
@@ -187,7 +187,7 @@
             <target name="-show-javadoc"/>
         </antcall>
     </target>
-    
+
     <target name="-javadoc-all" unless="langtools.tool.name">
         <echo level="info" message="Generate javadoc for all tools"/>
         <echo level="verbose" message="(Set langtools.tool.name to generate javadoc for a single tool)"/>
@@ -196,26 +196,26 @@
             <target name="-show-javadoc"/>
         </antcall>
     </target>
-    
+
     <target name="-show-javadoc" if="netbeans.home">
         <!-- what if doing javadoc for all? -->
         <nbbrowse file="${build.javadoc.dir}/${langtools.tool.name}/index.html"/>
     </target>
-    
+
     <!-- Prompt for values. -->
-    
+
     <target name="-get-tool-if-set" depends="-def-select-tool">
-        <select-tool 
-            toolproperty="langtools.tool.name" 
+        <select-tool
+            toolproperty="langtools.tool.name"
             propertyfile="${langtools.properties}"
             askIfUnset="false"
             />
     </target>
-    
+
     <target name="-get-tool-and-args" depends="-def-select-tool">
-        <select-tool 
-            toolproperty="langtools.tool.name" 
-            argsproperty="langtools.tool.args" 
+        <select-tool
+            toolproperty="langtools.tool.name"
+            argsproperty="langtools.tool.args"
             propertyfile="${langtools.properties}"
             askIfUnset="true"
             />
@@ -236,7 +236,7 @@
             </sequential>
         </macrodef>
     </target>
-    
+
     <!-- Macro to start the debugger and set a property containg the args needed by the run task -->
     <target name="-def-start-debugger" if="netbeans.home">
         <macrodef name="start-debugger">
@@ -251,28 +251,29 @@
                         <pathelement location="${src.classes.dir}"/>
                     </sourcepath>
                 </nbjpdastart>
-                <property 
-                    name="@{jpda.jvmargs.property}" 
+                <property
+                    name="@{jpda.jvmargs.property}"
                     value="-Xdebug -Xnoagent -Djava.compiler=none -Xrunjdwp:transport=dt_socket,address=${jpda.address}"
                 />
             </sequential>
         </macrodef>
     </target>
-    
+
     <target name="-def-select-tool">
         <mkdir dir="${build.toolclasses.dir}"/>
         <javac srcdir="${make.tools.dir}/SelectTool"
                destdir="${build.toolclasses.dir}/"
-               classpath="${ant.home}/lib/ant.jar"
-               debug="${javac.debug}" 
+               classpath="${ant.core.lib}"
+               includeantruntime="false"
+               debug="${javac.debug}"
                debuglevel="${javac.debuglevel}">
                    <compilerarg line="-Xlint"/>
         </javac>
         <taskdef name="select-tool"
-                 classname="SelectToolTask" 
+                 classname="SelectToolTask"
                  classpath="${build.toolclasses.dir}/"/>
     </target>
-        
+
     <target name="select-tool" depends="-def-select-tool">
         <select-tool propertyfile="${langtools.properties}"/>
     </target>
--- a/langtools/src/share/classes/com/sun/tools/apt/main/JavaCompiler.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/apt/main/JavaCompiler.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -99,9 +99,6 @@
     private static Context preRegister(Context context) {
         Bark.preRegister(context);
 
-        // force the use of the scanner that captures Javadoc comments
-        DocCommentScanner.Factory.preRegister(context);
-
         if (context.get(JavaFileManager.class) == null)
             JavacFileManager.preRegister(context);
 
--- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -96,9 +96,6 @@
         args.getClass();
         context.getClass();
         fileObjects.getClass();
-
-        // force the use of the scanner that captures Javadoc comments
-        com.sun.tools.javac.parser.DocCommentScanner.Factory.preRegister(context);
     }
 
     JavacTaskImpl(JavacTool tool,
@@ -337,9 +334,13 @@
 
             ListBuffer<TypeElement> elements = new ListBuffer<TypeElement>();
             for (JCCompilationUnit unit : units) {
-                for (JCTree node : unit.defs)
-                    if (node.getTag() == JCTree.CLASSDEF)
-                        elements.append(((JCTree.JCClassDecl) node).sym);
+                for (JCTree node : unit.defs) {
+                    if (node.getTag() == JCTree.CLASSDEF) {
+                        JCClassDecl cdef = (JCClassDecl) node;
+                        if (cdef.sym != null) // maybe null if errors in anno processing
+                            elements.append(cdef.sym);
+                    }
+                }
             }
             return elements.toList();
         }
--- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -56,7 +56,6 @@
 import com.sun.tools.javac.comp.MemberEnter;
 import com.sun.tools.javac.comp.Resolve;
 import com.sun.tools.javac.model.JavacElements;
-import com.sun.tools.javac.processing.JavacMessager;
 import com.sun.tools.javac.processing.JavacProcessingEnvironment;
 import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.tree.JCTree;
@@ -81,14 +80,15 @@
  */
 public class JavacTrees extends Trees {
 
-    private final Resolve resolve;
-    private final Enter enter;
-    private final Log log;
-    private final MemberEnter memberEnter;
-    private final Attr attr;
-    private final TreeMaker treeMaker;
-    private final JavacElements elements;
-    private final JavacTaskImpl javacTaskImpl;
+    // in a world of a single context per compilation, these would all be final
+    private Resolve resolve;
+    private Enter enter;
+    private Log log;
+    private MemberEnter memberEnter;
+    private Attr attr;
+    private TreeMaker treeMaker;
+    private JavacElements elements;
+    private JavacTaskImpl javacTaskImpl;
 
     public static JavacTrees instance(JavaCompiler.CompilationTask task) {
         if (!(task instanceof JavacTaskImpl))
@@ -111,6 +111,14 @@
 
     private JavacTrees(Context context) {
         context.put(JavacTrees.class, this);
+        init(context);
+    }
+
+    public void updateContext(Context context) {
+        init(context);
+    }
+
+    private void init(Context context) {
         attr = Attr.instance(context);
         enter = Enter.instance(context);
         elements = JavacElements.instance(context);
@@ -337,6 +345,7 @@
             super(M);
         }
 
+        @Override
         public <T extends JCTree> T copy(T t, JCTree leaf) {
             T t2 = super.copy(t, leaf);
             if (t == leaf)
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Scope.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Scope.java	Wed Jul 05 17:24:21 2017 +0200
@@ -70,6 +70,45 @@
      */
     public int nelems = 0;
 
+    /** A timestamp - useful to quickly check whether a scope has changed or not
+     */
+    public ScopeCounter scopeCounter;
+
+    static ScopeCounter dummyCounter = new ScopeCounter() {
+        @Override
+        public void inc() {
+            //do nothing
+        }
+    };
+
+    public static class ScopeCounter {
+        protected static final Context.Key<ScopeCounter> scopeCounterKey =
+            new Context.Key<ScopeCounter>();
+
+        public static ScopeCounter instance(Context context) {
+            ScopeCounter instance = context.get(scopeCounterKey);
+            if (instance == null)
+                instance = new ScopeCounter(context);
+            return instance;
+        }
+
+        protected ScopeCounter(Context context) {
+            context.put(scopeCounterKey, this);
+        }
+
+        private ScopeCounter() {};
+
+        private long val = 0;
+
+        public void inc() {
+            val++;
+        }
+
+        public long val() {
+            return val;
+        }
+    }
+
     /** Every hash bucket is a list of Entry's which ends in sentinel.
      */
     private static final Entry sentinel = new Entry(null, null, null, null);
@@ -80,12 +119,12 @@
 
     /** A value for the empty scope.
      */
-    public static final Scope emptyScope = new Scope(null, null, new Entry[]{});
+    public static final Scope emptyScope = new Scope(null, null, new Entry[]{}, dummyCounter);
 
     /** Construct a new scope, within scope next, with given owner, using
      *  given table. The table's length must be an exponent of 2.
      */
-    Scope(Scope next, Symbol owner, Entry[] table) {
+    private Scope(Scope next, Symbol owner, Entry[] table, ScopeCounter scopeCounter) {
         this.next = next;
         assert emptyScope == null || owner != null;
         this.owner = owner;
@@ -94,13 +133,18 @@
         this.elems = null;
         this.nelems = 0;
         this.shared = 0;
+        this.scopeCounter = scopeCounter;
     }
 
     /** Construct a new scope, within scope next, with given owner,
      *  using a fresh table of length INITIAL_SIZE.
      */
     public Scope(Symbol owner) {
-        this(null, owner, new Entry[INITIAL_SIZE]);
+        this(owner, dummyCounter);
+    }
+
+    protected Scope(Symbol owner, ScopeCounter scopeCounter) {
+        this(null, owner, new Entry[INITIAL_SIZE], scopeCounter);
         for (int i = 0; i < INITIAL_SIZE; i++) table[i] = sentinel;
     }
 
@@ -110,7 +154,7 @@
      *  of fresh tables.
      */
     public Scope dup() {
-        Scope result = new Scope(this, this.owner, this.table);
+        Scope result = new Scope(this, this.owner, this.table, scopeCounter);
         shared++;
         // System.out.println("====> duping scope " + this.hashCode() + " owned by " + this.owner + " to " + result.hashCode());
         // new Error().printStackTrace(System.out);
@@ -123,7 +167,7 @@
      *  of fresh tables.
      */
     public Scope dup(Symbol newOwner) {
-        Scope result = new Scope(this, newOwner, this.table);
+        Scope result = new Scope(this, newOwner, this.table, scopeCounter);
         shared++;
         // System.out.println("====> duping scope " + this.hashCode() + " owned by " + newOwner + " to " + result.hashCode());
         // new Error().printStackTrace(System.out);
@@ -135,7 +179,7 @@
      *  the table of its outer scope.
      */
     public Scope dupUnshared() {
-        return new Scope(this, this.owner, this.table.clone());
+        return new Scope(this, this.owner, this.table.clone(), scopeCounter);
     }
 
     /** Remove all entries of this scope from its table, if shared
@@ -211,6 +255,7 @@
         table[hash] = e;
         elems = e;
         nelems++;
+        scopeCounter.inc();
     }
 
     Entry makeEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope, Scope origin) {
@@ -226,6 +271,8 @@
         while (e.scope == this && e.sym != sym) e = e.next();
         if (e.scope == null) return;
 
+        scopeCounter.inc();
+
         // remove e from table and shadowed list;
         Entry te = table[sym.name.hashCode() & hashMask];
         if (te == e)
@@ -472,7 +519,7 @@
         public static final Entry[] emptyTable = new Entry[0];
 
         public DelegatedScope(Scope outer) {
-            super(outer, outer.owner, emptyTable);
+            super(outer, outer.owner, emptyTable, outer.scopeCounter);
             delegatee = outer;
         }
         public Scope dup() {
@@ -498,10 +545,22 @@
         }
     }
 
+    /** A class scope, for which a scope counter should be provided */
+    public static class ClassScope extends Scope {
+
+        ClassScope(Scope next, Symbol owner, Entry[] table, ScopeCounter scopeCounter) {
+            super(next, owner, table, scopeCounter);
+        }
+
+        public ClassScope(Symbol owner, ScopeCounter scopeCounter) {
+            super(owner, scopeCounter);
+        }
+    }
+
     /** An error scope, for which the owner should be an error symbol. */
     public static class ErrorScope extends Scope {
         ErrorScope(Scope next, Symbol errSymbol, Entry[] table) {
-            super(next, /*owner=*/errSymbol, table);
+            super(next, /*owner=*/errSymbol, table, dummyCounter);
         }
         public ErrorScope(Symbol errSymbol) {
             super(errSymbol);
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java	Wed Jul 05 17:24:21 2017 +0200
@@ -25,11 +25,14 @@
 
 package com.sun.tools.javac.code;
 
+import java.util.*;
+import javax.lang.model.SourceVersion;
+import static javax.lang.model.SourceVersion.*;
+
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.jvm.Target;
-import javax.lang.model.SourceVersion;
-import static javax.lang.model.SourceVersion.*;
-import java.util.*;
+
+import static com.sun.tools.javac.main.OptionName.*;
 
 /** The source language version accepted.
  *
@@ -71,7 +74,7 @@
         Source instance = context.get(sourceKey);
         if (instance == null) {
             Options options = Options.instance(context);
-            String sourceString = options.get("-source");
+            String sourceString = options.get(SOURCE);
             if (sourceString != null) instance = lookup(sourceString);
             if (instance == null) instance = DEFAULT;
             context.put(sourceKey, instance);
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -960,6 +960,8 @@
                 return ElementKind.ENUM_CONSTANT;
             } else if (owner.kind == TYP || owner.kind == ERR) {
                 return ElementKind.FIELD;
+            } else if (isResourceVariable()) {
+                return ElementKind.RESOURCE_VARIABLE;
             } else {
                 return ElementKind.LOCAL_VARIABLE;
             }
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java	Wed Jul 05 17:24:21 2017 +0200
@@ -74,6 +74,7 @@
     public final JCNoType voidType = new JCNoType(TypeTags.VOID);
 
     private final Names names;
+    private final Scope.ScopeCounter scopeCounter;
     private final ClassReader reader;
     private final Target target;
 
@@ -340,6 +341,7 @@
         context.put(symtabKey, this);
 
         names = Names.instance(context);
+        scopeCounter = Scope.ScopeCounter.instance(context);
         target = Target.instance(context);
 
         // Create the unknown type
@@ -386,7 +388,7 @@
 
         // Create class to hold all predefined constants and operations.
         predefClass = new ClassSymbol(PUBLIC|ACYCLIC, names.empty, rootPackage);
-        Scope scope = new Scope(predefClass);
+        Scope scope = new Scope.ClassScope(predefClass, scopeCounter);
         predefClass.members_field = scope;
 
         // Enter symbols for basic types.
@@ -476,7 +478,7 @@
         proprietarySymbol.completer = null;
         proprietarySymbol.flags_field = PUBLIC|ACYCLIC|ANNOTATION|INTERFACE;
         proprietarySymbol.erasure_field = proprietaryType;
-        proprietarySymbol.members_field = new Scope(proprietarySymbol);
+        proprietarySymbol.members_field = new Scope.ClassScope(proprietarySymbol, scopeCounter);
         proprietaryType.typarams_field = List.nil();
         proprietaryType.allparams_field = List.nil();
         proprietaryType.supertype_field = annotationType;
@@ -488,7 +490,7 @@
         ClassType arrayClassType = (ClassType)arrayClass.type;
         arrayClassType.supertype_field = objectType;
         arrayClassType.interfaces_field = List.of(cloneableType, serializableType);
-        arrayClass.members_field = new Scope(arrayClass);
+        arrayClass.members_field = new Scope.ClassScope(arrayClass, scopeCounter);
         lengthVar = new VarSymbol(
             PUBLIC | FINAL,
             names.length,
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Wed Jul 05 17:24:21 2017 +0200
@@ -69,6 +69,7 @@
         new Context.Key<Types>();
 
     final Symtab syms;
+    final Scope.ScopeCounter scopeCounter;
     final JavacMessages messages;
     final Names names;
     final boolean allowBoxing;
@@ -89,6 +90,7 @@
     protected Types(Context context) {
         context.put(typesKey, this);
         syms = Symtab.instance(context);
+        scopeCounter = Scope.ScopeCounter.instance(context);
         names = Names.instance(context);
         allowBoxing = Source.instance(context).allowBoxing();
         reader = ClassReader.instance(context);
@@ -1984,22 +1986,26 @@
             final MethodSymbol cachedImpl;
             final Filter<Symbol> implFilter;
             final boolean checkResult;
+            final Scope.ScopeCounter scopeCounter;
 
             public Entry(MethodSymbol cachedImpl,
                     Filter<Symbol> scopeFilter,
-                    boolean checkResult) {
+                    boolean checkResult,
+                    Scope.ScopeCounter scopeCounter) {
                 this.cachedImpl = cachedImpl;
                 this.implFilter = scopeFilter;
                 this.checkResult = checkResult;
+                this.scopeCounter = scopeCounter;
             }
 
-            boolean matches(Filter<Symbol> scopeFilter, boolean checkResult) {
+            boolean matches(Filter<Symbol> scopeFilter, boolean checkResult, Scope.ScopeCounter scopeCounter) {
                 return this.implFilter == scopeFilter &&
-                        this.checkResult == checkResult;
+                        this.checkResult == checkResult &&
+                        this.scopeCounter.val() >= scopeCounter.val();
             }
         }
 
-        MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
+        MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter, Scope.ScopeCounter scopeCounter) {
             SoftReference<Map<TypeSymbol, Entry>> ref_cache = _map.get(ms);
             Map<TypeSymbol, Entry> cache = ref_cache != null ? ref_cache.get() : null;
             if (cache == null) {
@@ -2008,9 +2014,9 @@
             }
             Entry e = cache.get(origin);
             if (e == null ||
-                    !e.matches(implFilter, checkResult)) {
+                    !e.matches(implFilter, checkResult, scopeCounter)) {
                 MethodSymbol impl = implementationInternal(ms, origin, Types.this, checkResult, implFilter);
-                cache.put(origin, new Entry(impl, implFilter, checkResult));
+                cache.put(origin, new Entry(impl, implFilter, checkResult, scopeCounter));
                 return impl;
             }
             else {
@@ -2038,7 +2044,7 @@
     private ImplementationCache implCache = new ImplementationCache();
 
     public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, Types types, boolean checkResult, Filter<Symbol> implFilter) {
-        return implCache.get(ms, origin, checkResult, implFilter);
+        return implCache.get(ms, origin, checkResult, implFilter, scopeCounter);
     }
     // </editor-fold>
 
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Wed Jul 05 17:24:21 2017 +0200
@@ -119,10 +119,10 @@
         allowAnonOuterThis = source.allowAnonOuterThis();
         allowStringsInSwitch = source.allowStringsInSwitch();
         sourceName = source.name;
-        relax = (options.get("-retrofit") != null ||
-                 options.get("-relax") != null);
-        useBeforeDeclarationWarning = options.get("useBeforeDeclarationWarning") != null;
-        enableSunApiLintControl = options.get("enableSunApiLintControl") != null;
+        relax = (options.isSet("-retrofit") ||
+                 options.isSet("-relax"));
+        useBeforeDeclarationWarning = options.isSet("useBeforeDeclarationWarning");
+        enableSunApiLintControl = options.isSet("enableSunApiLintControl");
     }
 
     /** Switch: relax some constraints for retrofit mode.
@@ -1422,7 +1422,8 @@
 
             // Compute the result type.
             Type restype = mtype.getReturnType();
-            assert restype.tag != WILDCARD : mtype;
+            if (restype.tag == WILDCARD)
+                throw new AssertionError(mtype);
 
             // as a special case, array.clone() has a result that is
             // the same as static type of the array being cloned
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Wed Jul 05 17:24:21 2017 +0200
@@ -25,7 +25,6 @@
 
 package com.sun.tools.javac.comp;
 
-import com.sun.source.tree.AssignmentTree;
 import java.util.*;
 import java.util.Set;
 
@@ -46,6 +45,8 @@
 import static com.sun.tools.javac.code.Kinds.*;
 import static com.sun.tools.javac.code.TypeTags.*;
 
+import static com.sun.tools.javac.main.OptionName.*;
+
 /** Type checking helper class for the attribution phase.
  *
  *  <p><b>This is NOT part of any supported API.
@@ -60,6 +61,7 @@
     private final Names names;
     private final Log log;
     private final Symtab syms;
+    private final Enter enter;
     private final Infer infer;
     private final Types types;
     private final JCDiagnostic.Factory diags;
@@ -86,6 +88,7 @@
         names = Names.instance(context);
         log = Log.instance(context);
         syms = Symtab.instance(context);
+        enter = Enter.instance(context);
         infer = Infer.instance(context);
         this.types = Types.instance(context);
         diags = JCDiagnostic.Factory.instance(context);
@@ -97,10 +100,10 @@
         allowGenerics = source.allowGenerics();
         allowAnnotations = source.allowAnnotations();
         allowCovariantReturns = source.allowCovariantReturns();
-        complexInference = options.get("-complexinference") != null;
-        skipAnnotations = options.get("skipAnnotations") != null;
-        warnOnSyntheticConflicts = options.get("warnOnSyntheticConflicts") != null;
-        suppressAbortOnBadClassFile = options.get("suppressAbortOnBadClassFile") != null;
+        complexInference = options.isSet(COMPLEXINFERENCE);
+        skipAnnotations = options.isSet("skipAnnotations");
+        warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts");
+        suppressAbortOnBadClassFile = options.isSet("suppressAbortOnBadClassFile");
 
         Target target = Target.instance(context);
         syntheticNameChar = target.syntheticNameChar();
@@ -1727,6 +1730,113 @@
             return undef;
         }
 
+    void checkNonCyclicDecl(JCClassDecl tree) {
+        CycleChecker cc = new CycleChecker();
+        cc.scan(tree);
+        if (!cc.errorFound && !cc.partialCheck) {
+            tree.sym.flags_field |= ACYCLIC;
+        }
+    }
+
+    class CycleChecker extends TreeScanner {
+
+        List<Symbol> seenClasses = List.nil();
+        boolean errorFound = false;
+        boolean partialCheck = false;
+
+        private void checkSymbol(DiagnosticPosition pos, Symbol sym) {
+            if (sym != null && sym.kind == TYP) {
+                Env<AttrContext> classEnv = enter.getEnv((TypeSymbol)sym);
+                if (classEnv != null) {
+                    DiagnosticSource prevSource = log.currentSource();
+                    try {
+                        log.useSource(classEnv.toplevel.sourcefile);
+                        scan(classEnv.tree);
+                    }
+                    finally {
+                        log.useSource(prevSource.getFile());
+                    }
+                } else if (sym.kind == TYP) {
+                    checkClass(pos, sym, List.<JCTree>nil());
+                }
+            } else {
+                //not completed yet
+                partialCheck = true;
+            }
+        }
+
+        @Override
+        public void visitSelect(JCFieldAccess tree) {
+            super.visitSelect(tree);
+            checkSymbol(tree.pos(), tree.sym);
+        }
+
+        @Override
+        public void visitIdent(JCIdent tree) {
+            checkSymbol(tree.pos(), tree.sym);
+        }
+
+        @Override
+        public void visitTypeApply(JCTypeApply tree) {
+            scan(tree.clazz);
+        }
+
+        @Override
+        public void visitTypeArray(JCArrayTypeTree tree) {
+            scan(tree.elemtype);
+        }
+
+        @Override
+        public void visitClassDef(JCClassDecl tree) {
+            List<JCTree> supertypes = List.nil();
+            if (tree.getExtendsClause() != null) {
+                supertypes = supertypes.prepend(tree.getExtendsClause());
+            }
+            if (tree.getImplementsClause() != null) {
+                for (JCTree intf : tree.getImplementsClause()) {
+                    supertypes = supertypes.prepend(intf);
+                }
+            }
+            checkClass(tree.pos(), tree.sym, supertypes);
+        }
+
+        void checkClass(DiagnosticPosition pos, Symbol c, List<JCTree> supertypes) {
+            if ((c.flags_field & ACYCLIC) != 0)
+                return;
+            if (seenClasses.contains(c)) {
+                errorFound = true;
+                noteCyclic(pos, (ClassSymbol)c);
+            } else if (!c.type.isErroneous()) {
+                try {
+                    seenClasses = seenClasses.prepend(c);
+                    if (c.type.tag == CLASS) {
+                        if (supertypes.nonEmpty()) {
+                            scan(supertypes);
+                        }
+                        else {
+                            ClassType ct = (ClassType)c.type;
+                            if (ct.supertype_field == null ||
+                                    ct.interfaces_field == null) {
+                                //not completed yet
+                                partialCheck = true;
+                                return;
+                            }
+                            checkSymbol(pos, ct.supertype_field.tsym);
+                            for (Type intf : ct.interfaces_field) {
+                                checkSymbol(pos, intf.tsym);
+                            }
+                        }
+                        if (c.owner.kind == TYP) {
+                            checkSymbol(pos, c.owner);
+                        }
+                    }
+                } finally {
+                    seenClasses = seenClasses.tail;
+                }
+            }
+        }
+    }
+
     /** Check for cyclic references. Issue an error if the
      *  symbol of the type referred to has a LOCKED flag set.
      *
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java	Wed Jul 05 17:24:21 2017 +0200
@@ -94,6 +94,7 @@
 
     Log log;
     Symtab syms;
+    Scope.ScopeCounter scopeCounter;
     Check chk;
     TreeMaker make;
     ClassReader reader;
@@ -121,6 +122,7 @@
         reader = ClassReader.instance(context);
         make = TreeMaker.instance(context);
         syms = Symtab.instance(context);
+        scopeCounter = Scope.ScopeCounter.instance(context);
         chk = Check.instance(context);
         memberEnter = MemberEnter.instance(context);
         types = Types.instance(context);
@@ -189,7 +191,7 @@
      */
     public Env<AttrContext> classEnv(JCClassDecl tree, Env<AttrContext> env) {
         Env<AttrContext> localEnv =
-            env.dup(tree, env.info.dup(new Scope(tree.sym)));
+            env.dup(tree, env.info.dup(new Scope.ClassScope(tree.sym, scopeCounter)));
         localEnv.enclClass = tree;
         localEnv.outer = env;
         localEnv.info.isSelfCall = false;
@@ -325,7 +327,7 @@
             c.flatname = names.fromString(tree.packge + "." + name);
             c.sourcefile = tree.sourcefile;
             c.completer = null;
-            c.members_field = new Scope(c);
+            c.members_field = new Scope.ClassScope(c, scopeCounter);
             tree.packge.package_info = c;
         }
         classEnter(tree.defs, topEnv);
@@ -393,7 +395,7 @@
         c.completer = memberEnter;
         c.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, c, tree);
         c.sourcefile = env.toplevel.sourcefile;
-        c.members_field = new Scope(c);
+        c.members_field = new Scope.ClassScope(c, scopeCounter);
 
         ClassType ct = (ClassType)c.type;
         if (owner.kind != PCK && (c.flags_field & STATIC) == 0) {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java	Wed Jul 05 17:24:21 2017 +0200
@@ -80,25 +80,12 @@
 
     }
 
-    public static class InferenceException extends RuntimeException {
+    public static class InferenceException extends Resolve.InapplicableMethodException {
         private static final long serialVersionUID = 0;
 
-        JCDiagnostic diagnostic;
-        JCDiagnostic.Factory diags;
-
         InferenceException(JCDiagnostic.Factory diags) {
-            this.diagnostic = null;
-            this.diags = diags;
+            super(diags);
         }
-
-        InferenceException setMessage(String key, Object... args) {
-            this.diagnostic = diags.fragment(key, args);
-            return this;
-        }
-
-        public JCDiagnostic getDiagnostic() {
-             return diagnostic;
-         }
     }
 
     public static class NoInstanceException extends InferenceException {
@@ -320,7 +307,7 @@
         Type qtype1 = types.subst(that.qtype, that.tvars, undetvars);
         if (!types.isSubtype(qtype1, to)) {
             throw unambiguousNoInstanceException
-                .setMessage("no.conforming.instance.exists",
+                .setMessage("infer.no.conforming.instance.exists",
                             that.tvars, that.qtype, to);
         }
         for (List<Type> l = undetvars; l.nonEmpty(); l = l.tail)
@@ -378,6 +365,11 @@
         // instantiate all polymorphic argument types and
         // set up lower bounds constraints for undetvars
         Type varargsFormal = useVarargs ? formals.last() : null;
+        if (varargsFormal == null &&
+                actuals.size() != formals.size()) {
+            throw unambiguousNoInstanceException
+                .setMessage("infer.arg.length.mismatch");
+        }
         while (actuals.nonEmpty() && formals.head != varargsFormal) {
             Type formal = formals.head;
             Type actual = actuals.head.baseType();
@@ -390,19 +382,16 @@
                 : types.isSubtypeUnchecked(actual, undetFormal, warn);
             if (!works) {
                 throw unambiguousNoInstanceException
-                    .setMessage("no.conforming.assignment.exists",
+                    .setMessage("infer.no.conforming.assignment.exists",
                                 tvars, actualNoCapture, formal);
             }
             formals = formals.tail;
             actuals = actuals.tail;
             actualsNoCapture = actualsNoCapture.tail;
         }
-        if (formals.head != varargsFormal || // not enough args
-            !useVarargs && actuals.nonEmpty()) { // too many args
-            // argument lists differ in length
-            throw unambiguousNoInstanceException
-                .setMessage("arg.length.mismatch");
-        }
+
+        if (formals.head != varargsFormal) // not enough args
+            throw unambiguousNoInstanceException.setMessage("infer.arg.length.mismatch");
 
         // for varargs arguments as well
         if (useVarargs) {
@@ -416,7 +405,7 @@
                 boolean works = types.isConvertible(actual, elemUndet, warn);
                 if (!works) {
                     throw unambiguousNoInstanceException
-                        .setMessage("no.conforming.assignment.exists",
+                        .setMessage("infer.no.conforming.assignment.exists",
                                     tvars, actualNoCapture, elemType);
                 }
                 actuals = actuals.tail;
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java	Wed Jul 05 17:24:21 2017 +0200
@@ -68,6 +68,7 @@
     private Names names;
     private Log log;
     private Symtab syms;
+    private Scope.ScopeCounter scopeCounter;
     private Resolve rs;
     private Check chk;
     private Attr attr;
@@ -90,6 +91,7 @@
         names = Names.instance(context);
         log = Log.instance(context);
         syms = Symtab.instance(context);
+        scopeCounter = Scope.ScopeCounter.instance(context);
         rs = Resolve.instance(context);
         chk = Check.instance(context);
         attr = Attr.instance(context);
@@ -107,7 +109,7 @@
 
         types = Types.instance(context);
         Options options = Options.instance(context);
-        debugLower = options.get("debuglower") != null;
+        debugLower = options.isSet("debuglower");
         pkginfoOpt = PkgInfo.get(options);
     }
 
@@ -569,7 +571,7 @@
         c.flatname = chk.localClassName(c);
         c.sourcefile = owner.sourcefile;
         c.completer = null;
-        c.members_field = new Scope(c);
+        c.members_field = new Scope.ClassScope(c, scopeCounter);
         c.flags_field = flags;
         ClassType ctype = (ClassType) c.type;
         ctype.supertype_field = syms.objectType;
@@ -2677,7 +2679,8 @@
     }
 //where
         private JCTree convert(JCTree tree, Type pt) {
-            if (tree.type == pt) return tree;
+            if (tree.type == pt || tree.type.tag == TypeTags.BOT)
+                return tree;
             JCTree result = make_at(tree.pos()).TypeCast(make.Type(pt), (JCExpression)tree);
             result.type = (tree.type.constValue() != null) ? cfolder.coerce(tree.type, pt)
                                                            : pt;
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Wed Jul 05 17:24:21 2017 +0200
@@ -67,6 +67,7 @@
     private final Check chk;
     private final Attr attr;
     private final Symtab syms;
+    private final Scope.ScopeCounter scopeCounter;
     private final TreeMaker make;
     private final ClassReader reader;
     private final Todo todo;
@@ -92,6 +93,7 @@
         chk = Check.instance(context);
         attr = Attr.instance(context);
         syms = Symtab.instance(context);
+        scopeCounter = Scope.ScopeCounter.instance(context);
         make = TreeMaker.instance(context);
         reader = ClassReader.instance(context);
         todo = Todo.instance(context);
@@ -100,7 +102,7 @@
         diags = JCDiagnostic.Factory.instance(context);
         target = Target.instance(context);
         Options options = Options.instance(context);
-        skipAnnotations = options.get("skipAnnotations") != null;
+        skipAnnotations = options.isSet("skipAnnotations");
     }
 
     /** A queue for classes whose members still need to be entered into the
@@ -925,7 +927,7 @@
                 tp.accept(new TypeAnnotate(baseEnv));
             tree.accept(new TypeAnnotate(env));
 
-            chk.checkNonCyclic(tree.pos(), c.type);
+            chk.checkNonCyclicDecl(tree);
 
             attr.attribTypeVariables(tree.typarams, baseEnv);
 
@@ -1087,7 +1089,7 @@
 
 
     private Env<AttrContext> baseEnv(JCClassDecl tree, Env<AttrContext> env) {
-        Scope baseScope = new Scope(tree.sym);
+        Scope baseScope = new Scope.ClassScope(tree.sym, scopeCounter);
         //import already entered local classes into base scope
         for (Scope.Entry e = env.outer.info.scope.elems ; e != null ; e = e.sibling) {
             if (e.sym.isLocal()) {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Wed Jul 05 17:24:21 2017 +0200
@@ -110,15 +110,17 @@
         boxingEnabled = source.allowBoxing();
         varargsEnabled = source.allowVarargs();
         Options options = Options.instance(context);
-        debugResolve = options.get("debugresolve") != null;
-        allowTransitionalJSR292 = options.get("allowTransitionalJSR292") != null;
+        debugResolve = options.isSet("debugresolve");
+        allowTransitionalJSR292 = options.isSet("allowTransitionalJSR292");
         Target target = Target.instance(context);
         allowMethodHandles = allowTransitionalJSR292 ||
                 target.hasMethodHandles();
         allowInvokeDynamic = (allowTransitionalJSR292 ||
                 target.hasInvokedynamic()) &&
-                options.get("invokedynamic") != null;
+                options.isSet("invokedynamic");
         polymorphicSignatureScope = new Scope(syms.noSymbol);
+
+        inapplicableMethodException = new InapplicableMethodException(diags);
     }
 
     /** error symbols, which are returned when resolution fails
@@ -318,7 +320,8 @@
         throws Infer.InferenceException {
         boolean polymorphicSignature = (m.isPolymorphicSignatureGeneric() && allowMethodHandles) ||
                                         isTransitionalDynamicCallSite(site, m);
-        if (useVarargs && (m.flags() & VARARGS) == 0) return null;
+        if (useVarargs && (m.flags() & VARARGS) == 0)
+            throw inapplicableMethodException.setMessage(null);
         Type mt = types.memberType(site, m);
 
         // tvars is the list of formal type variables for which type arguments
@@ -334,7 +337,7 @@
         } else if (mt.tag == FORALL && typeargtypes.nonEmpty()) {
             ForAll pmt = (ForAll) mt;
             if (typeargtypes.length() != pmt.tvars.length())
-                return null;
+                throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args
             // Check type arguments are within bounds
             List<Type> formals = pmt.tvars;
             List<Type> actuals = typeargtypes;
@@ -343,7 +346,7 @@
                                                 pmt.tvars, typeargtypes);
                 for (; bounds.nonEmpty(); bounds = bounds.tail)
                     if (!types.isSubtypeUnchecked(actuals.head, bounds.head, warn))
-                        return null;
+                        throw inapplicableMethodException.setMessage("explicit.param.do.not.conform.to.bounds",actuals.head, bounds);
                 formals = formals.tail;
                 actuals = actuals.tail;
             }
@@ -375,11 +378,10 @@
                                     allowBoxing,
                                     useVarargs,
                                     warn);
-        return
-            argumentsAcceptable(argtypes, mt.getParameterTypes(),
-                                allowBoxing, useVarargs, warn)
-            ? mt
-            : null;
+
+        checkRawArgumentsAcceptable(argtypes, mt.getParameterTypes(),
+                                allowBoxing, useVarargs, warn);
+        return mt;
     }
 
     boolean isTransitionalDynamicCallSite(Type site, Symbol sym) {
@@ -403,7 +405,7 @@
         try {
             return rawInstantiate(env, site, m, argtypes, typeargtypes,
                                   allowBoxing, useVarargs, warn);
-        } catch (Infer.InferenceException ex) {
+        } catch (InapplicableMethodException ex) {
             return null;
         }
     }
@@ -415,26 +417,76 @@
                                 boolean allowBoxing,
                                 boolean useVarargs,
                                 Warner warn) {
+        try {
+            checkRawArgumentsAcceptable(argtypes, formals, allowBoxing, useVarargs, warn);
+            return true;
+        } catch (InapplicableMethodException ex) {
+            return false;
+        }
+    }
+    void checkRawArgumentsAcceptable(List<Type> argtypes,
+                                List<Type> formals,
+                                boolean allowBoxing,
+                                boolean useVarargs,
+                                Warner warn) {
         Type varargsFormal = useVarargs ? formals.last() : null;
+        if (varargsFormal == null &&
+                argtypes.size() != formals.size()) {
+            throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args
+        }
+
         while (argtypes.nonEmpty() && formals.head != varargsFormal) {
             boolean works = allowBoxing
                 ? types.isConvertible(argtypes.head, formals.head, warn)
                 : types.isSubtypeUnchecked(argtypes.head, formals.head, warn);
-            if (!works) return false;
+            if (!works)
+                throw inapplicableMethodException.setMessage("no.conforming.assignment.exists",
+                        argtypes.head,
+                        formals.head);
             argtypes = argtypes.tail;
             formals = formals.tail;
         }
-        if (formals.head != varargsFormal) return false; // not enough args
-        if (!useVarargs)
-            return argtypes.isEmpty();
-        Type elt = types.elemtype(varargsFormal);
-        while (argtypes.nonEmpty()) {
-            if (!types.isConvertible(argtypes.head, elt, warn))
-                return false;
-            argtypes = argtypes.tail;
+
+        if (formals.head != varargsFormal)
+            throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args
+
+        if (useVarargs) {
+            Type elt = types.elemtype(varargsFormal);
+            while (argtypes.nonEmpty()) {
+                if (!types.isConvertible(argtypes.head, elt, warn))
+                    throw inapplicableMethodException.setMessage("varargs.argument.mismatch",
+                            argtypes.head,
+                            elt);
+                argtypes = argtypes.tail;
+            }
         }
-        return true;
+        return;
     }
+    // where
+        public static class InapplicableMethodException extends RuntimeException {
+            private static final long serialVersionUID = 0;
+
+            JCDiagnostic diagnostic;
+            JCDiagnostic.Factory diags;
+
+            InapplicableMethodException(JCDiagnostic.Factory diags) {
+                this.diagnostic = null;
+                this.diags = diags;
+            }
+            InapplicableMethodException setMessage(String key) {
+                this.diagnostic = key != null ? diags.fragment(key) : null;
+                return this;
+            }
+            InapplicableMethodException setMessage(String key, Object... args) {
+                this.diagnostic = key != null ? diags.fragment(key, args) : null;
+                return this;
+            }
+
+            public JCDiagnostic getDiagnostic() {
+                return diagnostic;
+            }
+        }
+        private final InapplicableMethodException inapplicableMethodException;
 
 /* ***************************************************************************
  *  Symbol lookup
@@ -595,6 +647,7 @@
      *  @param allowBoxing Allow boxing conversions of arguments.
      *  @param useVarargs Box trailing arguments into an array for varargs.
      */
+    @SuppressWarnings("fallthrough")
     Symbol selectBest(Env<AttrContext> env,
                       Type site,
                       List<Type> argtypes,
@@ -608,21 +661,16 @@
         if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar;
         assert sym.kind < AMBIGUOUS;
         try {
-            if (rawInstantiate(env, site, sym, argtypes, typeargtypes,
-                               allowBoxing, useVarargs, Warner.noWarnings) == null) {
-                // inapplicable
-                switch (bestSoFar.kind) {
-                case ABSENT_MTH: return wrongMethod.setWrongSym(sym);
-                case WRONG_MTH: return wrongMethods;
-                default: return bestSoFar;
-                }
-            }
-        } catch (Infer.InferenceException ex) {
+            rawInstantiate(env, site, sym, argtypes, typeargtypes,
+                               allowBoxing, useVarargs, Warner.noWarnings);
+        } catch (InapplicableMethodException ex) {
             switch (bestSoFar.kind) {
             case ABSENT_MTH:
                 return wrongMethod.setWrongSym(sym, ex.getDiagnostic());
             case WRONG_MTH:
-                return wrongMethods;
+                wrongMethods.addCandidate(currentStep, wrongMethod.sym, wrongMethod.explanation);
+            case WRONG_MTHS:
+                return wrongMethods.addCandidate(currentStep, sym, ex.getDiagnostic());
             default:
                 return bestSoFar;
             }
@@ -631,7 +679,7 @@
             return (bestSoFar.kind == ABSENT_MTH)
                 ? new AccessError(env, site, sym)
                 : bestSoFar;
-        }
+            }
         return (bestSoFar.kind > AMBIGUOUS)
             ? sym
             : mostSpecific(sym, bestSoFar, env, site,
@@ -1253,11 +1301,12 @@
                          Name name,
                          List<Type> argtypes,
                          List<Type> typeargtypes) {
-        Symbol sym = methodNotFound;
+        Symbol sym = startResolution();
         List<MethodResolutionPhase> steps = methodResolutionSteps;
         while (steps.nonEmpty() &&
                steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
                sym.kind >= ERRONEOUS) {
+            currentStep = steps.head;
             sym = findFun(env, name, argtypes, typeargtypes,
                     steps.head.isBoxingRequired,
                     env.info.varArgs = steps.head.isVarargsRequired);
@@ -1274,6 +1323,12 @@
         return sym;
     }
 
+    private Symbol startResolution() {
+        wrongMethod.clear();
+        wrongMethods.clear();
+        return methodNotFound;
+    }
+
     /** Resolve a qualified method identifier
      *  @param pos       The position to use for error reporting.
      *  @param env       The environment current at the method invocation.
@@ -1286,11 +1341,12 @@
     Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
                                   Type site, Name name, List<Type> argtypes,
                                   List<Type> typeargtypes) {
-        Symbol sym = methodNotFound;
+        Symbol sym = startResolution();
         List<MethodResolutionPhase> steps = methodResolutionSteps;
         while (steps.nonEmpty() &&
                steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
                sym.kind >= ERRONEOUS) {
+            currentStep = steps.head;
             sym = findMethod(env, site, name, argtypes, typeargtypes,
                     steps.head.isBoxingRequired(),
                     env.info.varArgs = steps.head.isVarargsRequired(), false);
@@ -1404,11 +1460,12 @@
                               Type site,
                               List<Type> argtypes,
                               List<Type> typeargtypes) {
-        Symbol sym = methodNotFound;
+        Symbol sym = startResolution();
         List<MethodResolutionPhase> steps = methodResolutionSteps;
         while (steps.nonEmpty() &&
                steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
                sym.kind >= ERRONEOUS) {
+            currentStep = steps.head;
             sym = resolveConstructor(pos, env, site, argtypes, typeargtypes,
                     steps.head.isBoxingRequired(),
                     env.info.varArgs = steps.head.isVarargsRequired());
@@ -1439,26 +1496,22 @@
                               Type site,
                               List<Type> argtypes,
                               List<Type> typeargtypes) {
-        Symbol sym = methodNotFound;
-        JCDiagnostic explanation = null;
+        Symbol sym = startResolution();
         List<MethodResolutionPhase> steps = methodResolutionSteps;
         while (steps.nonEmpty() &&
                steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
                sym.kind >= ERRONEOUS) {
+            currentStep = steps.head;
             sym = resolveConstructor(pos, env, site, argtypes, typeargtypes,
                     steps.head.isBoxingRequired(),
                     env.info.varArgs = steps.head.isVarargsRequired());
             methodResolutionCache.put(steps.head, sym);
-            if (sym.kind == WRONG_MTH &&
-                    ((InapplicableSymbolError)sym).explanation != null) {
-                //if the symbol is an inapplicable method symbol, then the
-                //explanation contains the reason for which inference failed
-                explanation = ((InapplicableSymbolError)sym).explanation;
-            }
             steps = steps.tail;
         }
         if (sym.kind >= AMBIGUOUS) {
-            final JCDiagnostic details = explanation;
+            final JCDiagnostic details = sym.kind == WRONG_MTH ?
+                ((InapplicableSymbolError)sym).explanation :
+                null;
             Symbol errSym = new ResolveError(WRONG_MTH, "diamond error") {
                 @Override
                 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
@@ -1860,7 +1913,8 @@
          */
         InapplicableSymbolError setWrongSym(Symbol sym, JCDiagnostic explanation) {
             this.sym = sym;
-            this.explanation = explanation;
+            if (this.sym == sym && explanation != null)
+                this.explanation = explanation; //update the details
             return this;
         }
 
@@ -1868,7 +1922,6 @@
          */
         InapplicableSymbolError setWrongSym(Symbol sym) {
             this.sym = sym;
-            this.explanation = null;
             return this;
         }
 
@@ -1905,6 +1958,10 @@
             }
         }
 
+        void clear() {
+            explanation = null;
+        }
+
         @Override
         public Symbol access(Name name, TypeSymbol location) {
             return types.createErrorType(name, location, syms.errSymbol.type).tsym;
@@ -1917,6 +1974,9 @@
      * given an actual arguments/type argument list.
      */
     class InapplicableSymbolsError extends ResolveError {
+
+        private List<Candidate> candidates = List.nil();
+
         InapplicableSymbolsError(Symbol sym) {
             super(WRONG_MTHS, "inapplicable symbols");
         }
@@ -1928,8 +1988,85 @@
                 Name name,
                 List<Type> argtypes,
                 List<Type> typeargtypes) {
-            return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos,
+            if (candidates.nonEmpty()) {
+                JCDiagnostic err = diags.create(dkind,
+                        log.currentSource(),
+                        pos,
+                        "cant.apply.symbols",
+                        name == names.init ? KindName.CONSTRUCTOR : absentKind(kind),
+                        getName(),
+                        argtypes);
+                return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(site));
+            } else {
+                return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos,
                     site, name, argtypes, typeargtypes);
+            }
+        }
+
+        //where
+        List<JCDiagnostic> candidateDetails(Type site) {
+            List<JCDiagnostic> details = List.nil();
+            for (Candidate c : candidates)
+                details = details.prepend(c.getDiagnostic(site));
+            return details.reverse();
+        }
+
+        Symbol addCandidate(MethodResolutionPhase currentStep, Symbol sym, JCDiagnostic details) {
+            Candidate c = new Candidate(currentStep, sym, details);
+            if (c.isValid() && !candidates.contains(c))
+                candidates = candidates.append(c);
+            return this;
+        }
+
+        void clear() {
+            candidates = List.nil();
+        }
+
+        private Name getName() {
+            Symbol sym = candidates.head.sym;
+            return sym.name == names.init ?
+                sym.owner.name :
+                sym.name;
+        }
+
+        private class Candidate {
+
+            final MethodResolutionPhase step;
+            final Symbol sym;
+            final JCDiagnostic details;
+
+            private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details) {
+                this.step = step;
+                this.sym = sym;
+                this.details = details;
+            }
+
+            JCDiagnostic getDiagnostic(Type site) {
+                return diags.fragment("inapplicable.method",
+                        Kinds.kindName(sym),
+                        sym.location(site, types),
+                        sym.asMemberOf(site, types),
+                        details);
+            }
+
+            @Override
+            public boolean equals(Object o) {
+                if (o instanceof Candidate) {
+                    Symbol s1 = this.sym;
+                    Symbol s2 = ((Candidate)o).sym;
+                    if  ((s1 != s2 &&
+                        (s1.overrides(s2, s1.owner.type.tsym, types, false) ||
+                        (s2.overrides(s1, s2.owner.type.tsym, types, false)))) ||
+                        ((s1.isConstructor() || s2.isConstructor()) && s1.owner != s2.owner))
+                        return true;
+                }
+                return false;
+            }
+
+            boolean isValid() {
+                return  (((sym.flags() & VARARGS) != 0 && step == VARARITY) ||
+                          (sym.flags() & VARARGS) == 0 && step == (boxingEnabled ? BOX : BASIC));
+            }
         }
     }
 
@@ -2093,6 +2230,8 @@
 
     final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY);
 
+    private MethodResolutionPhase currentStep = null;
+
     private MethodResolutionPhase firstErroneousResolutionPhase() {
         MethodResolutionPhase bestSoFar = BASIC;
         Symbol sym = methodNotFound;
--- a/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -150,8 +150,8 @@
 
         useZipFileIndex = System.getProperty("useJavaUtilZip") == null;// TODO: options.get("useJavaUtilZip") == null;
 
-        mmappedIO = options.get("mmappedIO") != null;
-        ignoreSymbolFile = options.get("ignore.symbol.file") != null;
+        mmappedIO = options.isSet("mmappedIO");
+        ignoreSymbolFile = options.isSet("ignore.symbol.file");
     }
 
     public JavaFileObject getFileForInput(String name) {
@@ -435,7 +435,7 @@
                     zdir = new ZipFile(zipFileName);
                 }
                 else {
-                    usePreindexedCache = options.get("usezipindex") != null;
+                    usePreindexedCache = options.isSet("usezipindex");
                     preindexCacheLocation = options.get("java.io.tmpdir");
                     String optCacheLoc = options.get("cachezipindexdir");
 
@@ -469,7 +469,7 @@
                                     null,
                                     usePreindexedCache,
                                     preindexCacheLocation,
-                                    options.get("writezipindexfiles") != null));
+                                    options.isSet("writezipindexfiles")));
                     }
                 }
                 else {
@@ -482,7 +482,7 @@
                                     symbolFilePrefix,
                                     usePreindexedCache,
                                     preindexCacheLocation,
-                                    options.get("writezipindexfiles") != null));
+                                    options.isSet("writezipindexfiles")));
                     }
                 }
             } catch (FileNotFoundException ex) {
@@ -605,7 +605,7 @@
         nullCheck(className);
         nullCheck(kind);
         if (!sourceOrClass.contains(kind))
-            throw new IllegalArgumentException("Invalid kind " + kind);
+            throw new IllegalArgumentException("Invalid kind: " + kind);
         return getFileForInput(location, RelativeFile.forClass(className, kind));
     }
 
@@ -658,7 +658,7 @@
         nullCheck(className);
         nullCheck(kind);
         if (!sourceOrClass.contains(kind))
-            throw new IllegalArgumentException("Invalid kind " + kind);
+            throw new IllegalArgumentException("Invalid kind: " + kind);
         return getFileForOutput(location, RelativeFile.forClass(className, kind), sibling);
     }
 
@@ -672,7 +672,7 @@
         // validatePackageName(packageName);
         nullCheck(packageName);
         if (!isRelativeUri(relativeName))
-            throw new IllegalArgumentException("relativeName is invalid");
+            throw new IllegalArgumentException("Invalid relative name: " + relativeName);
         RelativeFile name = packageName.length() == 0
             ? new RelativeFile(relativeName)
             : new RelativeFile(RelativeDirectory.forPackage(packageName), relativeName);
@@ -806,6 +806,8 @@
         String path = uri.normalize().getPath();
         if (path.length() == 0 /* isEmpty() is mustang API */)
             return false;
+        if (!path.equals(uri.getPath())) // implicitly checks for embedded . and ..
+            return false;
         char first = path.charAt(0);
         return first != '.' && first != '/';
     }
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Wed Jul 05 17:24:21 2017 +0200
@@ -56,6 +56,8 @@
 import static com.sun.tools.javac.jvm.ClassFile.*;
 import static com.sun.tools.javac.jvm.ClassFile.Version.*;
 
+import static com.sun.tools.javac.main.OptionName.*;
+
 /** This class provides operations to read a classfile into an internal
  *  representation. The internal representation is anchored in a
  *  ClassSymbol which contains in its scope symbol representations
@@ -122,6 +124,9 @@
     /** The symbol table. */
     Symtab syms;
 
+    /** The scope counter */
+    Scope.ScopeCounter scopeCounter;
+
     Types types;
 
     /** The name table. */
@@ -244,6 +249,7 @@
 
         names = Names.instance(context);
         syms = Symtab.instance(context);
+        scopeCounter = Scope.ScopeCounter.instance(context);
         types = Types.instance(context);
         fileManager = context.get(JavaFileManager.class);
         if (fileManager == null)
@@ -255,23 +261,23 @@
 
         Options options = Options.instance(context);
         annotate = Annotate.instance(context);
-        verbose        = options.get("-verbose")        != null;
-        checkClassFile = options.get("-checkclassfile") != null;
+        verbose        = options.isSet(VERBOSE);
+        checkClassFile = options.isSet("-checkclassfile");
         Source source = Source.instance(context);
         allowGenerics    = source.allowGenerics();
         allowVarargs     = source.allowVarargs();
         allowAnnotations = source.allowAnnotations();
-        saveParameterNames = options.get("save-parameter-names") != null;
-        cacheCompletionFailure = options.get("dev") == null;
+        saveParameterNames = options.isSet("save-parameter-names");
+        cacheCompletionFailure = options.isUnset("dev");
         preferSource = "source".equals(options.get("-Xprefer"));
 
         completionFailureName =
-            (options.get("failcomplete") != null)
+            options.isSet("failcomplete")
             ? names.fromString(options.get("failcomplete"))
             : null;
 
         typevars = new Scope(syms.noSymbol);
-        debugJSR308 = options.get("TA:reader") != null;
+        debugJSR308 = options.isSet("TA:reader");
 
         initAttributeReaders();
     }
@@ -1984,7 +1990,7 @@
         ClassType ct = (ClassType)c.type;
 
         // allocate scope for members
-        c.members_field = new Scope(c);
+        c.members_field = new Scope.ClassScope(c, scopeCounter);
 
         // prepare type variable table
         typevars = typevars.dup(currentOwner);
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Wed Jul 05 17:24:21 2017 +0200
@@ -45,8 +45,10 @@
 import static com.sun.tools.javac.code.Kinds.*;
 import static com.sun.tools.javac.code.TypeTags.*;
 import static com.sun.tools.javac.jvm.UninitializedType.*;
+import static com.sun.tools.javac.main.OptionName.*;
 import static javax.tools.StandardLocation.CLASS_OUTPUT;
 
+
 /** This class provides operations to map an internal symbol table graph
  *  rooted in a ClassSymbol into a classfile.
  *
@@ -178,15 +180,16 @@
         types = Types.instance(context);
         fileManager = context.get(JavaFileManager.class);
 
-        debugJSR308    = options.get("TA:writer") != null;
-        verbose        = options.get("-verbose")     != null;
-        scramble       = options.get("-scramble")    != null;
-        scrambleAll    = options.get("-scrambleAll") != null;
-        retrofit       = options.get("-retrofit") != null;
-        genCrt         = options.get("-Xjcov") != null;
-        debugstackmap  = options.get("debugstackmap") != null;
+        debugJSR308    = options.isSet("TA:writer");
+        verbose        = options.isSet(VERBOSE);
+        scramble       = options.isSet("-scramble");
+        scrambleAll    = options.isSet("-scrambleAll");
+        retrofit       = options.isSet("-retrofit");
+        genCrt         = options.isSet(XJCOV);
+        debugstackmap  = options.isSet("debugstackmap");
 
-        emitSourceFile = options.get("-g:")==null || options.get("-g:source")!=null;
+        emitSourceFile = options.isUnset(G_CUSTOM) ||
+                            options.isSet(G_CUSTOM, "source");
 
         String dumpModFlags = options.get("dumpmodifiers");
         dumpClassModifiers =
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Wed Jul 05 17:24:21 2017 +0200
@@ -46,6 +46,7 @@
 import static com.sun.tools.javac.code.TypeTags.*;
 import static com.sun.tools.javac.jvm.ByteCodes.*;
 import static com.sun.tools.javac.jvm.CRTFlags.*;
+import static com.sun.tools.javac.main.OptionName.*;
 
 /** This pass maps flat Java (i.e. without inner classes) to bytecodes.
  *
@@ -113,19 +114,19 @@
 
         Options options = Options.instance(context);
         lineDebugInfo =
-            options.get("-g:") == null ||
-            options.get("-g:lines") != null;
+            options.isUnset(G_CUSTOM) ||
+            options.isSet(G_CUSTOM, "lines");
         varDebugInfo =
-            options.get("-g:") == null
-            ? options.get("-g") != null
-            : options.get("-g:vars") != null;
-        genCrt = options.get("-Xjcov") != null;
-        debugCode = options.get("debugcode") != null;
-        allowInvokedynamic = target.hasInvokedynamic() || options.get("invokedynamic") != null;
+            options.isUnset(G_CUSTOM)
+            ? options.isSet(G)
+            : options.isSet(G_CUSTOM, "vars");
+        genCrt = options.isSet(XJCOV);
+        debugCode = options.isSet("debugcode");
+        allowInvokedynamic = target.hasInvokedynamic() || options.isSet("invokedynamic");
 
         generateIproxies =
             target.requiresIproxy() ||
-            options.get("miranda") != null;
+            options.isSet("miranda");
 
         if (target.generateStackMapTable()) {
             // ignore cldc because we cannot have both stackmap formats
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java	Wed Jul 05 17:24:21 2017 +0200
@@ -31,6 +31,8 @@
 import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.util.*;
 
+import static com.sun.tools.javac.main.OptionName.*;
+
 /** The classfile version target.
  *
  *  <p><b>This is NOT part of any supported API.
@@ -73,7 +75,7 @@
         Target instance = context.get(targetKey);
         if (instance == null) {
             Options options = Options.instance(context);
-            String targetString = options.get("-target");
+            String targetString = options.get(TARGET);
             if (targetString != null) instance = lookup(targetString);
             if (instance == null) instance = DEFAULT;
             context.put(targetKey, instance);
--- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,48 +26,44 @@
 package com.sun.tools.javac.main;
 
 import java.io.*;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.MissingResourceException;
+import java.util.Queue;
 import java.util.ResourceBundle;
 import java.util.Set;
 import java.util.logging.Handler;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import javax.annotation.processing.Processor;
+import javax.lang.model.SourceVersion;
 import javax.tools.JavaFileManager;
 import javax.tools.JavaFileObject;
 import javax.tools.DiagnosticListener;
 
-import com.sun.tools.javac.file.JavacFileManager;
 import com.sun.source.util.TaskEvent;
 import com.sun.source.util.TaskListener;
 
+import com.sun.tools.javac.file.JavacFileManager;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.tree.*;
+import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.parser.*;
 import com.sun.tools.javac.comp.*;
 import com.sun.tools.javac.jvm.*;
-
-import com.sun.tools.javac.code.Symbol.*;
-import com.sun.tools.javac.tree.JCTree.*;
-
 import com.sun.tools.javac.processing.*;
-import javax.annotation.processing.Processor;
 
 import static javax.tools.StandardLocation.CLASS_OUTPUT;
+import static com.sun.tools.javac.main.OptionName.*;
 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
 import static com.sun.tools.javac.util.ListBuffer.lb;
 
-// TEMP, until we have a more efficient way to save doc comment info
-import com.sun.tools.javac.parser.DocCommentScanner;
-
-import java.util.HashMap;
-import java.util.Queue;
-import javax.lang.model.SourceVersion;
 
 /** This class could be the main entry point for GJC when GJC is used as a
  *  component in a larger software system. It provides operations to
@@ -359,22 +355,22 @@
 
         Options options = Options.instance(context);
 
-        verbose       = options.get("-verbose")       != null;
-        sourceOutput  = options.get("-printsource")   != null; // used to be -s
-        stubOutput    = options.get("-stubs")         != null;
-        relax         = options.get("-relax")         != null;
-        printFlat     = options.get("-printflat")     != null;
-        attrParseOnly = options.get("-attrparseonly") != null;
-        encoding      = options.get("-encoding");
-        lineDebugInfo = options.get("-g:")            == null ||
-                        options.get("-g:lines")       != null;
-        genEndPos     = options.get("-Xjcov")         != null ||
+        verbose       = options.isSet(VERBOSE);
+        sourceOutput  = options.isSet(PRINTSOURCE); // used to be -s
+        stubOutput    = options.isSet("-stubs");
+        relax         = options.isSet("-relax");
+        printFlat     = options.isSet("-printflat");
+        attrParseOnly = options.isSet("-attrparseonly");
+        encoding      = options.get(ENCODING);
+        lineDebugInfo = options.isUnset(G_CUSTOM) ||
+                        options.isSet(G_CUSTOM, "lines");
+        genEndPos     = options.isSet(XJCOV) ||
                         context.get(DiagnosticListener.class) != null;
-        devVerbose    = options.get("dev") != null;
-        processPcks   = options.get("process.packages") != null;
-        werror        = options.get("-Werror")        != null;
+        devVerbose    = options.isSet("dev");
+        processPcks   = options.isSet("process.packages");
+        werror        = options.isSet(WERROR);
 
-        verboseCompilePolicy = options.get("verboseCompilePolicy") != null;
+        verboseCompilePolicy = options.isSet("verboseCompilePolicy");
 
         if (attrParseOnly)
             compilePolicy = CompilePolicy.ATTR_ONLY;
@@ -384,15 +380,15 @@
         implicitSourcePolicy = ImplicitSourcePolicy.decode(options.get("-implicit"));
 
         completionFailureName =
-            (options.get("failcomplete") != null)
+            options.isSet("failcomplete")
             ? names.fromString(options.get("failcomplete"))
             : null;
 
         shouldStopPolicy =
-            (options.get("shouldStopPolicy") != null)
+            options.isSet("shouldStopPolicy")
             ? CompileState.valueOf(options.get("shouldStopPolicy"))
             : null;
-        if (options.get("oldDiags") == null)
+        if (options.isUnset("oldDiags"))
             log.setDiagnosticFormatter(RichDiagnosticFormatter.instance(context));
     }
 
@@ -957,18 +953,17 @@
         // Process annotations if processing is not disabled and there
         // is at least one Processor available.
         Options options = Options.instance(context);
-        if (options.get("-proc:none") != null) {
+        if (options.isSet(PROC, "none")) {
             processAnnotations = false;
         } else if (procEnvImpl == null) {
             procEnvImpl = new JavacProcessingEnvironment(context, processors);
             processAnnotations = procEnvImpl.atLeastOneProcessor();
 
             if (processAnnotations) {
-                if (context.get(Scanner.Factory.scannerFactoryKey) == null)
-                    DocCommentScanner.Factory.preRegister(context);
                 options.put("save-parameter-names", "save-parameter-names");
                 reader.saveParameterNames = true;
                 keepComments = true;
+                genEndPos = true;
                 if (taskListener != null)
                     taskListener.started(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING));
                 log.deferDiagnostics = true;
@@ -1017,7 +1012,7 @@
             // annotation processing is to occur with compilation,
             // emit a warning.
             Options options = Options.instance(context);
-            if (options.get("-proc:only") != null) {
+            if (options.isSet(PROC, "only")) {
                 log.warning("proc.proc-only.requested.no.procs");
                 todo.clear();
             }
@@ -1105,10 +1100,10 @@
         Options options = Options.instance(context);
         return
             explicitAnnotationProcessingRequested ||
-            options.get("-processor") != null ||
-            options.get("-processorpath") != null ||
-            options.get("-proc:only") != null ||
-            options.get("-Xprint") != null;
+            options.isSet(PROCESSOR) ||
+            options.isSet(PROCESSORPATH) ||
+            options.isSet(PROC, "only") ||
+            options.isSet(XPRINT);
     }
 
     /**
@@ -1587,6 +1582,7 @@
     }
 
     public void initRound(JavaCompiler prev) {
+        genEndPos = prev.genEndPos;
         keepComments = prev.keepComments;
         start_msec = prev.start_msec;
         hasBeenUsed = true;
--- a/langtools/src/share/classes/com/sun/tools/javac/main/Main.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/Main.java	Wed Jul 05 17:24:21 2017 +0200
@@ -32,6 +32,9 @@
 import java.security.DigestInputStream;
 import java.security.MessageDigest;
 import java.util.MissingResourceException;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.annotation.processing.Processor;
 
 import com.sun.tools.javac.code.Source;
 import com.sun.tools.javac.file.CacheFSInfo;
@@ -41,9 +44,8 @@
 import com.sun.tools.javac.main.RecognizedOptions.OptionHelper;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.processing.AnnotationProcessingError;
-import javax.tools.JavaFileManager;
-import javax.tools.JavaFileObject;
-import javax.annotation.processing.Processor;
+
+import static com.sun.tools.javac.main.OptionName.*;
 
 /** This class provides a commandline interface to the GJC compiler.
  *
@@ -239,16 +241,16 @@
             }
         }
 
-        if (!checkDirectory("-d"))
+        if (!checkDirectory(D))
             return null;
-        if (!checkDirectory("-s"))
+        if (!checkDirectory(S))
             return null;
 
-        String sourceString = options.get("-source");
+        String sourceString = options.get(SOURCE);
         Source source = (sourceString != null)
             ? Source.lookup(sourceString)
             : Source.DEFAULT;
-        String targetString = options.get("-target");
+        String targetString = options.get(TARGET);
         Target target = (targetString != null)
             ? Target.lookup(targetString)
             : Target.DEFAULT;
@@ -285,7 +287,7 @@
         // phase this out with JSR 292 PFD
         if ("no".equals(options.get("allowTransitionalJSR292"))) {
             options.put("allowTransitionalJSR292", null);
-        } else if (target.hasInvokedynamic() && options.get("allowTransitionalJSR292") == null) {
+        } else if (target.hasInvokedynamic() && options.isUnset("allowTransitionalJSR292")) {
             options.put("allowTransitionalJSR292", "allowTransitionalJSR292");
         }
 
@@ -300,7 +302,7 @@
         return filenames.toList();
     }
     // where
-        private boolean checkDirectory(String optName) {
+        private boolean checkDirectory(OptionName optName) {
             String value = options.get(optName);
             if (value == null)
                 return true;
@@ -367,10 +369,10 @@
                     return EXIT_CMDERR;
                 } else if (files.isEmpty() && fileObjects.isEmpty() && classnames.isEmpty()) {
                     // it is allowed to compile nothing if just asking for help or version info
-                    if (options.get("-help") != null
-                        || options.get("-X") != null
-                        || options.get("-version") != null
-                        || options.get("-fullversion") != null)
+                    if (options.isSet(HELP)
+                        || options.isSet(X)
+                        || options.isSet(VERSION)
+                        || options.isSet(FULLVERSION))
                         return EXIT_OK;
                     error("err.no.source.files");
                     return EXIT_CMDERR;
@@ -382,7 +384,7 @@
                 return EXIT_SYSERR;
             }
 
-            boolean forceStdOut = options.get("stdout") != null;
+            boolean forceStdOut = options.isSet("stdout");
             if (forceStdOut) {
                 out.flush();
                 out = new PrintWriter(System.out, true);
@@ -391,7 +393,7 @@
             context.put(Log.outKey, out);
 
             // allow System property in following line as a Mustang legacy
-            boolean batchMode = (options.get("nonBatchMode") == null
+            boolean batchMode = (options.isUnset("nonBatchMode")
                         && System.getProperty("nonBatchMode") == null);
             if (batchMode)
                 CacheFSInfo.preRegister(context);
@@ -455,7 +457,7 @@
             // for buggy compiler error recovery by swallowing thrown
             // exceptions.
             if (comp == null || comp.errorCount() == 0 ||
-                options == null || options.get("dev") != null)
+                options == null || options.isSet("dev"))
                 bugMessage(ex);
             return EXIT_ABNORMAL;
         } finally {
@@ -478,7 +480,7 @@
      */
     void feMessage(Throwable ex) {
         Log.printLines(out, ex.getMessage());
-        if (ex.getCause() != null && options.get("dev") != null) {
+        if (ex.getCause() != null && options.isSet("dev")) {
             ex.getCause().printStackTrace(out);
         }
     }
--- a/langtools/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java	Wed Jul 05 17:24:21 2017 +0200
@@ -366,11 +366,11 @@
 //            }
 //        }
         int maxDepth = (recurse ? Integer.MAX_VALUE : 1);
-        Set<FileVisitOption> opts = EnumSet.of(DETECT_CYCLES, FOLLOW_LINKS);
+        Set<FileVisitOption> opts = EnumSet.of(FOLLOW_LINKS);
         Files.walkFileTree(packageDir, opts, maxDepth,
                 new SimpleFileVisitor<Path>() {
             @Override
-            public FileVisitResult preVisitDirectory(Path dir) {
+            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
                 if (SourceVersion.isIdentifier(dir.getName().toString())) // JSR 292?
                     return FileVisitResult.CONTINUE;
                 else
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/DocCommentScanner.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/DocCommentScanner.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,50 +42,17 @@
  */
 public class DocCommentScanner extends Scanner {
 
-    /** A factory for creating scanners. */
-    public static class Factory extends Scanner.Factory {
-
-        public static void preRegister(final Context context) {
-            context.put(scannerFactoryKey, new Context.Factory<Scanner.Factory>() {
-                public Factory make() {
-                    return new Factory(context);
-                }
-            });
-        }
-
-        /** Create a new scanner factory. */
-        protected Factory(Context context) {
-            super(context);
-        }
-
-        @Override
-        public Scanner newScanner(CharSequence input) {
-            if (input instanceof CharBuffer) {
-                return new DocCommentScanner(this, (CharBuffer)input);
-            } else {
-                char[] array = input.toString().toCharArray();
-                return newScanner(array, array.length);
-            }
-        }
-
-        @Override
-        public Scanner newScanner(char[] input, int inputLength) {
-            return new DocCommentScanner(this, input, inputLength);
-        }
-    }
-
-
     /** Create a scanner from the input buffer.  buffer must implement
      *  array() and compact(), and remaining() must be less than limit().
      */
-    protected DocCommentScanner(Factory fac, CharBuffer buffer) {
+    protected DocCommentScanner(ScannerFactory fac, CharBuffer buffer) {
         super(fac, buffer);
     }
 
     /** Create a scanner from the input array.  The array must have at
      *  least a single character of extra space.
      */
-    protected DocCommentScanner(Factory fac, char[] input, int inputLength) {
+    protected DocCommentScanner(ScannerFactory fac, char[] input, int inputLength) {
         super(fac, input, inputLength);
     }
 
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -2473,6 +2473,11 @@
                 defs.append(importDeclaration());
             } else {
                 JCTree def = typeDeclaration(mods);
+                if (keepDocComments && dc != null && docComments.get(def) == dc) {
+                    // If the first type declaration has consumed the first doc
+                    // comment, then don't use it for the top level comment as well.
+                    dc = null;
+                }
                 if (def instanceof JCExpressionStatement)
                     def = ((JCExpressionStatement)def).expr;
                 defs.append(def);
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/ParserFactory.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/ParserFactory.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -59,7 +59,7 @@
     final Source source;
     final Names names;
     final Options options;
-    final Scanner.Factory scannerFactory;
+    final ScannerFactory scannerFactory;
 
     protected ParserFactory(Context context) {
         super();
@@ -70,11 +70,11 @@
         this.keywords = Keywords.instance(context);
         this.source = Source.instance(context);
         this.options = Options.instance(context);
-        this.scannerFactory = Scanner.Factory.instance(context);
+        this.scannerFactory = ScannerFactory.instance(context);
     }
 
     public Parser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap) {
-        Lexer lexer = scannerFactory.newScanner(input);
+        Lexer lexer = scannerFactory.newScanner(input, keepDocComments);
         if (keepEndPos) {
             return new EndPosParser(this, lexer, keepDocComments, keepLineMap);
         } else {
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -47,48 +47,6 @@
 
     private static boolean scannerDebug = false;
 
-    /** A factory for creating scanners. */
-    public static class Factory {
-        /** The context key for the scanner factory. */
-        public static final Context.Key<Scanner.Factory> scannerFactoryKey =
-            new Context.Key<Scanner.Factory>();
-
-        /** Get the Factory instance for this context. */
-        public static Factory instance(Context context) {
-            Factory instance = context.get(scannerFactoryKey);
-            if (instance == null)
-                instance = new Factory(context);
-            return instance;
-        }
-
-        final Log log;
-        final Names names;
-        final Source source;
-        final Keywords keywords;
-
-        /** Create a new scanner factory. */
-        protected Factory(Context context) {
-            context.put(scannerFactoryKey, this);
-            this.log = Log.instance(context);
-            this.names = Names.instance(context);
-            this.source = Source.instance(context);
-            this.keywords = Keywords.instance(context);
-        }
-
-        public Scanner newScanner(CharSequence input) {
-            if (input instanceof CharBuffer) {
-                return new Scanner(this, (CharBuffer)input);
-            } else {
-                char[] array = input.toString().toCharArray();
-                return newScanner(array, array.length);
-            }
-        }
-
-        public Scanner newScanner(char[] input, int inputLength) {
-            return new Scanner(this, input, inputLength);
-        }
-    }
-
     /* Output variables; set by nextToken():
      */
 
@@ -177,7 +135,7 @@
     private final Keywords keywords;
 
     /** Common code for constructors. */
-    private Scanner(Factory fac) {
+    private Scanner(ScannerFactory fac) {
         log = fac.log;
         names = fac.names;
         keywords = fac.keywords;
@@ -201,7 +159,7 @@
     /** Create a scanner from the input buffer.  buffer must implement
      *  array() and compact(), and remaining() must be less than limit().
      */
-    protected Scanner(Factory fac, CharBuffer buffer) {
+    protected Scanner(ScannerFactory fac, CharBuffer buffer) {
         this(fac, JavacFileManager.toArray(buffer), buffer.limit());
     }
 
@@ -216,7 +174,7 @@
      * @param inputLength the size of the input.
      * Must be positive and less than or equal to input.length.
      */
-    protected Scanner(Factory fac, char[] input, int inputLength) {
+    protected Scanner(ScannerFactory fac, char[] input, int inputLength) {
         this(fac);
         eofPos = inputLength;
         if (inputLength == input.length) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/ScannerFactory.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.javac.parser;
+
+import java.nio.CharBuffer;
+
+import com.sun.tools.javac.code.Source;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.Names;
+
+
+/**
+ * A factory for creating scanners.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own
+ *  risk.  This code and its internal interfaces are subject to change
+ *  or deletion without notice.</b>
+ */
+public class ScannerFactory {
+    /** The context key for the scanner factory. */
+    public static final Context.Key<ScannerFactory> scannerFactoryKey =
+        new Context.Key<ScannerFactory>();
+
+    /** Get the Factory instance for this context. */
+    public static ScannerFactory instance(Context context) {
+        ScannerFactory instance = context.get(scannerFactoryKey);
+        if (instance == null)
+            instance = new ScannerFactory(context);
+        return instance;
+    }
+
+    final Log log;
+    final Names names;
+    final Source source;
+    final Keywords keywords;
+
+    /** Create a new scanner factory. */
+    protected ScannerFactory(Context context) {
+        context.put(scannerFactoryKey, this);
+        this.log = Log.instance(context);
+        this.names = Names.instance(context);
+        this.source = Source.instance(context);
+        this.keywords = Keywords.instance(context);
+    }
+
+    public Scanner newScanner(CharSequence input, boolean keepDocComments) {
+        if (input instanceof CharBuffer) {
+            CharBuffer buf = (CharBuffer) input;
+            if (keepDocComments)
+                return new DocCommentScanner(this, buf);
+            else
+                return new Scanner(this, buf);
+        } else {
+            char[] array = input.toString().toCharArray();
+            return newScanner(array, array.length, keepDocComments);
+        }
+    }
+
+    public Scanner newScanner(char[] input, int inputLength, boolean keepDocComments) {
+        if (keepDocComments)
+            return new DocCommentScanner(this, input, inputLength);
+        else
+            return new Scanner(this, input, inputLength);
+    }
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacFiler.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacFiler.java	Wed Jul 05 17:24:21 2017 +0200
@@ -25,14 +25,6 @@
 
 package com.sun.tools.javac.processing;
 
-import com.sun.tools.javac.util.*;
-import javax.annotation.processing.*;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.NestingKind;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.Element;
-import java.util.*;
-
 import java.io.Closeable;
 import java.io.FileNotFoundException;
 import java.io.InputStream;
@@ -43,14 +35,26 @@
 import java.io.FilterWriter;
 import java.io.PrintWriter;
 import java.io.IOException;
+import java.util.*;
 
-import javax.tools.*;
 import static java.util.Collections.*;
 
+import javax.annotation.processing.*;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.NestingKind;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.Element;
+import javax.tools.*;
 import javax.tools.JavaFileManager.Location;
+
 import static javax.tools.StandardLocation.SOURCE_OUTPUT;
 import static javax.tools.StandardLocation.CLASS_OUTPUT;
 
+import com.sun.tools.javac.code.Lint;
+import com.sun.tools.javac.util.*;
+
+import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
+
 /**
  * The FilerImplementation class must maintain a number of
  * constraints.  First, multiple attempts to open the same path within
@@ -366,7 +370,7 @@
         aggregateGeneratedSourceNames = new LinkedHashSet<String>();
         aggregateGeneratedClassNames  = new LinkedHashSet<String>();
 
-        lint = (Options.instance(context)).lint("processing");
+        lint = (Lint.instance(context)).isEnabled(PROCESSING);
     }
 
     public JavaFileObject createSourceFile(CharSequence name,
--- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -49,6 +49,7 @@
 import javax.tools.JavaFileObject;
 import javax.tools.DiagnosticListener;
 
+import com.sun.tools.javac.api.JavacTrees;
 import com.sun.source.util.AbstractTypeProcessor;
 import com.sun.source.util.TaskEvent;
 import com.sun.source.util.TaskListener;
@@ -78,6 +79,8 @@
 
 import static javax.tools.StandardLocation.*;
 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
+import static com.sun.tools.javac.main.OptionName.*;
+import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
 
 /**
  * Objects of this class hold and manage the state needed to support
@@ -159,15 +162,14 @@
         source = Source.instance(context);
         diags = JCDiagnostic.Factory.instance(context);
         options = Options.instance(context);
-        printProcessorInfo = options.get("-XprintProcessorInfo") != null;
-        printRounds = options.get("-XprintRounds") != null;
-        verbose = options.get("-verbose") != null;
-        lint = options.lint("processing");
-        procOnly = options.get("-proc:only") != null ||
-            options.get("-Xprint") != null;
-        fatalErrors = options.get("fatalEnterError") != null;
-        showResolveErrors = options.get("showResolveErrors") != null;
-        werror = options.get("-Werror") != null;
+        printProcessorInfo = options.isSet(XPRINTPROCESSORINFO);
+        printRounds = options.isSet(XPRINTROUNDS);
+        verbose = options.isSet(VERBOSE);
+        lint = Lint.instance(context).isEnabled(PROCESSING);
+        procOnly = options.isSet(PROC, "only") || options.isSet(XPRINT);
+        fatalErrors = options.isSet("fatalEnterError");
+        showResolveErrors = options.isSet("showResolveErrors");
+        werror = options.isSet(WERROR);
         platformAnnotations = initPlatformAnnotations();
         foundTypeProcessors = false;
 
@@ -199,7 +201,7 @@
         Log   log   = Log.instance(context);
         Iterator<? extends Processor> processorIterator;
 
-        if (options.get("-Xprint") != null) {
+        if (options.isSet(XPRINT)) {
             try {
                 Processor processor = PrintingProcessor.class.newInstance();
                 processorIterator = List.of(processor).iterator();
@@ -212,7 +214,7 @@
         } else if (processors != null) {
             processorIterator = processors.iterator();
         } else {
-            String processorNames = options.get("-processor");
+            String processorNames = options.get(PROCESSOR);
             JavaFileManager fileManager = context.get(JavaFileManager.class);
             try {
                 // If processorpath is not explicitly set, use the classpath.
@@ -263,7 +265,7 @@
                 ? standardFileManager.getLocation(ANNOTATION_PROCESSOR_PATH)
                 : standardFileManager.getLocation(CLASS_PATH);
 
-            if (needClassLoader(options.get("-processor"), workingPath) )
+            if (needClassLoader(options.get(PROCESSOR), workingPath) )
                 handleException(key, e);
 
         } else {
@@ -744,7 +746,7 @@
         psi.runContributingProcs(renv);
 
         // Debugging
-        if (options.get("displayFilerState") != null)
+        if (options.isSet("displayFilerState"))
             filer.displayState();
     }
 
@@ -1104,6 +1106,12 @@
                 task.updateContext(next);
             }
 
+            JavacTrees trees = context.get(JavacTrees.class);
+            if (trees != null) {
+                next.put(JavacTrees.class, trees);
+                trees.updateContext(next);
+            }
+
             context.clear();
             return next;
         }
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Wed Jul 05 17:24:21 2017 +0200
@@ -93,6 +93,8 @@
     required: {2}\n\
     found: {3}\n\
     reason: {6}
+compiler.err.cant.apply.symbols=\
+    no suitable {0} found for {1}({2})
 compiler.err.cant.assign.val.to.final.var=\
     cannot assign a value to final variable {0}
 compiler.err.cant.deref=\
@@ -1075,11 +1077,11 @@
     no unique maximal instance exists for type variable {0} with upper bounds {1}
 compiler.misc.no.unique.minimal.instance.exists=\
     no unique minimal instance exists for type variable {0} with lower bounds {1}
-compiler.misc.no.conforming.instance.exists=\
+compiler.misc.infer.no.conforming.instance.exists=\
     no instance(s) of type variable(s) {0} exist so that {1} conforms to {2}
-compiler.misc.no.conforming.assignment.exists=\
+compiler.misc.infer.no.conforming.assignment.exists=\
     no instance(s) of type variable(s) {0} exist so that argument type {1} conforms to formal parameter type {2}
-compiler.misc.arg.length.mismatch=\
+compiler.misc.infer.arg.length.mismatch=\
     cannot instantiate from arguments because actual and formal argument lists differ in length
 compiler.misc.inferred.do.not.conform.to.bounds=\
     inferred type does not conform to declared bound(s)\n\
@@ -1095,6 +1097,16 @@
     type argument {0} inferred for {1} is not allowed in this context
 compiler.misc.diamond.invalid.args=\
     type arguments {0} inferred for {1} are not allowed in this context
+
+compiler.misc.explicit.param.do.not.conform.to.bounds=\
+    explicit type argument {0} does not conform to declared bound(s) {1}
+
+compiler.misc.arg.length.mismatch=\
+    actual and formal argument lists differ in length
+compiler.misc.no.conforming.assignment.exists=\
+    actual argument {0} cannot be converted to {1} by method invocation conversion
+compiler.misc.varargs.argument.mismatch=\
+    argument type {0} does not conform to vararg element type {1}
 #####
 
 ## The first argument ({0}) is a "kindname".
@@ -1232,6 +1244,10 @@
 compiler.misc.non.denotable.type=\
     Non-denotable type {0} not allowed here
 
+compiler.misc.inapplicable.method=\
+    {0} {1}.{2} is not applicable\n\
+    ({3})
+
 ########################################
 # Diagnostics for language feature changes
 ########################################
--- a/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/BasicDiagnosticFormatter.java	Wed Jul 05 17:24:21 2017 +0200
@@ -65,8 +65,6 @@
  */
 public class BasicDiagnosticFormatter extends AbstractDiagnosticFormatter {
 
-    protected int currentIndentation = 0;
-
     /**
      * Create a basic formatter based on the supplied options.
      *
@@ -107,33 +105,28 @@
     }
 
     public String formatMessage(JCDiagnostic d, Locale l) {
-        int prevIndentation = currentIndentation;
-        try {
-            StringBuilder buf = new StringBuilder();
-            Collection<String> args = formatArguments(d, l);
-            String msg = localize(l, d.getCode(), args.toArray());
-            String[] lines = msg.split("\n");
-            if (getConfiguration().getVisible().contains(DiagnosticPart.SUMMARY)) {
-                currentIndentation += getConfiguration().getIndentation(DiagnosticPart.SUMMARY);
-                buf.append(indent(lines[0], currentIndentation)); //summary
+        int currentIndentation = 0;
+        StringBuilder buf = new StringBuilder();
+        Collection<String> args = formatArguments(d, l);
+        String msg = localize(l, d.getCode(), args.toArray());
+        String[] lines = msg.split("\n");
+        if (getConfiguration().getVisible().contains(DiagnosticPart.SUMMARY)) {
+            currentIndentation += getConfiguration().getIndentation(DiagnosticPart.SUMMARY);
+            buf.append(indent(lines[0], currentIndentation)); //summary
+        }
+        if (lines.length > 1 && getConfiguration().getVisible().contains(DiagnosticPart.DETAILS)) {
+            currentIndentation += getConfiguration().getIndentation(DiagnosticPart.DETAILS);
+            for (int i = 1;i < lines.length; i++) {
+                buf.append("\n" + indent(lines[i], currentIndentation));
             }
-            if (lines.length > 1 && getConfiguration().getVisible().contains(DiagnosticPart.DETAILS)) {
-                currentIndentation += getConfiguration().getIndentation(DiagnosticPart.DETAILS);
-                for (int i = 1;i < lines.length; i++) {
-                    buf.append("\n" + indent(lines[i], currentIndentation));
-                }
-            }
-            if (d.isMultiline() && getConfiguration().getVisible().contains(DiagnosticPart.SUBDIAGNOSTICS)) {
-                currentIndentation += getConfiguration().getIndentation(DiagnosticPart.SUBDIAGNOSTICS);
+        }
+        if (d.isMultiline() && getConfiguration().getVisible().contains(DiagnosticPart.SUBDIAGNOSTICS)) {
+            currentIndentation += getConfiguration().getIndentation(DiagnosticPart.SUBDIAGNOSTICS);
                 for (String sub : formatSubdiagnostics(d, l)) {
-                    buf.append("\n" + sub);
-                }
+                    buf.append("\n" + indent(sub, currentIndentation));
             }
-            return buf.toString();
         }
-        finally {
-            currentIndentation = prevIndentation;
-        }
+        return buf.toString();
     }
 
     protected String addSourceLineIfNeeded(JCDiagnostic d, String msg) {
--- a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java	Wed Jul 05 17:24:21 2017 +0200
@@ -35,11 +35,14 @@
 import javax.tools.DiagnosticListener;
 import javax.tools.JavaFileObject;
 
+import com.sun.tools.javac.api.DiagnosticFormatter;
+import com.sun.tools.javac.main.OptionName;
 import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.api.DiagnosticFormatter;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
 
+import static com.sun.tools.javac.main.OptionName.*;
+
 /** A class for error logs. Reports errors and warnings, and
  *  keeps track of error numbers and positions.
  *
@@ -129,14 +132,14 @@
         this.noticeWriter = noticeWriter;
 
         Options options = Options.instance(context);
-        this.dumpOnError = options.get("-doe") != null;
-        this.promptOnError = options.get("-prompt") != null;
-        this.emitWarnings = options.get("-Xlint:none") == null;
-        this.suppressNotes = options.get("suppressNotes") != null;
-        this.MaxErrors = getIntOption(options, "-Xmaxerrs", getDefaultMaxErrors());
-        this.MaxWarnings = getIntOption(options, "-Xmaxwarns", getDefaultMaxWarnings());
+        this.dumpOnError = options.isSet(DOE);
+        this.promptOnError = options.isSet(PROMPT);
+        this.emitWarnings = options.isUnset(XLINT_CUSTOM, "none");
+        this.suppressNotes = options.isSet("suppressNotes");
+        this.MaxErrors = getIntOption(options, XMAXERRS, getDefaultMaxErrors());
+        this.MaxWarnings = getIntOption(options, XMAXWARNS, getDefaultMaxWarnings());
 
-        boolean rawDiagnostics = options.get("rawDiagnostics") != null;
+        boolean rawDiagnostics = options.isSet("rawDiagnostics");
         messages = JavacMessages.instance(context);
         this.diagFormatter = rawDiagnostics ? new RawDiagnosticFormatter(options) :
                                               new BasicDiagnosticFormatter(options, messages);
@@ -150,7 +153,7 @@
             expectDiagKeys = new HashSet<String>(Arrays.asList(ek.split(", *")));
     }
     // where
-        private int getIntOption(Options options, String optionName, int defaultValue) {
+        private int getIntOption(Options options, OptionName optionName, int defaultValue) {
             String s = options.get(optionName);
             try {
                 if (s != null) {
--- a/langtools/src/share/classes/com/sun/tools/javac/util/Names.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/Names.java	Wed Jul 05 17:24:21 2017 +0200
@@ -271,7 +271,7 @@
     }
 
     protected Name.Table createTable(Options options) {
-        boolean useUnsharedTable = options.get("useUnsharedTable") != null;
+        boolean useUnsharedTable = options.isSet("useUnsharedTable");
         if (useUnsharedTable)
             return new UnsharedNameTable(this);
         else
--- a/langtools/src/share/classes/com/sun/tools/javac/util/Options.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/Options.java	Wed Jul 05 17:24:21 2017 +0200
@@ -25,8 +25,9 @@
 
 package com.sun.tools.javac.util;
 
+import java.util.*;
 import com.sun.tools.javac.main.OptionName;
-import java.util.*;
+import static com.sun.tools.javac.main.OptionName.*;
 
 /** A table of all command-line options.
  *  If an option has an argument, the option name is mapped to the argument.
@@ -60,14 +61,62 @@
         context.put(optionsKey, this);
     }
 
+    /**
+     * Get the value for an undocumented option.
+     */
     public String get(String name) {
         return values.get(name);
     }
 
+    /**
+     * Get the value for an option.
+     */
     public String get(OptionName name) {
         return values.get(name.optionName);
     }
 
+    /**
+     * Check if the value for an undocumented option has been set.
+     */
+    public boolean isSet(String name) {
+        return (values.get(name) != null);
+    }
+
+    /**
+     * Check if the value for an option has been set.
+     */
+    public boolean isSet(OptionName name) {
+        return (values.get(name.optionName) != null);
+    }
+
+    /**
+     * Check if the value for a choice option has been set to a specific value.
+     */
+    public boolean isSet(OptionName name, String value) {
+        return (values.get(name.optionName + value) != null);
+    }
+
+    /**
+     * Check if the value for an undocumented option has not been set.
+     */
+    public boolean isUnset(String name) {
+        return (values.get(name) == null);
+    }
+
+    /**
+     * Check if the value for an option has not been set.
+     */
+    public boolean isUnset(OptionName name) {
+        return (values.get(name.optionName) == null);
+    }
+
+    /**
+     * Check if the value for a choice option has not been set to a specific value.
+     */
+    public boolean isUnset(OptionName name, String value) {
+        return (values.get(name.optionName + value) == null);
+    }
+
     public void put(String name, String value) {
         values.put(name, value);
     }
@@ -92,16 +141,14 @@
         return values.size();
     }
 
-    static final String LINT = "-Xlint";
-
     /** Check for a lint suboption. */
     public boolean lint(String s) {
         // return true if either the specific option is enabled, or
         // they are all enabled without the specific one being
         // disabled
         return
-            get(LINT + ":" + s)!=null ||
-            (get(LINT)!=null || get(LINT + ":all")!=null) &&
-                get(LINT+":-"+s)==null;
+            isSet(XLINT_CUSTOM, s) ||
+            (isSet(XLINT) || isSet(XLINT_CUSTOM, "all")) &&
+                isUnset(XLINT_CUSTOM, "-" + s);
     }
 }
--- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -107,9 +107,6 @@
             // force the use of Messager as a Log
             messager = Messager.instance0(context);
 
-            // force the use of the scanner that captures Javadoc comments
-            DocCommentScanner.Factory.preRegister(context);
-
             return new JavadocTool(context);
         } catch (CompletionFailure ex) {
             messager.error(Position.NOPOS, ex.getMessage());
--- a/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -526,15 +526,17 @@
     }
 
     private void showVersion(boolean full) {
-        log.println(version(full ? "full" : "release"));
+        log.println(version(full));
     }
 
     private static final String versionRBName = "com.sun.tools.javah.resources.version";
     private static ResourceBundle versionRB;
 
-    private String version(String key) {
-        // key=version:  mm.nn.oo[-milestone]
-        // key=full:     mm.mm.oo[-milestone]-build
+    private String version(boolean full) {
+        String msgKey = (full ? "javah.fullVersion" : "javah.version");
+        String versionKey = (full ? "full" : "release");
+        // versionKey=product:  mm.nn.oo[-milestone]
+        // versionKey=full:     mm.mm.oo[-milestone]-build
         if (versionRB == null) {
             try {
                 versionRB = ResourceBundle.getBundle(versionRBName);
@@ -543,7 +545,7 @@
             }
         }
         try {
-            return versionRB.getString(key);
+            return getMessage(msgKey, "javah", versionRB.getString(versionKey));
         }
         catch (MissingResourceException e) {
             return getMessage("version.unknown", System.getProperty("java.version"));
--- a/langtools/src/share/classes/com/sun/tools/javah/resources/l10n.properties	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javah/resources/l10n.properties	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -113,7 +113,8 @@
 #
 # Version string.
 #
-javah.version=javah version "{0}"
+javah.version={0} version "{1}"
+javah.fullVersion={0} full version "{1}"
 
 #
 # These should have better diagnostics.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javah/resources/version.properties-template	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,28 @@
+#
+# 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.  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=$(JDK_VERSION)
+full=$(FULL_VERSION)
+release=$(RELEASE)
--- a/langtools/test/tools/javac/6302184/T6302184.out	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/6302184/T6302184.out	Wed Jul 05 17:24:21 2017 +0200
@@ -1,4 +1,7 @@
 
+/**
+ * This is a test that uses ISO 8859 encoding.
+ */
 class T6302184 {
     
     T6302184() {
--- a/langtools/test/tools/javac/6304921/TestLog.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/6304921/TestLog.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,7 +35,6 @@
 import com.sun.tools.javac.file.JavacFileManager;
 import com.sun.tools.javac.parser.Parser;
 import com.sun.tools.javac.parser.ParserFactory;
-import com.sun.tools.javac.parser.Scanner;
 import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.tree.TreeScanner;
 import com.sun.tools.javac.util.Context;
@@ -60,7 +59,6 @@
         log.multipleErrors = true;
 
         JavacFileManager.preRegister(context);
-        Scanner.Factory sfac = Scanner.Factory.instance(context);
         ParserFactory pfac = ParserFactory.instance(context);
 
         final String text =
--- a/langtools/test/tools/javac/6758789/T6758789a.out	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/6758789/T6758789a.out	Wed Jul 05 17:24:21 2017 +0200
@@ -1,3 +1,3 @@
-T6758789a.java:14:9: compiler.err.cant.apply.symbol: kindname.method, m1, compiler.misc.no.args, int, kindname.class, T6758789a, null
-T6758789a.java:15:9: compiler.err.cant.apply.symbol: kindname.method, m2, int, compiler.misc.no.args, kindname.class, T6758789a, null
+T6758789a.java:14:9: compiler.err.cant.apply.symbol.1: kindname.method, m1, compiler.misc.no.args, int, kindname.class, T6758789a, (compiler.misc.arg.length.mismatch)
+T6758789a.java:15:9: compiler.err.cant.apply.symbol.1: kindname.method, m2, int, compiler.misc.no.args, kindname.class, T6758789a, (compiler.misc.arg.length.mismatch)
 2 errors
--- a/langtools/test/tools/javac/6840059/T6840059.out	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/6840059/T6840059.out	Wed Jul 05 17:24:21 2017 +0200
@@ -1,3 +1,3 @@
-T6840059.java:15:9: compiler.err.cant.apply.symbol: kindname.constructor, T6840059, java.lang.Integer, java.lang.String, kindname.class, T6840059, null
-T6840059.java:15:25: compiler.err.cant.apply.symbol: kindname.constructor, T6840059, java.lang.Integer, compiler.misc.no.args, kindname.class, T6840059, null
+T6840059.java:15:9: compiler.err.cant.apply.symbol.1: kindname.constructor, T6840059, java.lang.Integer, java.lang.String, kindname.class, T6840059, (compiler.misc.no.conforming.assignment.exists: java.lang.String, java.lang.Integer)
+T6840059.java:15:25: compiler.err.cant.apply.symbol.1: kindname.constructor, T6840059, java.lang.Integer, compiler.misc.no.args, kindname.class, T6840059, (compiler.misc.arg.length.mismatch)
 2 errors
--- a/langtools/test/tools/javac/6857948/T6857948.out	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/6857948/T6857948.out	Wed Jul 05 17:24:21 2017 +0200
@@ -1,3 +1,3 @@
 T6857948.java:16:32: compiler.err.cant.resolve.location.args: kindname.method, nosuchfunction, , , kindname.class, Test
-T6857948.java:16:50: compiler.err.cant.apply.symbol: kindname.constructor, Foo, java.lang.String, compiler.misc.no.args, kindname.class, Foo, null
+T6857948.java:16:50: compiler.err.cant.apply.symbol.1: kindname.constructor, Foo, java.lang.String, compiler.misc.no.args, kindname.class, Foo, (compiler.misc.arg.length.mismatch)
 2 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6863465/T6863465a.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,14 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug     6863465
+ * @summary javac doesn't detect circular subclass dependencies via qualified names
+ * @author  Maurizio Cimadamore
+ * @compile/fail/ref=T6863465a.out -XDrawDiagnostics T6863465a.java
+ */
+
+class T6863465a {
+    static class a { static interface b {} }
+    static class c extends a implements z.y {}
+    static class x { static interface y {} }
+    static class z extends x implements c.b {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6863465/T6863465a.out	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,2 @@
+T6863465a.java:11:12: compiler.err.cyclic.inheritance: T6863465a.c
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6863465/T6863465b.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,14 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug     6863465
+ * @summary javac doesn't detect circular subclass dependencies via qualified names
+ * @author  Maurizio Cimadamore
+ * @compile/fail/ref=T6863465b.out -XDrawDiagnostics T6863465b.java
+ */
+
+class T6863465b {
+    static class a { static interface b { static interface d {} } }
+    static class c extends a implements z.y, z.d {}
+    static class x { static interface y {} }
+    static class z extends x implements c.b {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6863465/T6863465b.out	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,2 @@
+T6863465b.java:11:12: compiler.err.cyclic.inheritance: T6863465b.c
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6863465/T6863465c.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,14 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug     6863465
+ * @summary javac doesn't detect circular subclass dependencies via qualified names
+ * @author  Maurizio Cimadamore
+ * @compile/fail/ref=T6863465c.out -XDrawDiagnostics T6863465c.java
+ */
+
+class T6863465c {
+    static class x { static interface y {} }
+    static class z extends x implements c.b {}
+    static class a { static interface b { static interface d {} } }
+    static class c extends a implements z.y, z.d {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6863465/T6863465c.out	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,3 @@
+T6863465c.java:13:47: compiler.err.cant.resolve.location: kindname.class, d, , , kindname.class, T6863465c.z
+T6863465c.java:11:12: compiler.err.cyclic.inheritance: T6863465c.z
+2 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6863465/T6863465d.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,14 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug     6863465
+ * @summary javac doesn't detect circular subclass dependencies via qualified names
+ * @author  Maurizio Cimadamore
+ * @compile/fail/ref=T6863465d.out -XDrawDiagnostics T6863465d.java
+ */
+
+class T6863465d {
+    static class a { static interface b { static interface d {} } }
+    static class c extends a implements z.y, z.d {}
+    static class x { static interface y { static interface w {} } }
+    static class z extends x implements c.b, c.w {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6863465/T6863465d.out	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,3 @@
+T6863465d.java:13:47: compiler.err.cant.resolve.location: kindname.class, w, , , kindname.class, T6863465d.c
+T6863465d.java:11:12: compiler.err.cyclic.inheritance: T6863465d.c
+2 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6863465/TestCircularClassfile.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along 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 6863465
+ * @summary  javac doesn't detect circular subclass dependencies via qualified names
+ * @run main TestCircularClassfile
+ */
+
+import java.io.*;
+import java.net.URI;
+import java.util.Arrays;
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticListener;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.ToolProvider;
+
+import com.sun.source.util.JavacTask;
+import java.util.EnumSet;
+
+public class TestCircularClassfile {
+
+    enum ClassName {
+        A("A"),
+        B("B"),
+        C("C"),
+        OBJECT("Object");
+
+        String name;
+
+        ClassName(String name) {
+            this.name = name;
+        }
+    }
+
+    static class JavaSource extends SimpleJavaFileObject {
+
+        final static String sourceStub = "class #C extends #S {}";
+
+        String source;
+
+        public JavaSource(ClassName clazz, ClassName sup) {
+            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+            source = sourceStub.replace("#C", clazz.name).replace("#S", sup.name);
+        }
+
+        @Override
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return source;
+        }
+    }
+
+    public static void main(String... args) throws Exception {
+        int count = 0;
+        for (ClassName clazz : EnumSet.of(ClassName.A, ClassName.B, ClassName.C)) {
+            for (ClassName sup : EnumSet.of(ClassName.A, ClassName.B, ClassName.C)) {
+                if (sup.ordinal() < clazz.ordinal()) continue;
+                check("sub_"+count++, clazz, sup);
+            }
+        }
+    }
+
+    static JavaSource[] initialSources = new JavaSource[] {
+            new JavaSource(ClassName.A, ClassName.OBJECT),
+            new JavaSource(ClassName.B, ClassName.A),
+            new JavaSource(ClassName.C, ClassName.B)
+        };
+
+    static String workDir = System.getProperty("user.dir");
+
+    static void check(String destPath, ClassName clazz, ClassName sup) throws Exception {
+        File destDir = new File(workDir, destPath); destDir.mkdir();
+        final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
+        JavacTask ct = (JavacTask)tool.getTask(null, null, null,
+                Arrays.asList("-d", destPath), null, Arrays.asList(initialSources));
+        ct.generate();
+        File fileToRemove = new File(destPath, clazz.name + ".class");
+        fileToRemove.delete();
+        JavaSource newSource = new JavaSource(clazz, sup);
+        DiagnosticChecker checker = new DiagnosticChecker();
+        ct = (JavacTask)tool.getTask(null, null, checker,
+                Arrays.asList("-cp", destPath), null, Arrays.asList(newSource));
+        ct.analyze();
+        if (!checker.errorFound) {
+            throw new AssertionError(newSource.source);
+        }
+    }
+
+    static class DiagnosticChecker implements DiagnosticListener<JavaFileObject> {
+
+        boolean errorFound = false;
+
+        public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+            if (diagnostic.getKind() == Diagnostic.Kind.ERROR &&
+                    diagnostic.getCode().equals("compiler.err.cyclic.inheritance")) {
+                errorFound = true;
+            }
+        }
+    }
+}
--- a/langtools/test/tools/javac/CyclicInheritance.out	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/CyclicInheritance.out	Wed Jul 05 17:24:21 2017 +0200
@@ -4,6 +4,6 @@
 CyclicInheritance.java:22:1: compiler.err.cyclic.inheritance: I11
 CyclicInheritance.java:27:1: compiler.err.cyclic.inheritance: C211
 CyclicInheritance.java:31:1: compiler.err.cyclic.inheritance: C212
-CyclicInheritance.java:36:27: compiler.err.report.access: C221.I, private, C221
-CyclicInheritance.java:40:24: compiler.err.report.access: C222.C, private, C222
+CyclicInheritance.java:36:1: compiler.err.cyclic.inheritance: C221
+CyclicInheritance.java:40:1: compiler.err.cyclic.inheritance: C222
 8 errors
--- a/langtools/test/tools/javac/Diagnostics/6722234/T6722234a_1.out	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/Diagnostics/6722234/T6722234a_1.out	Wed Jul 05 17:24:21 2017 +0200
@@ -1,2 +1,2 @@
-T6722234a.java:12:9: compiler.err.cant.apply.symbol: kindname.method, m, compiler.misc.type.var: T, 1, compiler.misc.type.var: T, 2, kindname.class, T6722234a<compiler.misc.type.var: T, 1>, null
+T6722234a.java:12:9: compiler.err.cant.apply.symbol.1: kindname.method, m, compiler.misc.type.var: T, 1, compiler.misc.type.var: T, 2, kindname.class, T6722234a<compiler.misc.type.var: T, 1>, (compiler.misc.no.conforming.assignment.exists: compiler.misc.type.var: T, 2, compiler.misc.type.var: T, 1)
 1 error
--- a/langtools/test/tools/javac/Diagnostics/6722234/T6722234a_2.out	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/Diagnostics/6722234/T6722234a_2.out	Wed Jul 05 17:24:21 2017 +0200
@@ -1,3 +1,3 @@
-T6722234a.java:12:9: compiler.err.cant.apply.symbol: kindname.method, m, compiler.misc.type.var: T, 1, compiler.misc.type.var: T, 2, kindname.class, T6722234a<compiler.misc.type.var: T, 1>, null
+T6722234a.java:12:9: compiler.err.cant.apply.symbol.1: kindname.method, m, compiler.misc.type.var: T, 1, compiler.misc.type.var: T, 2, kindname.class, T6722234a<compiler.misc.type.var: T, 1>, (compiler.misc.no.conforming.assignment.exists: compiler.misc.type.var: T, 2, compiler.misc.type.var: T, 1)
 - compiler.misc.where.description.typevar.1: compiler.misc.type.var: T, 1,compiler.misc.type.var: T, 2,{(compiler.misc.where.typevar: compiler.misc.type.var: T, 1, java.lang.String, kindname.class, T6722234a),(compiler.misc.where.typevar: compiler.misc.type.var: T, 2, java.lang.Integer, kindname.method, <compiler.misc.type.var: T, 2>test(compiler.misc.type.var: T, 2))}
 1 error
--- a/langtools/test/tools/javac/Diagnostics/6722234/T6722234b_1.out	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/Diagnostics/6722234/T6722234b_1.out	Wed Jul 05 17:24:21 2017 +0200
@@ -1,2 +1,2 @@
-T6722234b.java:16:9: compiler.err.cant.apply.symbol: kindname.method, m, List<T>,List<T>, List<compiler.misc.type.captureof: 1, ? extends T6722234b>,List<compiler.misc.type.captureof: 2, ? extends T6722234b>, kindname.class, T6722234b, null
+T6722234b.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, m, List<T>,List<T>, List<compiler.misc.type.captureof: 1, ? extends T6722234b>,List<compiler.misc.type.captureof: 2, ? extends T6722234b>, kindname.class, T6722234b, (compiler.misc.infer.no.conforming.assignment.exists: T, List<compiler.misc.type.captureof: 2, ? extends T6722234b>, List<T>)
 1 error
--- a/langtools/test/tools/javac/Diagnostics/6722234/T6722234b_2.out	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/Diagnostics/6722234/T6722234b_2.out	Wed Jul 05 17:24:21 2017 +0200
@@ -1,4 +1,4 @@
-T6722234b.java:16:9: compiler.err.cant.apply.symbol: kindname.method, m, List<T>,List<T>, List<compiler.misc.captured.type: 1>,List<compiler.misc.captured.type: 2>, kindname.class, T6722234b, null
+T6722234b.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, m, List<T>,List<T>, List<compiler.misc.captured.type: 1>,List<compiler.misc.captured.type: 2>, kindname.class, T6722234b, (compiler.misc.infer.no.conforming.assignment.exists: T, List<compiler.misc.captured.type: 2>, List<T>)
 - compiler.misc.where.description.typevar: T,{(compiler.misc.where.typevar: T, Object, kindname.method, <T>m(List<T>,List<T>))}
 - compiler.misc.where.description.captured.1: compiler.misc.captured.type: 1,compiler.misc.captured.type: 2,{(compiler.misc.where.captured.1: compiler.misc.captured.type: 1, T6722234b, compiler.misc.type.null, ? extends T6722234b),(compiler.misc.where.captured.1: compiler.misc.captured.type: 2, T6722234b, compiler.misc.type.null, ? extends T6722234b)}
 1 error
--- a/langtools/test/tools/javac/Diagnostics/6722234/T6722234c.out	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/Diagnostics/6722234/T6722234c.out	Wed Jul 05 17:24:21 2017 +0200
@@ -1,2 +1,2 @@
-T6722234c.java:14:9: compiler.err.cant.apply.symbol: kindname.method, m, T6722234c.String, java.lang.String, kindname.class, T6722234c, null
+T6722234c.java:14:9: compiler.err.cant.apply.symbol.1: kindname.method, m, T6722234c.String, java.lang.String, kindname.class, T6722234c, (compiler.misc.infer.no.conforming.assignment.exists: T, java.lang.String, T6722234c.String)
 1 error
--- a/langtools/test/tools/javac/Diagnostics/6799605/T6799605.out	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/Diagnostics/6799605/T6799605.out	Wed Jul 05 17:24:21 2017 +0200
@@ -1,4 +1,4 @@
-T6799605.java:17:9: compiler.err.cant.resolve.location.args: kindname.method, m, , T6799605<compiler.misc.type.captureof: 1, ?>, kindname.class, T6799605<X>
-T6799605.java:18:9: compiler.err.cant.resolve.location.args: kindname.method, m, , T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>, kindname.class, T6799605<X>
-T6799605.java:19:9: compiler.err.cant.resolve.location.args: kindname.method, m, , T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,T6799605<compiler.misc.type.captureof: 3, ?>, kindname.class, T6799605<X>
+T6799605.java:17:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.inferred.do.not.conform.to.bounds: compiler.misc.type.captureof: 1, ?, T6799605<compiler.misc.type.captureof: 1, ?>))}
+T6799605.java:18:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.no.conforming.assignment.exists: T, T6799605<compiler.misc.type.captureof: 2, ?>, T6799605<T>)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.infer.arg.length.mismatch))}
+T6799605.java:19:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,T6799605<compiler.misc.type.captureof: 3, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.no.conforming.assignment.exists: T, T6799605<compiler.misc.type.captureof: 2, ?>, T6799605<T>)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.infer.arg.length.mismatch))}
 3 errors
--- a/langtools/test/tools/javac/Diagnostics/6862608/T6862608a.out	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/Diagnostics/6862608/T6862608a.out	Wed Jul 05 17:24:21 2017 +0200
@@ -1,3 +1,3 @@
-T6862608a.java:19:41: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.conforming.instance.exists: T, java.util.Comparator<T>, java.util.Comparator<java.lang.String>)), <T>java.util.Comparator<T>, java.util.Comparator<java.lang.String>
+T6862608a.java:19:41: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: T, java.util.Comparator<T>, java.util.Comparator<java.lang.String>)), <T>java.util.Comparator<T>, java.util.Comparator<java.lang.String>
 - compiler.misc.where.description.typevar: T,{(compiler.misc.where.typevar: T, java.lang.Object, kindname.method, <T>compound(java.lang.Iterable<? extends java.util.Comparator<? super T>>))}
 1 error
--- a/langtools/test/tools/javac/Diagnostics/6862608/T6862608b.out	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/Diagnostics/6862608/T6862608b.out	Wed Jul 05 17:24:21 2017 +0200
@@ -1,3 +1,3 @@
-T6862608b.java:11:7: compiler.err.cant.apply.symbol: kindname.method, test, compiler.misc.type.var: T, 1, compiler.misc.type.var: T, 2, kindname.class, T66862608b<compiler.misc.type.var: T, 1,compiler.misc.type.var: S, 2>, null
+T6862608b.java:11:7: compiler.err.cant.apply.symbol.1: kindname.method, test, compiler.misc.type.var: T, 1, compiler.misc.type.var: T, 2, kindname.class, T66862608b<compiler.misc.type.var: T, 1,compiler.misc.type.var: S, 2>, (compiler.misc.no.conforming.assignment.exists: compiler.misc.type.var: T, 2, compiler.misc.type.var: T, 1)
 - compiler.misc.where.description.typevar.1: compiler.misc.type.var: T, 1,compiler.misc.type.var: T, 2,compiler.misc.type.var: S, 1,compiler.misc.type.var: S, 2,{(compiler.misc.where.typevar: compiler.misc.type.var: T, 1, java.lang.String, kindname.class, T66862608b),(compiler.misc.where.typevar: compiler.misc.type.var: T, 2, compiler.misc.type.var: S, 1, kindname.method, <compiler.misc.type.var: S, 1,compiler.misc.type.var: T, 2>foo(compiler.misc.type.var: T, 2)),(compiler.misc.where.typevar: compiler.misc.type.var: S, 1, java.lang.Object, kindname.method, <compiler.misc.type.var: S, 1,compiler.misc.type.var: T, 2>foo(compiler.misc.type.var: T, 2)),(compiler.misc.where.typevar: compiler.misc.type.var: S, 2, java.lang.Object, kindname.class, T66862608b)}
 1 error
--- a/langtools/test/tools/javac/NameCollision.out	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/NameCollision.out	Wed Jul 05 17:24:21 2017 +0200
@@ -1,2 +1,3 @@
 NameCollision.java:13:31: compiler.err.intf.expected.here
-1 error
+NameCollision.java:13:5: compiler.err.cyclic.inheritance: NameCollision.Runnable
+2 errors
--- a/langtools/test/tools/javac/T6326754.out	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/T6326754.out	Wed Jul 05 17:24:21 2017 +0200
@@ -1,7 +1,7 @@
 T6326754.java:44:12: compiler.err.name.clash.same.erasure: TestConstructor(T), TestConstructor(K)
 T6326754.java:52:17: compiler.err.name.clash.same.erasure: setT(K), setT(T)
 T6326754.java:64:18: compiler.err.prob.found.req: (compiler.misc.incompatible.types), T, T
-T6326754.java:70:11: compiler.err.cant.apply.symbol: kindname.method, setT, java.lang.Object, compiler.misc.no.args, kindname.class, TestC<T>, null
+T6326754.java:70:11: compiler.err.cant.apply.symbol.1: kindname.method, setT, java.lang.Object, compiler.misc.no.args, kindname.class, TestC<T>, (compiler.misc.arg.length.mismatch)
 - compiler.note.unchecked.filename: T6326754.java
 - compiler.note.unchecked.recompile
 4 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T6587674.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along 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 6587674
+ * @summary NoClassdefFound when anonymously extending a class.
+ */
+
+import java.util.Vector;
+
+public class T6587674 {
+    private static final Vector<String> list =
+        true ? null : new Vector<String>() { };
+
+    public static void main(String[] args) {
+        System.out.println("T6587674 runs fine!");
+    }
+}
--- a/langtools/test/tools/javac/api/TestJavacTaskScanner.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/api/TestJavacTaskScanner.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,8 +31,8 @@
  */
 
 import com.sun.tools.javac.api.JavacTaskImpl;
-import com.sun.tools.javac.parser.*; // XXX
-import com.sun.tools.javac.util.*; // XXX
+import com.sun.tools.javac.parser.*;
+import com.sun.tools.javac.util.*;
 import java.io.*;
 import java.net.*;
 import java.nio.*;
@@ -65,7 +65,7 @@
             fm.getJavaFileObjects(new File[] {file});
         StandardJavaFileManager fm = getLocalFileManager(tool, null, null);
         task = (JavacTaskImpl)tool.getTask(null, fm, null, null, null, compilationUnits);
-        task.getContext().put(Scanner.Factory.scannerFactoryKey,
+        task.getContext().put(ScannerFactory.scannerFactoryKey,
                 new MyScanner.Factory(task.getContext(), this));
         elements = task.getElements();
         types = task.getTypes();
@@ -170,34 +170,36 @@
 
 class MyScanner extends Scanner {
 
-    public static class Factory extends Scanner.Factory {
+    public static class Factory extends ScannerFactory {
         public Factory(Context context, TestJavacTaskScanner test) {
             super(context);
             this.test = test;
         }
 
         @Override
-        public Scanner newScanner(CharSequence input) {
+        public Scanner newScanner(CharSequence input, boolean keepDocComments) {
+            assert !keepDocComments;
             if (input instanceof CharBuffer) {
                 return new MyScanner(this, (CharBuffer)input, test);
             } else {
                 char[] array = input.toString().toCharArray();
-                return newScanner(array, array.length);
+                return newScanner(array, array.length, keepDocComments);
             }
         }
 
         @Override
-        public Scanner newScanner(char[] input, int inputLength) {
+        public Scanner newScanner(char[] input, int inputLength, boolean keepDocComments) {
+            assert !keepDocComments;
             return new MyScanner(this, input, inputLength, test);
         }
 
         private TestJavacTaskScanner test;
     }
-    protected MyScanner(Factory fac, CharBuffer buffer, TestJavacTaskScanner test) {
+    protected MyScanner(ScannerFactory fac, CharBuffer buffer, TestJavacTaskScanner test) {
         super(fac, buffer);
         this.test = test;
     }
-    protected MyScanner(Factory fac, char[] input, int inputLength, TestJavacTaskScanner test) {
+    protected MyScanner(ScannerFactory fac, char[] input, int inputLength, TestJavacTaskScanner test) {
         super(fac, input, inputLength);
         this.test = test;
     }
--- a/langtools/test/tools/javac/diags/Example.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/diags/Example.java	Wed Jul 05 17:24:21 2017 +0200
@@ -401,7 +401,7 @@
                 }
             }
             for (JCDiagnostic sd: d.getSubdiagnostics())
-                scanForKeys(d, keys);
+                scanForKeys(sd, keys);
         }
     }
 
--- a/langtools/test/tools/javac/diags/examples.not-yet.txt	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/diags/examples.not-yet.txt	Wed Jul 05 17:24:21 2017 +0200
@@ -3,7 +3,7 @@
 compiler.err.annotation.value.not.allowable.type        # cannot happen: precluded by complete type-specific tests
 compiler.err.assignment.from.super-bound                # DEAD
 compiler.err.assignment.to.extends-bound                # DEAD
-compiler.err.cant.apply.symbol.1
+compiler.err.cant.apply.symbol
 compiler.err.cant.read.file                             # (apt.JavaCompiler?)
 compiler.err.cant.select.static.class.from.param.type
 compiler.err.illegal.char.for.encoding
@@ -43,7 +43,6 @@
 compiler.err.unexpected.type
 compiler.err.unknown.enum.constant                      # in bad class file
 compiler.err.unsupported.cross.fp.lit                   # Scanner: host system dependent
-compiler.misc.arg.length.mismatch
 compiler.misc.assignment.from.super-bound
 compiler.misc.assignment.to.extends-bound
 compiler.misc.bad.class.file.header                     # bad class file
@@ -73,7 +72,6 @@
 compiler.misc.kindname.type.variable
 compiler.misc.kindname.type.variable.bound
 compiler.misc.kindname.value
-compiler.misc.no.conforming.assignment.exists
 compiler.misc.non.denotable.type
 compiler.misc.no.unique.minimal.instance.exists
 compiler.misc.resume.abort                              # prompt for a response
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ExplicitParamsDoNotConformToBounds.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along 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.
+ */
+
+// key: compiler.err.cant.apply.symbol.1
+// key: compiler.misc.explicit.param.do.not.conform.to.bounds
+
+class ExplicitParamsDoNotConformToBounds {
+    <X extends Number> void m() {}
+    { this.<String>m(); }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/InapplicableSymbols.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along 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.
+ */
+
+// key: compiler.err.cant.apply.symbols
+// key: compiler.misc.arg.length.mismatch
+// key: compiler.misc.inapplicable.method
+
+class ExplicitParamsDoNotConformToBounds {
+    void m(int i1) {}
+    void m(int i1, int i2) {}
+    { this.m(); }
+}
--- a/langtools/test/tools/javac/diags/examples/IncompatibleTypes1.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/diags/examples/IncompatibleTypes1.java	Wed Jul 05 17:24:21 2017 +0200
@@ -22,7 +22,7 @@
  */
 
 // key: compiler.misc.incompatible.types.1
-// key: compiler.misc.no.conforming.instance.exists
+// key: compiler.misc.infer.no.conforming.instance.exists
 // key: compiler.err.prob.found.req
 
 class IncompatibleTypes1<V> {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/InferArgsLengthMismatch.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along 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.
+ */
+
+// key: compiler.err.cant.apply.symbol.1
+// key: compiler.misc.infer.arg.length.mismatch
+
+class InferArgsLengthMismatch {
+    <X extends Number> void m(X x1, X x2) {}
+    { this.m(1); }
+}
--- a/langtools/test/tools/javac/diags/examples/KindnameConstructor.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/diags/examples/KindnameConstructor.java	Wed Jul 05 17:24:21 2017 +0200
@@ -24,7 +24,9 @@
 // key: compiler.misc.kindname.constructor
 // key: compiler.misc.kindname.class
 // key: compiler.misc.no.args
-// key: compiler.err.cant.apply.symbol
+// key: compiler.err.cant.apply.symbol.1
+// key: compiler.misc.arg.length.mismatch
+// key: compiler.misc.no.conforming.assignment.exists
 // key: compiler.misc.count.error.plural
 // run: backdoor
 
--- a/langtools/test/tools/javac/diags/examples/NoArgs.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/diags/examples/NoArgs.java	Wed Jul 05 17:24:21 2017 +0200
@@ -22,7 +22,8 @@
  */
 
 // key: compiler.misc.no.args
-// key: compiler.err.cant.apply.symbol
+// key: compiler.err.cant.apply.symbol.1
+// key: compiler.misc.arg.length.mismatch
 // run: simple
 
 class X {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/VarargsArgumentMismatch.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along 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.
+ */
+
+// key: compiler.err.cant.apply.symbol.1
+// key: compiler.misc.varargs.argument.mismatch
+
+class VarargsArgumentMismatch {
+    void m(String s, Integer... is) {}
+    { this.m("1", "2", "3"); }
+}
--- a/langtools/test/tools/javac/diags/examples/WhereCaptured.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/diags/examples/WhereCaptured.java	Wed Jul 05 17:24:21 2017 +0200
@@ -25,7 +25,8 @@
 // key: compiler.misc.where.description.captured.1
 // key: compiler.misc.where.description.typevar
 // key: compiler.misc.where.typevar
-// key: compiler.err.cant.apply.symbol
+// key: compiler.err.cant.apply.symbol.1
+// key: compiler.misc.infer.no.conforming.assignment.exists
 // key: compiler.misc.captured.type
 // options: -XDdiags=where,simpleNames
 // run: simple
--- a/langtools/test/tools/javac/diags/examples/WhereCaptured1.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/diags/examples/WhereCaptured1.java	Wed Jul 05 17:24:21 2017 +0200
@@ -25,7 +25,8 @@
 // key: compiler.misc.where.description.captured.1
 // key: compiler.misc.where.description.typevar
 // key: compiler.misc.where.typevar
-// key: compiler.err.cant.apply.symbol
+// key: compiler.err.cant.apply.symbol.1
+// key: compiler.misc.infer.no.conforming.assignment.exists
 // key: compiler.misc.captured.type
 // key: compiler.misc.type.null
 // options: -XDdiags=where,simpleNames
--- a/langtools/test/tools/javac/diags/examples/WhereTypeVar.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/diags/examples/WhereTypeVar.java	Wed Jul 05 17:24:21 2017 +0200
@@ -24,7 +24,8 @@
 // key: compiler.misc.where.typevar
 // key: compiler.misc.where.description.typevar.1
 // key: compiler.misc.type.var
-// key: compiler.err.cant.apply.symbol
+// key: compiler.err.cant.apply.symbol.1
+// key: compiler.misc.no.conforming.assignment.exists
 // options: -XDdiags=where,disambiguateTvars
 // run: simple
 
--- a/langtools/test/tools/javac/generics/diamond/neg/Neg06.out	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/generics/diamond/neg/Neg06.out	Wed Jul 05 17:24:21 2017 +0200
@@ -1,4 +1,4 @@
-Neg06.java:18:36: compiler.err.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.IFoo), (compiler.misc.no.conforming.instance.exists: X, Neg06.IFoo<X>, Neg06.ISuperFoo<java.lang.String>)
-Neg06.java:19:37: compiler.err.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.CFoo), (compiler.misc.no.conforming.instance.exists: X, Neg06.CFoo<X>, Neg06.CSuperFoo<java.lang.String>)
-Neg06.java:20:37: compiler.err.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.CFoo), (compiler.misc.no.conforming.instance.exists: X, Neg06.CFoo<X>, Neg06.CSuperFoo<java.lang.String>)
+Neg06.java:18:36: compiler.err.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.IFoo), (compiler.misc.infer.no.conforming.instance.exists: X, Neg06.IFoo<X>, Neg06.ISuperFoo<java.lang.String>)
+Neg06.java:19:37: compiler.err.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.CFoo), (compiler.misc.infer.no.conforming.instance.exists: X, Neg06.CFoo<X>, Neg06.CSuperFoo<java.lang.String>)
+Neg06.java:20:37: compiler.err.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.CFoo), (compiler.misc.infer.no.conforming.instance.exists: X, Neg06.CFoo<X>, Neg06.CSuperFoo<java.lang.String>)
 3 errors
--- a/langtools/test/tools/javac/generics/inference/6315770/T6315770.out	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/generics/inference/6315770/T6315770.out	Wed Jul 05 17:24:21 2017 +0200
@@ -1,3 +1,3 @@
 T6315770.java:16:42: compiler.err.undetermined.type.1: <T>T6315770<T>, (compiler.misc.no.unique.maximal.instance.exists: T, java.lang.String,java.lang.Integer,java.lang.Runnable)
-T6315770.java:17:40: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.conforming.instance.exists: T, T6315770<T>, T6315770<? super java.lang.String>)), <T>T6315770<T>, T6315770<? super java.lang.String>
+T6315770.java:17:40: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: T, T6315770<T>, T6315770<? super java.lang.String>)), <T>T6315770<T>, T6315770<? super java.lang.String>
 2 errors
--- a/langtools/test/tools/javac/generics/inference/6611449/T6611449.out	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/generics/inference/6611449/T6611449.out	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
-T6611449.java:18:9: compiler.err.cant.resolve.location.args: kindname.constructor, T6611449, , int, kindname.class, T6611449<S>
-T6611449.java:19:9: compiler.err.cant.resolve.location.args: kindname.constructor, T6611449, , int,int, kindname.class, T6611449<S>
-T6611449.java:20:9: compiler.err.cant.apply.symbol: kindname.method, m1, T, int, kindname.class, T6611449<S>, null
-T6611449.java:21:9: compiler.err.cant.apply.symbol: kindname.method, m2, T,T, int,int, kindname.class, T6611449<S>, null
+T6611449.java:18:9: compiler.err.cant.apply.symbols: kindname.constructor, T6611449, int,{(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T,T), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T), (compiler.misc.inferred.do.not.conform.to.bounds: java.lang.Integer, S))}
+T6611449.java:19:9: compiler.err.cant.apply.symbols: kindname.constructor, T6611449, int,int,{(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T,T), (compiler.misc.inferred.do.not.conform.to.bounds: java.lang.Integer, S)),(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T), (compiler.misc.infer.arg.length.mismatch))}
+T6611449.java:20:9: compiler.err.cant.apply.symbol.1: kindname.method, m1, T, int, kindname.class, T6611449<S>, (compiler.misc.inferred.do.not.conform.to.bounds: java.lang.Integer, S)
+T6611449.java:21:9: compiler.err.cant.apply.symbol.1: kindname.method, m2, T,T, int,int, kindname.class, T6611449<S>, (compiler.misc.inferred.do.not.conform.to.bounds: java.lang.Integer, S)
 4 errors
--- a/langtools/test/tools/javac/generics/inference/6638712/T6638712a.out	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712a.out	Wed Jul 05 17:24:21 2017 +0200
@@ -1,2 +1,2 @@
-T6638712a.java:16:41: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.conforming.instance.exists: T, java.util.Comparator<T>, java.util.Comparator<java.lang.String>)), <T>java.util.Comparator<T>, java.util.Comparator<java.lang.String>
+T6638712a.java:16:41: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: T, java.util.Comparator<T>, java.util.Comparator<java.lang.String>)), <T>java.util.Comparator<T>, java.util.Comparator<java.lang.String>
 1 error
--- a/langtools/test/tools/javac/generics/inference/6638712/T6638712b.out	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712b.out	Wed Jul 05 17:24:21 2017 +0200
@@ -1,2 +1,2 @@
-T6638712b.java:14:21: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.conforming.instance.exists: T, T, java.lang.String)), <T>T, java.lang.String
+T6638712b.java:14:21: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: T, T, java.lang.String)), <T>T, java.lang.String
 1 error
--- a/langtools/test/tools/javac/generics/inference/6638712/T6638712c.out	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712c.out	Wed Jul 05 17:24:21 2017 +0200
@@ -1,2 +1,2 @@
-T6638712c.java:16:9: compiler.err.cant.apply.symbol: kindname.method, sort, T[],java.util.Comparator<? super T>, java.lang.Enum[],java.util.Comparator<java.lang.Enum<?>>, kindname.class, T6638712c, null
+T6638712c.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, sort, T[],java.util.Comparator<? super T>, java.lang.Enum[],java.util.Comparator<java.lang.Enum<?>>, kindname.class, T6638712c, (compiler.misc.inferred.do.not.conform.to.params: java.lang.Enum[],java.util.Comparator<? super java.lang.Enum>, java.lang.Enum[],java.util.Comparator<java.lang.Enum<?>>)
 1 error
--- a/langtools/test/tools/javac/generics/inference/6638712/T6638712d.out	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712d.out	Wed Jul 05 17:24:21 2017 +0200
@@ -1,2 +1,2 @@
-T6638712d.java:16:9: compiler.err.cant.apply.symbol: kindname.method, m, U,java.util.List<java.util.List<U>>, int,java.util.List<java.util.List<java.lang.String>>, kindname.class, T6638712d, null
+T6638712d.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, m, U,java.util.List<java.util.List<U>>, int,java.util.List<java.util.List<java.lang.String>>, kindname.class, T6638712d, (compiler.misc.inferred.do.not.conform.to.params: java.lang.String,java.util.List<java.util.List<java.lang.String>>, int,java.util.List<java.util.List<java.lang.String>>)
 1 error
--- a/langtools/test/tools/javac/generics/inference/6638712/T6638712e.out	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/generics/inference/6638712/T6638712e.out	Wed Jul 05 17:24:21 2017 +0200
@@ -1,2 +1,2 @@
-T6638712e.java:17:27: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.no.conforming.instance.exists: X, T6638712e.Foo<X,java.lang.String>, T6638712e.Foo<java.lang.Object,java.lang.String>)), <X>T6638712e.Foo<X,java.lang.String>, T6638712e.Foo<java.lang.Object,java.lang.String>
+T6638712e.java:17:27: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: X, T6638712e.Foo<X,java.lang.String>, T6638712e.Foo<java.lang.Object,java.lang.String>)), <X>T6638712e.Foo<X,java.lang.String>, T6638712e.Foo<java.lang.Object,java.lang.String>
 1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lib/JavacTestingAbstractProcessor.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along 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.util.*;
+import javax.annotation.processing.*;
+import javax.lang.model.SourceVersion;
+import static javax.lang.model.SourceVersion.*;
+import javax.lang.model.element.*;
+import javax.lang.model.util.*;
+
+/**
+ * An abstract annotation processor tailored to javac regression testing.
+ */
+public abstract class JavacTestingAbstractProcessor extends AbstractProcessor {
+    private static final Set<String> allAnnotations;
+
+    static {
+        Set<String> tmp = new HashSet<>();
+        tmp.add("*");
+        allAnnotations = Collections.unmodifiableSet(tmp);
+    }
+
+    protected Elements eltUtils;
+    protected Elements elements;
+    protected Types    typeUtils;
+    protected Types    types;
+    protected Filer    filer;
+    protected Messager messager;
+    protected Map<String, String> options;
+
+    /**
+     * Constructor for subclasses to call.
+     */
+    protected JavacTestingAbstractProcessor() {
+        super();
+    }
+
+    /**
+     * Return the latest source version. Unless this method is
+     * overridden, an {@code IllegalStateException} will be thrown if a
+     * subclass has a {@code SupportedSourceVersion} annotation.
+     */
+    @Override
+    public SourceVersion getSupportedSourceVersion() {
+        SupportedSourceVersion ssv = this.getClass().getAnnotation(SupportedSourceVersion.class);
+        if (ssv != null)
+            throw new IllegalStateException("SupportedSourceVersion annotation not supported here.");
+
+        return SourceVersion.latest();
+    }
+
+    /**
+     * If the processor class is annotated with {@link
+     * SupportedAnnotationTypes}, return an unmodifiable set with the
+     * same set of strings as the annotation.  If the class is not so
+     * annotated, a one-element set containing {@code "*"} is returned
+     * to indicate all annotations are processed.
+     *
+     * @return the names of the annotation types supported by this
+     * processor, or an empty set if none
+     */
+    @Override
+    public Set<String> getSupportedAnnotationTypes() {
+        SupportedAnnotationTypes sat = this.getClass().getAnnotation(SupportedAnnotationTypes.class);
+        if (sat != null)
+            return super.getSupportedAnnotationTypes();
+        else
+            return allAnnotations;
+    }
+
+    @Override
+    public void init(ProcessingEnvironment processingEnv) {
+        super.init(processingEnv);
+        elements = eltUtils  = processingEnv.getElementUtils();
+        types = typeUtils = processingEnv.getTypeUtils();
+        filer     = processingEnv.getFiler();
+        messager  = processingEnv.getMessager();
+        options   = processingEnv.getOptions();
+    }
+}
--- a/langtools/test/tools/javac/processing/6348499/A.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/6348499/A.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,10 +27,8 @@
 import javax.lang.model.*;
 import javax.lang.model.element.*;
 
-@SupportedAnnotationTypes("*")
-public class A extends AbstractProcessor {
+public class A extends JavacTestingAbstractProcessor {
     public boolean process(Set<? extends TypeElement> tes, RoundEnvironment renv) {
-        Filer filer = processingEnv.getFiler();
         try {
             OutputStream out = filer.createClassFile(getClass().getName()+"_0").openOutputStream();
             out.close();
@@ -39,8 +37,4 @@
         }
         return true;
     }
-    @Override
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
 }
--- a/langtools/test/tools/javac/processing/6348499/T6348499.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/6348499/T6348499.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,8 @@
  * @test
  * @bug 6441871
  * @summary javac crashes at com.sun.tools.javac.jvm.ClassReader$BadClassFile
- * @build A
+ * @library ../../lib
+ * @build JavacTestingAbstractProcessor A
  * @run main T6348499
  */
 
@@ -54,7 +55,6 @@
             fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "A.java")));
         Iterable<String> opts = Arrays.asList("-proc:only",
                                               "-processor", "A",
-                                              "-source", "1.6",
                                               "-processorpath", testClasses);
         StringWriter out = new StringWriter();
         JavacTask task = tool.getTask(out, fm, dl, opts, null, files);
--- a/langtools/test/tools/javac/processing/6359313/T6359313.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/6359313/T6359313.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
  * @bug     6359313
  * @summary error compiling annotated package
  * @author  Peter von der Ah\u00e9
+ * @library ../../lib
+ * @build   JavacTestingAbstractProcessor
  * @compile T6359313.java
  * @compile -processor T6359313 package-info.java Foo.java
  */
@@ -37,7 +39,7 @@
 import javax.lang.model.element.TypeElement;
 
 @SupportedAnnotationTypes("Foo")
-public class T6359313 extends AbstractProcessor {
+public class T6359313 extends JavacTestingAbstractProcessor {
     public boolean process(Set<? extends TypeElement> annotations,
                            RoundEnvironment roundEnvironment) {
         return true;
--- a/langtools/test/tools/javac/processing/6365040/ProcBar.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/6365040/ProcBar.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,13 +31,11 @@
 /**
  * Second of several processors to run.
  */
-@SupportedAnnotationTypes("*")
-public class ProcBar extends AbstractProcessor {
+public class ProcBar extends JavacTestingAbstractProcessor {
     public boolean process(Set<? extends TypeElement> annotations,
                            RoundEnvironment roundEnvironment) {
         if (!roundEnvironment.processingOver())
-            processingEnv.getMessager().printMessage(NOTE,
-                                                     "Hello from ProcBar");
+            messager.printMessage(NOTE, "Hello from ProcBar");
         return false;
     }
 }
--- a/langtools/test/tools/javac/processing/6365040/ProcFoo.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/6365040/ProcFoo.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,13 +31,11 @@
 /**
  * First of several processors to run.
  */
-@SupportedAnnotationTypes("*")
-public class ProcFoo extends AbstractProcessor {
+public class ProcFoo extends JavacTestingAbstractProcessor {
     public boolean process(Set<? extends TypeElement> annotations,
                            RoundEnvironment roundEnvironment) {
         if (!roundEnvironment.processingOver())
-            processingEnv.getMessager().printMessage(NOTE,
-                                                     "Hello from ProcFoo");
+            messager.printMessage(NOTE, "Hello from ProcFoo");
         return false;
     }
 }
--- a/langtools/test/tools/javac/processing/6365040/T6365040.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/6365040/T6365040.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
  * @bug 6365040 6358129
  * @summary Test -processor foo,bar,baz
  * @author  Joseph D. Darcy
+ * @library ../../lib
+ * @build   JavacTestingAbstractProcessor
  * @compile ProcFoo.java
  * @compile ProcBar.java
  * @compile T6365040.java
@@ -43,13 +45,11 @@
 import javax.lang.model.element.TypeElement;
 import static javax.tools.Diagnostic.Kind.*;
 
-@SupportedAnnotationTypes("*")
-public class T6365040 extends AbstractProcessor {
+public class T6365040 extends JavacTestingAbstractProcessor {
     public boolean process(Set<? extends TypeElement> annotations,
                            RoundEnvironment roundEnvironment) {
         if (!roundEnvironment.processingOver())
-            processingEnv.getMessager().printMessage(NOTE,
-                                                     "Hello from T6365040");
+            messager.printMessage(NOTE, "Hello from T6365040");
         return true;
     }
 }
--- a/langtools/test/tools/javac/processing/6413690/T6413690.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/6413690/T6413690.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
  * @bug     6413690 6380018
  * @summary JavacProcessingEnvironment does not enter trees from preceding rounds
  * @author  Peter von der Ah\u00e9
+ * @library ../../lib
+ * @build   JavacTestingAbstractProcessor
  * @compile T6413690.java
  * @compile -XDfatalEnterError -verbose -processor T6413690 src/Super.java TestMe.java
  */
@@ -42,11 +44,9 @@
 import javax.lang.model.util.Elements;
 
 @SupportedAnnotationTypes("TestMe")
-public class T6413690 extends AbstractProcessor {
+public class T6413690 extends JavacTestingAbstractProcessor {
     public boolean process(Set<? extends TypeElement> annotations,
                            RoundEnvironment roundEnvironment) {
-        Elements elements = processingEnv.getElementUtils();
-        Filer filer = processingEnv.getFiler();
         TypeElement testMe = elements.getTypeElement(TestMe.class.getName());
         Set<? extends Element> supers = roundEnvironment.getElementsAnnotatedWith(testMe);
         try {
--- a/langtools/test/tools/javac/processing/6414633/A.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/6414633/A.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,9 +29,8 @@
 import javax.lang.model.element.*;
 import javax.tools.*;
 
-@SupportedAnnotationTypes("*")
-public class A extends AbstractProcessor {
-
+@SuppressWarnings("")
+public class A extends JavacTestingAbstractProcessor {
     public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
         Messager m = processingEnv.getMessager();
         for (TypeElement anno: annotations) {
@@ -42,8 +41,6 @@
         return true;
     }
 
-    @Override
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
+    @SuppressWarnings("")
+    private void foo() {}
 }
--- a/langtools/test/tools/javac/processing/6414633/T6414633.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/6414633/T6414633.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,8 @@
  * @test
  * @bug 6414633 6440109
  * @summary Only the first processor message at a source location is reported
- * @build A T6414633
+ * @library ../../lib
+ * @build    JavacTestingAbstractProcessor A T6414633
  * @run main T6414633
  */
 
@@ -55,8 +56,7 @@
             fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, A.class.getName()+".java")));
         String[] opts = { "-proc:only",
                           "-processor", A.class.getName(),
-                          "-source", "1.6",
-                          "-classpath", testClasses };
+                          "-classpath", testClasses + System.getProperty("path.separator") + "../../lib" };
         JavacTask task = tool.getTask(null, fm, dl, Arrays.asList(opts), null, files);
         task.call();
 
--- a/langtools/test/tools/javac/processing/6430209/T6430209.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/6430209/T6430209.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,8 @@
  * @test
  * @bug 6441871
  * @summary spurious compiler error elicited by packageElement.getEnclosedElements()
- * @build b6341534
+ * @library ../../lib
+ * @build JavacTestingAbstractProcessor b6341534
  * @run main T6430209
  */
 
@@ -54,7 +55,7 @@
         // run annotation processor b6341534 so we can check diagnostics
         // -proc:only -processor b6341534 -cp . ./src/*.java
         String testSrc = System.getProperty("test.src", ".");
-        String testClasses = System.getProperty("test.classes");
+        String testClasses = System.getProperty("test.classes") + System.getProperty("path.separator") + "../../lib";
         JavacTool tool = JavacTool.create();
         MyDiagListener dl = new MyDiagListener();
         StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null);
--- a/langtools/test/tools/javac/processing/6430209/b6341534.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/6430209/b6341534.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,16 +30,9 @@
 import java.util.*;
 import java.util.Set;
 
-@SupportedAnnotationTypes({"*"})
-public class b6341534 extends AbstractProcessor {
+public class b6341534 extends JavacTestingAbstractProcessor {
     static int r = 0;
-    static Elements E = null;
-    static Messager msgr = null;
-    public void init(ProcessingEnvironment penv)  {
-        processingEnv = penv;
-        msgr = penv.getMessager();
-        E = penv.getElementUtils();
-    }
+
     //Create directory 'dir1' and a test class in dir1
     public boolean process(Set<? extends TypeElement> tes, RoundEnvironment renv)
     {
@@ -49,13 +42,13 @@
                 System.out.println("Round"+r+ ": " + t.toString());
 
             try {
-                PackageElement PE = E.getPackageElement("dir1");
+                PackageElement PE = eltUtils.getPackageElement("dir1");
                 List<? extends Element> LEE = PE.getEnclosedElements();    /* <=This line elicits the error message.  */
                 for(Element e : LEE)
                     System.out.println("found " + e.toString() + " in dir1.");
             }
             catch(NullPointerException npe) {
-                msgr.printMessage(ERROR,npe.toString());
+                messager.printMessage(ERROR,npe.toString());
                 //npe.printStackTrace();
                 return false;
             }
@@ -63,13 +56,8 @@
         // on round 1, expect errorRaised == false && processingOver == false
         // on round 2, expect errorRaised == true && processingOver == true
         if( renv.errorRaised() != renv.processingOver()) {
-            msgr.printMessage(ERROR, "FAILED");
+            messager.printMessage(ERROR, "FAILED");
         }
         return true;
     }
-
-    @Override
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
 }
--- a/langtools/test/tools/javac/processing/6499119/ClassProcessor.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/6499119/ClassProcessor.java	Wed Jul 05 17:24:21 2017 +0200
@@ -32,20 +32,17 @@
  * @test
  * @bug 6499119
  * @summary Created package-info class file modeled improperly
+ * @library ../../lib
+ * @build   JavacTestingAbstractProcessor
  * @compile ClassProcessor.java package-info.java
  * @compile/process -cp . -processor ClassProcessor -Akind=java  java.lang.Object
  * @compile/process -cp . -processor ClassProcessor -Akind=class java.lang.Object
  */
 
 @SupportedOptions({ "gen", "expect" })
-@SupportedAnnotationTypes({"*"})
-public class ClassProcessor extends AbstractProcessor {
+public class ClassProcessor extends JavacTestingAbstractProcessor {
     int round = 1;
 
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
-
     public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
         if (round == 1) {
             System.out.println("-- Round 1 --");
@@ -71,8 +68,6 @@
     }
 
     private void createPackageFile() {
-        Filer filer = processingEnv.getFiler();
-
         String kind = processingEnv.getOptions().get("kind");
 
         File pkgInfo;
@@ -125,7 +120,6 @@
     }
 
     private void error(String msg) {
-        Messager messager = processingEnv.getMessager();
         messager.printMessage(Kind.ERROR, msg);
     }
 }
--- a/langtools/test/tools/javac/processing/6511613/DummyProcessor.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/6511613/DummyProcessor.java	Wed Jul 05 17:24:21 2017 +0200
@@ -26,15 +26,10 @@
 import javax.lang.model.element.*;
 import java.util.Set;
 
-@SupportedAnnotationTypes("*")
-public class DummyProcessor extends  AbstractProcessor {
+public class DummyProcessor extends JavacTestingAbstractProcessor {
    public boolean process(Set<? extends TypeElement> annotations,
                   RoundEnvironment roundEnv) {
        return true;
    }
-    @Override
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
 }
 
--- a/langtools/test/tools/javac/processing/6511613/clss41701.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/6511613/clss41701.java	Wed Jul 05 17:24:21 2017 +0200
@@ -26,7 +26,8 @@
  * @bug 6511613
  * @summary javac unexpectedly doesn't fail in some cases if an annotation processor specified
  *
- * @build DummyProcessor
+ * @library ../../lib
+ * @build JavacTestingAbstractProcessor DummyProcessor
  * @compile/fail clss41701.java
  * @compile/fail -processor DummyProcessor clss41701.java
  */
--- a/langtools/test/tools/javac/processing/6512707/T6512707.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/6512707/T6512707.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,8 +26,9 @@
  * @bug 6512707
  * @summary "incompatible types" after (unrelated) annotation processing
  * @author  Peter Runge
+ * @library ../../lib
+ * @build   JavacTestingAbstractProcessor
  * @compile T6512707.java
- *
  * @compile -processor T6512707 TestAnnotation.java
  */
 
@@ -41,16 +42,10 @@
  * Dummy processor to force bug 6512707 to show - it does not matter what
  * the annotation processor does for this bug.
  */
-@SupportedAnnotationTypes("*")
-public class T6512707 extends AbstractProcessor {
+public class T6512707 extends JavacTestingAbstractProcessor {
 
     public boolean process(Set<? extends TypeElement> annotations,
                            RoundEnvironment roundEnv) {
-        return(false);
-    }
-
-    @Override
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
+        return false;
     }
 }
--- a/langtools/test/tools/javac/processing/6634138/T6634138.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/6634138/T6634138.java	Wed Jul 05 17:24:21 2017 +0200
@@ -26,6 +26,8 @@
  * @bug 6634138
  * @author  Joseph D. Darcy
  * @summary Verify source files output after processing is over are compiled
+ * @library ../../lib
+ * @build   JavacTestingAbstractProcessor
  * @compile T6634138.java
  * @compile -processor T6634138 Dummy.java
  * @run main ExerciseDependency
@@ -44,10 +46,7 @@
 import javax.lang.model.element.*;
 import javax.lang.model.util.*;
 
-@SupportedAnnotationTypes("*")
-public class T6634138 extends AbstractProcessor {
-    private Filer filer;
-
+public class T6634138 extends JavacTestingAbstractProcessor {
     public boolean process(Set<? extends TypeElement> annotations,
                            RoundEnvironment roundEnvironment) {
         // Write out files *after* processing is over.
@@ -77,16 +76,6 @@
         }
         return true;
     }
-
-    @Override
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
-
-    public void init(ProcessingEnvironment processingEnv) {
-        super.init(processingEnv);
-        filer    = processingEnv.getFiler();
-    }
 }
 
 
--- a/langtools/test/tools/javac/processing/T6439826.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/T6439826.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -48,8 +48,7 @@
         StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null);
         Iterable<? extends JavaFileObject> files =
             fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, T6439826.class.getName()+".java")));
-        Iterable<String> opts = Arrays.asList("-source","1.6",
-                                              "-proc:only",
+        Iterable<String> opts = Arrays.asList("-proc:only",
                                               "-processor", "T6439826",
                                               "-processorpath", testClasses);
         StringWriter out = new StringWriter();
--- a/langtools/test/tools/javac/processing/T6920317.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/T6920317.java	Wed Jul 05 17:24:21 2017 +0200
@@ -25,6 +25,7 @@
  * @test
  * @bug 6920317
  * @summary package-info.java file has to be specified on the javac cmdline, else it will not be avail
+ * @library ../lib
  */
 
 import java.io.*;
@@ -349,12 +350,7 @@
     /** Annotation processor used to verify the expected value for the
         package annotations found by javac. */
     @SupportedOptions({ "gen", "expect" })
-    @SupportedAnnotationTypes({"*"})
-    public static class Processor extends AbstractProcessor {
-        public SourceVersion getSupportedSourceVersion() {
-            return SourceVersion.latest();
-        }
-
+    public static class Processor extends JavacTestingAbstractProcessor {
         public boolean process(Set<? extends TypeElement> annots, RoundEnvironment renv) {
             round++;
             System.err.println("Round " + round + " annots:" + annots + " rootElems:" + renv.getRootElements());
--- a/langtools/test/tools/javac/processing/Xprint.java	Wed Jul 05 17:23:40 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2005, 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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along 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     6266828
- * @summary JSR 269: Java Language Model API
- * @author  Peter von der Ah\u00e9
- */
-import javax.tools.JavaCompiler;
-import javax.tools.ToolProvider;
-
-public class Xprint {
-    public static void main(String[] args) {
-        JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
-        javac.run(System.in, null, null,
-                  "-Xprint",
-                  "com.sun.tools.javac.code.Types",
-                  "com.sun.tools.javac.parser.Parser",
-                  "java.util.EnumSet");
-    }
-}
--- a/langtools/test/tools/javac/processing/environment/TestSourceVersion.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/environment/TestSourceVersion.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
  * @bug 6402506
  * @summary Test that getSourceVersion works properly
  * @author  Joseph D. Darcy
+ * @library ../../lib
+ * @build   JavacTestingAbstractProcessor
  * @compile TestSourceVersion.java
  * @compile -processor TestSourceVersion -proc:only -source 1.2 -AExpectedVersion=RELEASE_2 HelloWorld.java
  * @compile -processor TestSourceVersion -proc:only -source 1.3 -AExpectedVersion=RELEASE_3 HelloWorld.java
@@ -52,9 +54,8 @@
  * This processor checks that ProcessingEnvironment.getSourceVersion()
  * is consistent with the setting of the -source option.
  */
-@SupportedAnnotationTypes("*")
 @SupportedOptions("ExpectedVersion")
-public class TestSourceVersion extends AbstractProcessor {
+public class TestSourceVersion extends JavacTestingAbstractProcessor {
 
     public boolean process(Set<? extends TypeElement> annotations,
                            RoundEnvironment roundEnvironment) {
@@ -68,9 +69,4 @@
 
         return true;
     }
-
-    @Override
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
 }
--- a/langtools/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
  * @bug 6397298 6400986 6425592 6449798 6453386 6508401 6498938 6911854
  * @summary Tests that getElementsAnnotatedWith works properly.
  * @author  Joseph D. Darcy
+ * @library ../../../lib
+ * @build   JavacTestingAbstractProcessor
  * @compile TestElementsAnnotatedWith.java
  * @compile InheritedAnnotation.java
  * @compile -processor TestElementsAnnotatedWith -proc:only SurfaceAnnotations.java
@@ -57,16 +59,13 @@
  * getElementsAnnotatedWith is consistent with the expected results
  * stored in an AnnotatedElementInfo annotation.
  */
-@SupportedAnnotationTypes("*")
 @AnnotatedElementInfo(annotationName="java.lang.SuppressWarnings", expectedSize=0, names={})
-public class TestElementsAnnotatedWith extends AbstractProcessor {
+public class TestElementsAnnotatedWith extends JavacTestingAbstractProcessor {
 
     public boolean process(Set<? extends TypeElement> annotations,
                            RoundEnvironment roundEnvironment) {
-        Elements elementUtils = processingEnv.getElementUtils();
-
         TypeElement annotatedElementInfoElement =
-            elementUtils.getTypeElement("AnnotatedElementInfo");
+            elements.getTypeElement("AnnotatedElementInfo");
         Set<? extends Element> resultsMeta = Collections.emptySet();
         Set<? extends Element> resultsBase = Collections.emptySet();
 
@@ -93,9 +92,7 @@
 
                 resultsMeta =
                     roundEnvironment.
-                    getElementsAnnotatedWith(elementUtils.
-                                             getTypeElement(annotatedElementInfo.
-                                                            annotationName())) ;
+                    getElementsAnnotatedWith(elements.getTypeElement(annotatedElementInfo.annotationName()));
 
                 System.err.println("Results: " + resultsMeta);
 
@@ -167,9 +164,4 @@
             throw new RuntimeException("Illegal argument exception not thrown");
         } catch(IllegalArgumentException iae) {}
     }
-
-    @Override
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
 }
--- a/langtools/test/tools/javac/processing/errors/TestFatalityOfParseErrors.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/errors/TestFatalityOfParseErrors.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,9 @@
  * @bug 6403459
  * @summary Test that generating programs with syntax errors is a fatal condition
  * @author  Joseph D. Darcy
+ * @library ../../lib
+ * @build JavacTestingAbstractProcessor
+ * @compile TestReturnCode.java
  * @compile TestFatalityOfParseErrors.java
  * @compile/fail -XprintRounds -processor TestFatalityOfParseErrors -proc:only TestFatalityOfParseErrors.java
  */
@@ -45,11 +48,8 @@
  * Write out an incomplete source file and observe that the next round
  * is marked as an error.
  */
-@SupportedAnnotationTypes("*")
-public class TestFatalityOfParseErrors extends AbstractProcessor {
+public class TestFatalityOfParseErrors extends JavacTestingAbstractProcessor {
     int round = 0;
-    Messager messager;
-    Filer filer;
 
     public boolean process(Set<? extends TypeElement> annotations,
                            RoundEnvironment roundEnvironment) {
@@ -87,14 +87,4 @@
         }
         return true;
     }
-
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
-
-    public void init(ProcessingEnvironment processingEnv) {
-        super.init(processingEnv);
-        messager = processingEnv.getMessager();
-        filer    = processingEnv.getFiler();
-    }
 }
--- a/langtools/test/tools/javac/processing/errors/TestOptionSyntaxErrors.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/errors/TestOptionSyntaxErrors.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
  * @bug 6406212
  * @summary Test that annotation processor options with illegal syntax are rejected
  * @author  Joseph D. Darcy
+ * @library ../../lib
+ * @build JavacTestingAbstractProcessor
  * @compile TestOptionSyntaxErrors.java
  * @compile/fail -A TestOptionSyntaxErrors.java
  * @compile/fail -A8adOption TestOptionSyntaxErrors.java
@@ -46,14 +48,9 @@
 /**
  * No-op processor; should not be run.
  */
-@SupportedAnnotationTypes("*")
-public class TestOptionSyntaxErrors extends AbstractProcessor {
+public class TestOptionSyntaxErrors extends JavacTestingAbstractProcessor {
     public boolean process(Set<? extends TypeElement> annotations,
                            RoundEnvironment roundEnvironment) {
         return true;
     }
-
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
 }
--- a/langtools/test/tools/javac/processing/errors/TestReturnCode.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/errors/TestReturnCode.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
  * @bug 6403468
  * @summary Test that an erroneous return code results from raising an error.
  * @author  Joseph D. Darcy
+ * @library ../../lib
+ * @build JavacTestingAbstractProcessor
  * @compile TestReturnCode.java
  *
  * @compile      -processor TestReturnCode -proc:only                                                                   Foo.java
@@ -60,20 +62,17 @@
  * This processor raises errors or throws exceptions on different
  * rounds to allow the return code to be test.
  */
-@SupportedAnnotationTypes("*")
 @SupportedOptions({"ErrorOnFirst",
                    "ErrorOnLast",
                    "ExceptionOnFirst",
                    "ExceptionOnLast"})
-public class TestReturnCode extends AbstractProcessor {
+public class TestReturnCode extends JavacTestingAbstractProcessor {
 
     private boolean errorOnFirst;
     private boolean errorOnLast;
     private boolean exceptionOnFirst;
     private boolean exceptionOnLast;
 
-    private Messager messager;
-
     public boolean process(Set<? extends TypeElement> annotations,
                            RoundEnvironment roundEnv) {
         if (!roundEnv.processingOver()) {
@@ -103,11 +102,5 @@
         errorOnLast     = keySet.contains("ErrorOnLast");
         exceptionOnFirst  = keySet.contains("ExceptionOnFirst");
         exceptionOnLast = keySet.contains("ExceptionOnLast");
-        messager = processingEnv.getMessager();
-    }
-
-    @Override
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
     }
 }
--- a/langtools/test/tools/javac/processing/filer/TestFilerConstraints.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/filer/TestFilerConstraints.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
  * @bug 6380018 6453386 6457283
  * @summary Test that the constraints guaranteed by the Filer and maintained
  * @author  Joseph D. Darcy
+ * @library ../../lib
  * @build TestFilerConstraints
  * @compile -encoding iso-8859-1 -processor TestFilerConstraints -proc:only TestFilerConstraints.java
  */
@@ -69,11 +70,8 @@
  *
  * </ul>
  */
-@SupportedAnnotationTypes("*")
-public class TestFilerConstraints extends AbstractProcessor {
+public class TestFilerConstraints extends JavacTestingAbstractProcessor {
     private int round = 0;
-    private Messager messager;
-    private Filer filer;
 
     private PrintWriter  pw_src1 = null;
     private PrintWriter  pw_src2 = null;
@@ -167,17 +165,6 @@
         return true;
     }
 
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
-
-    public void init(ProcessingEnvironment processingEnv) {
-        super.init(processingEnv);
-        messager = processingEnv.getMessager();
-        filer    = processingEnv.getFiler();
-
-    }
-
     /**
      * Test that the single expected expected type, name, is the root
      * element.
--- a/langtools/test/tools/javac/processing/filer/TestGetResource.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/filer/TestGetResource.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,8 @@
  * @bug 6380018 6449798
  * @summary Test Filer.getResource
  * @author  Joseph D. Darcy
- * @build TestGetResource
+ * @library ../../lib
+ * @build  JavacTestingAbstractProcessor TestGetResource
  * @compile -processor TestGetResource -proc:only -Aphase=write TestGetResource.java
  * @compile -processor TestGetResource -proc:only -Aphase=read  TestGetResource.java
  */
@@ -49,13 +50,8 @@
  * first run of the annotation processor, write out a resource file
  * and on the second run read it in.
  */
-@SupportedAnnotationTypes("*")
 @SupportedOptions("phase")
-public class TestGetResource extends AbstractProcessor {
-    private Messager messager;
-    private Filer filer;
-    private Map<String,String> options;
-
+public class TestGetResource extends JavacTestingAbstractProcessor {
     private static String CONTENTS = "Hello World.";
     private static String PKG = "";
     private static String RESOURCE_NAME = "Resource1";
@@ -92,15 +88,4 @@
         }
         return false;
     }
-
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
-
-    public void init(ProcessingEnvironment processingEnv) {
-        super.init(processingEnv);
-        messager = processingEnv.getMessager();
-        filer    = processingEnv.getFiler();
-        options  = processingEnv.getOptions();
-    }
 }
--- a/langtools/test/tools/javac/processing/filer/TestGetResource2.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/filer/TestGetResource2.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
 /* @test
  * @bug 6929404
  * @summary Filer.getResource(SOURCE_PATH, ...) does not work when -sourcepath contains >1 entry
+ * @library ../../lib
  */
 
 import java.io.*;
@@ -114,8 +115,7 @@
             throw new Exception(errors + " errors occurred");
     }
 
-    @SupportedAnnotationTypes("*")
-    static class AnnoProc extends AbstractProcessor {
+    static class AnnoProc extends JavacTestingAbstractProcessor {
 
         public @Override boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
             if (roundEnv.processingOver()) {
@@ -123,27 +123,23 @@
             }
 
             try {
-                FileObject resource = processingEnv.getFiler().getResource(StandardLocation.SOURCE_PATH, "resources", "file.txt");
+                FileObject resource = filer.getResource(StandardLocation.SOURCE_PATH, "resources", "file.txt");
                 try {
                     resource.openInputStream().close();
-                    processingEnv.getMessager().printMessage(Kind.NOTE, "found: " + resource.toUri());
+                    messager.printMessage(Kind.NOTE, "found: " + resource.toUri());
                     return true;
                 } catch (IOException x) {
-                    processingEnv.getMessager().printMessage(Kind.ERROR, "could not read: " + resource.toUri());
+                    messager.printMessage(Kind.ERROR, "could not read: " + resource.toUri());
                     x.printStackTrace();
                 }
             } catch (IOException x) {
-                processingEnv.getMessager().printMessage(Kind.ERROR, "did not find resource");
+                messager.printMessage(Kind.ERROR, "did not find resource");
                 x.printStackTrace();
             }
 
             return false;
         }
 
-        @Override
-        public SourceVersion getSupportedSourceVersion() {
-            return SourceVersion.latest();
-        }
     }
 
     private File write(File dir, String path, String contents) throws IOException {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/filer/TestInvalidRelativeNames.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along 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 6502392
+ * @summary Invalid relative names for Filer.createResource and Filer.getResource
+ * @library ../../lib
+ * @build   JavacTestingAbstractProcessor
+ * @compile TestInvalidRelativeNames.java
+ * @compile/process -processor TestInvalidRelativeNames java.lang.Object
+ */
+
+import java.io.*;
+import java.util.*;
+import javax.annotation.processing.*;
+import javax.lang.model.*;
+import javax.lang.model.element.*;
+import javax.tools.Diagnostic;
+import javax.tools.StandardLocation;
+
+public class TestInvalidRelativeNames extends JavacTestingAbstractProcessor {
+    enum Kind { CREATE_WRITER, GET_READER, CREATE_OUTPUT_STREAM, GET_INPUT_STREAM };
+
+    static final String[] invalidRelativeNames = {
+            "/boo", "goo/../hoo", "./ioo", ""
+    };
+
+    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        if (roundEnv.processingOver()) {
+            for (String relative: invalidRelativeNames) {
+                for (Kind kind: Kind.values()) {
+                    test(relative, kind);
+                }
+            }
+        }
+        return true;
+    }
+
+    void test(String relative, Kind kind) {
+        System.out.println("test relative path: " + relative + ", kind: " + kind);
+        try {
+            switch (kind) {
+                case CREATE_WRITER:
+                    Writer writer = filer.createResource(
+                            StandardLocation.SOURCE_OUTPUT, "", relative).openWriter();
+                    writer.close();
+                    break;
+
+                case GET_READER:
+                    Reader reader = filer.getResource(
+                            StandardLocation.SOURCE_OUTPUT, "", relative).openReader(true);
+                    reader.close();
+                    break;
+
+                case CREATE_OUTPUT_STREAM:
+                    OutputStream out = filer.createResource(
+                            StandardLocation.SOURCE_OUTPUT, "", relative).openOutputStream();
+                    out.close();
+                    break;
+
+                case GET_INPUT_STREAM:
+                    InputStream in = filer.createResource(
+                            StandardLocation.SOURCE_OUTPUT, "", relative).openInputStream();
+                    in.close();
+                    break;
+            }
+        } catch (IllegalArgumentException expected) {
+            System.out.println("expected exception thrown: " + expected);
+            return;
+        } catch (Exception e) {
+            messager.printMessage(Diagnostic.Kind.ERROR,
+                    "relative path: " + relative + ", kind: " + kind + ", unexpected exception: " + e);
+            return;
+        }
+        messager.printMessage(Diagnostic.Kind.ERROR,
+                "relative path: " + relative + ", kind: " + kind + ", no exception thrown");
+    }
+}
+
--- a/langtools/test/tools/javac/processing/filer/TestLastRound.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/filer/TestLastRound.java	Wed Jul 05 17:24:21 2017 +0200
@@ -24,6 +24,8 @@
 /*
  * @test 6966604
  * @summary JavacFiler not correctly notified of lastRound
+ * @library ../../lib
+ * @build   JavacTestingAbstractProcessor
  * @compile TestLastRound.java
  * @compile/fail/ref=TestLastRound.out -XDrawDiagnostics -Werror -proc:only -processor TestLastRound TestLastRound.java
  */
@@ -35,12 +37,10 @@
 import javax.lang.model.element.*;
 import javax.tools.*;
 
-@SupportedAnnotationTypes("*")
-public class TestLastRound extends AbstractProcessor {
+public class TestLastRound extends JavacTestingAbstractProcessor {
     @Override
     public boolean process(Set<? extends TypeElement> annotations,
                            RoundEnvironment roundEnv) {
-        Filer filer = processingEnv.getFiler();
         if (roundEnv.processingOver()) {
             try {
                 JavaFileObject fo = filer.createSourceFile("LastRound.java");
@@ -52,9 +52,4 @@
         }
         return true;
     }
-
-    @Override
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
 }
--- a/langtools/test/tools/javac/processing/filer/TestPackageInfo.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/filer/TestPackageInfo.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
  * @bug 6380018 6392177
  * @summary Test the ability to create and process package-info.java files
  * @author  Joseph D. Darcy
+ * @library ../../lib
+ * @build   JavacTestingAbstractProcessor
  * @compile TestPackageInfo.java
  * @compile -processor TestPackageInfo -proc:only foo/bar/package-info.java TestPackageInfo.java
  */
@@ -49,13 +51,7 @@
  * 1) Visibility of package-info files from the command line
  * 2) Visibility of generated package-info.java source files
  */
-@SupportedAnnotationTypes("*")
-public class TestPackageInfo extends AbstractProcessor {
-    private Elements eltUtils;
-    private Messager messager;
-    private Filer filer;
-    private Map<String,String> options;
-
+public class TestPackageInfo extends JavacTestingAbstractProcessor {
     private int round = 0;
 
     public boolean process(Set<? extends TypeElement> annotations,
@@ -64,11 +60,7 @@
 
         // Verify annotations are as expected
         Set<TypeElement> expectedAnnotations = new HashSet<TypeElement>();
-        if (round == 1)
-            expectedAnnotations.add(eltUtils.
-                                    getTypeElement("javax.annotation.processing.SupportedAnnotationTypes"));
-        expectedAnnotations.add(eltUtils.
-                                getTypeElement("java.lang.SuppressWarnings"));
+        expectedAnnotations.add(eltUtils.getTypeElement("java.lang.SuppressWarnings"));
 
         if (!roundEnv.processingOver()) {
             System.out.println("\nRound " + round);
@@ -127,16 +119,4 @@
         }
         return false;
     }
-
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
-
-    public void init(ProcessingEnvironment processingEnv) {
-        super.init(processingEnv);
-        eltUtils = processingEnv.getElementUtils();
-        messager = processingEnv.getMessager();
-        filer    = processingEnv.getFiler();
-        options  = processingEnv.getOptions();
-    }
 }
--- a/langtools/test/tools/javac/processing/messager/6362067/T6362067.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/messager/6362067/T6362067.java	Wed Jul 05 17:24:21 2017 +0200
@@ -2,39 +2,34 @@
  * @test  /nodynamiccopyright/
  * @bug     6362067
  * @summary Messager methods do not print out source position information
- * @build   T6362067
+ * @library ../../../lib
+ * @build   JavacTestingAbstractProcessor T6362067
  * @compile -processor T6362067 -proc:only T6362067.java
  * @compile/ref=T6362067.out -XDrawDiagnostics -processor T6362067 -proc:only T6362067.java
  */
-
 import java.util.Set;
 import javax.annotation.processing.*;
 import javax.lang.model.element.*;
 import static javax.tools.Diagnostic.Kind.*;
 
-@Deprecated // convenient test annotation
-@SupportedAnnotationTypes("*")
-public class T6362067 extends AbstractProcessor {
+@Deprecated // convenient test annotations
+@SuppressWarnings({""})
+public class T6362067 extends JavacTestingAbstractProcessor {
     public boolean process(Set<? extends TypeElement> annos,
                            RoundEnvironment roundEnv) {
-        Messager msgr = processingEnv.getMessager();
+
         for (Element e: roundEnv.getRootElements()) {
-            msgr.printMessage(NOTE, "note:elem", e);
+            messager.printMessage(NOTE, "note:elem", e);
             for (AnnotationMirror a: e.getAnnotationMirrors()) {
-                msgr.printMessage(NOTE, "note:anno", e, a);
+                messager.printMessage(NOTE, "note:anno", e, a);
                 for (AnnotationValue v: a.getElementValues().values()) {
-                    msgr.printMessage(NOTE, "note:value", e, a, v);
+                    messager.printMessage(NOTE, "note:value", e, a, v);
                 }
-
             }
         }
+
         if (roundEnv.processingOver())
-            msgr.printMessage(NOTE, "note:nopos");
+            messager.printMessage(NOTE, "note:nopos");
         return true;
     }
-
-    @Override
-    public javax.lang.model.SourceVersion getSupportedSourceVersion() {
-        return javax.lang.model.SourceVersion.latest();
-    }
 }
--- a/langtools/test/tools/javac/processing/messager/MessagerBasics.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/messager/MessagerBasics.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
  * @bug     6341173 6341072
  * @summary Test presence of Messager methods
  * @author  Joseph D. Darcy
+ * @library ../../lib
+ * @build   JavacTestingAbstractProcessor
  * @compile MessagerBasics.java
  * @compile -processor MessagerBasics -proc:only MessagerBasics.java
  * @compile/fail -processor MessagerBasics -proc:only -AfinalError MessagerBasics.java
@@ -39,18 +41,16 @@
 import javax.lang.model.util.*;
 import static javax.tools.Diagnostic.Kind.*;
 
-@SupportedAnnotationTypes("*")
 @SupportedOptions("finalError")
-public class MessagerBasics extends AbstractProcessor {
+public class MessagerBasics extends JavacTestingAbstractProcessor {
     public boolean process(Set<? extends TypeElement> annotations,
                            RoundEnvironment roundEnv) {
-        Messager m = processingEnv.getMessager();
         if (roundEnv.processingOver()) {
             if (processingEnv.getOptions().containsKey("finalError"))
-                m.printMessage(ERROR,   "Does not compute");
+                messager.printMessage(ERROR,   "Does not compute");
             else {
-                m.printMessage(NOTE,    "Post no bills");
-                m.printMessage(WARNING, "Beware the ides of March!");
+                messager.printMessage(NOTE,    "Post no bills");
+                messager.printMessage(WARNING, "Beware the ides of March!");
             }
         }
         return true;
--- a/langtools/test/tools/javac/processing/model/6194785/T6194785.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/model/6194785/T6194785.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
  * @bug     6194785
  * @summary ParameterDeclaration.getSimpleName does not return actual name from class files
  * @author  Peter von der Ah\u00e9
+ * @library ../../../lib
+ * @build   JavacTestingAbstractProcessor
  * @compile -g T6194785.java T6194785a.java
  * @compile -processor T6194785 foo.T6194785a T6194785.java
  */
@@ -36,13 +38,10 @@
 import javax.lang.model.util.*;
 import static javax.tools.Diagnostic.Kind.*;
 
-@SupportedAnnotationTypes("*")
-public class T6194785 extends AbstractProcessor {
+public class T6194785 extends JavacTestingAbstractProcessor {
     public boolean process(Set<? extends TypeElement> annotations,
                            RoundEnvironment roundEnvironment)
     {
-        final Messager log = processingEnv.getMessager();
-        final Elements elements = processingEnv.getElementUtils();
         class Scan extends ElementScanner7<Void,Void> {
             @Override
             public Void visitExecutable(ExecutableElement e, Void ignored) {
--- a/langtools/test/tools/javac/processing/model/6341534/T6341534.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/model/6341534/T6341534.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,8 @@
  * @summary PackageElement.getEnclosedElements results in NullPointerException from parse(JavaCompiler.java:429)
  * @author  Steve Sides
  * @author  Peter von der Ahe
+ * @library ../../../lib
+ * @build   JavacTestingAbstractProcessor
  * @compile T6341534.java
  * @compile -proc:only -processor T6341534 dir/package-info.java
  * @compile -processor T6341534 dir/package-info.java
@@ -40,20 +42,11 @@
 import java.util.Set;
 import static javax.tools.Diagnostic.Kind.*;
 
-@SupportedAnnotationTypes("*")
-public class T6341534 extends AbstractProcessor {
-    Elements elements;
-    Messager messager;
-    public void init(ProcessingEnvironment penv)  {
-        super.init(penv);
-        elements = penv.getElementUtils();
-        messager = processingEnv.getMessager();
-    }
-
+public class T6341534 extends JavacTestingAbstractProcessor {
     public boolean process(Set<? extends TypeElement> tes, RoundEnvironment renv)  {
         messager.printMessage(NOTE,
-                              String.valueOf(elements.getPackageElement("no.such.package")));
-        PackageElement dir = elements.getPackageElement("dir");
+                              String.valueOf(eltUtils.getPackageElement("no.such.package")));
+        PackageElement dir = eltUtils.getPackageElement("dir");
         messager.printMessage(NOTE, dir.getQualifiedName().toString());
         for (Element e : dir.getEnclosedElements())
             messager.printMessage(NOTE, e.toString());
--- a/langtools/test/tools/javac/processing/model/element/TestAnonClassNames.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/model/element/TestAnonClassNames.java	Wed Jul 05 17:24:21 2017 +0200
@@ -26,7 +26,8 @@
  * @bug 6449781
  * @summary Test that reported names of anonymous classes are non-null.
  * @author  Joseph D. Darcy
- * @build TestAnonSourceNames
+ * @library ../../../lib
+ * @build   JavacTestingAbstractProcessor TestAnonSourceNames
  * @compile -processor TestAnonSourceNames TestAnonClassNames.java
  * @run main TestAnonClassNames
  */
@@ -141,8 +142,7 @@
 /**
  * Probe at the various kinds of names of a type element.
  */
-@SupportedAnnotationTypes("*")
-class ClassNameProber extends AbstractProcessor {
+class ClassNameProber extends JavacTestingAbstractProcessor {
     public ClassNameProber(){super();}
 
     private boolean classesFound=false;
@@ -174,8 +174,4 @@
         }
         return true;
     }
-
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
 }
--- a/langtools/test/tools/javac/processing/model/element/TestAnonSourceNames.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/model/element/TestAnonSourceNames.java	Wed Jul 05 17:24:21 2017 +0200
@@ -36,8 +36,7 @@
  * Using the tree API, retrieve element representations of anonymous
  * classes and verify their names are as specified.
  */
-@SupportedAnnotationTypes("*")
-public class TestAnonSourceNames extends AbstractProcessor {
+public class TestAnonSourceNames extends JavacTestingAbstractProcessor {
 
    public boolean process(Set<? extends TypeElement> annotations,
                           RoundEnvironment roundEnv) {
@@ -84,9 +83,4 @@
            return super.visitClass(node, cu);
        }
    }
-
-   @Override
-   public SourceVersion getSupportedSourceVersion() {
-       return SourceVersion.latest();
-   }
 }
--- a/langtools/test/tools/javac/processing/model/element/TestElement.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/model/element/TestElement.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,8 @@
  * @bug 6453386
  * @summary Test basic properties of javax.lang.element.Element
  * @author  Joseph D. Darcy
- * @build TestElement
+ * @library ../../../lib
+ * @build   JavacTestingAbstractProcessor TestElement
  * @compile -processor TestElement -proc:only TestElement.java
  */
 
@@ -43,8 +44,7 @@
 /**
  * Test basic workings of javax.lang.element.Element
  */
-@SupportedAnnotationTypes("*")
-public class TestElement extends AbstractProcessor {
+public class TestElement extends JavacTestingAbstractProcessor {
     /**
      * For now, just check that constructors have a simple name of
      * "<init>".
@@ -66,9 +66,4 @@
         }
         return true;
     }
-
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
-
 }
--- a/langtools/test/tools/javac/processing/model/element/TestNames.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/model/element/TestNames.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,8 @@
  * @bug 6380016
  * @summary Test that the constraints guaranteed by the Filer and maintained
  * @author  Joseph D. Darcy
- * @build TestNames
+ * @library ../../../lib
+ * @build   JavacTestingAbstractProcessor TestNames
  * @compile -processor TestNames -proc:only TestNames.java
  */
 
@@ -45,11 +46,8 @@
 /**
  * Basic tests of semantics of javax.lang.model.element.Name
  */
-@SupportedAnnotationTypes("*")
-public class TestNames extends AbstractProcessor {
+public class TestNames extends JavacTestingAbstractProcessor {
     private int round = 0;
-    private Filer filer;
-    private Elements eltUtils;
 
     String stringStringName = "java.lang.String";
     Name stringName = null;
@@ -106,16 +104,6 @@
         return true;
     }
 
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
-
-    public void init(ProcessingEnvironment processingEnv) {
-        super.init(processingEnv);
-        filer    = processingEnv.getFiler();
-        eltUtils = processingEnv.getElementUtils();
-    }
-
     private static class Pseudonym implements Name {
         private String name;
 
--- a/langtools/test/tools/javac/processing/model/element/TestPackageElement.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/model/element/TestPackageElement.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,8 @@
  * @bug 6449798 6399404
  * @summary Test basic workings of PackageElement
  * @author  Joseph D. Darcy
- * @build TestPackageElement
+ * @library ../../../lib
+ * @build   JavacTestingAbstractProcessor TestPackageElement
  * @compile -processor TestPackageElement -proc:only TestPackageElement.java
  */
 
@@ -43,11 +44,7 @@
 /**
  * Test basic workings of PackageElement.
  */
-@SupportedAnnotationTypes("*")
-public class TestPackageElement extends AbstractProcessor {
-    private Filer filer;
-    private Elements eltUtils;
-
+public class TestPackageElement extends JavacTestingAbstractProcessor {
     public boolean process(Set<? extends TypeElement> annotations,
                            RoundEnvironment roundEnv) {
         if (!roundEnv.processingOver()) {
@@ -71,15 +68,4 @@
         }
         return true;
     }
-
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
-
-    public void init(ProcessingEnvironment processingEnv) {
-        super.init(processingEnv);
-        filer    = processingEnv.getFiler();
-        eltUtils = processingEnv.getElementUtils();
-    }
-
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/element/TestResourceElement.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along 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 6967842
+ * @summary Element not returned from tree API for ARM resource variables.
+ * @author A. Sundararajan
+ * @library ../../../lib
+ * @build   JavacTestingAbstractProcessor TestResourceElement
+ * @compile -processor TestResourceElement -proc:only TestResourceElement.java
+ */
+
+import javax.annotation.processing.*;
+import javax.lang.model.*;
+import javax.lang.model.element.*;
+import java.util.*;
+import com.sun.source.tree.*;
+import com.sun.source.util.*;
+
+public class TestResourceElement extends JavacTestingAbstractProcessor implements AutoCloseable {
+    public boolean process(Set<? extends TypeElement> annotations,
+                          RoundEnvironment roundEnv) {
+       if (!roundEnv.processingOver()) {
+           Trees trees = Trees.instance(processingEnv);
+
+           for(Element rootElement : roundEnv.getRootElements()) {
+               TreePath treePath = trees.getPath(rootElement);
+
+               VariableScanner varScanner =  new VariableScanner(trees);
+               varScanner.scan(trees.getTree(rootElement),
+                        treePath.getCompilationUnit());
+               if (varScanner.getTrvElement() == null) {
+                   throw new AssertionError("Element is null for 'trv'");
+               }
+           }
+       }
+       return true;
+    }
+
+    @Override
+    public void close() {}
+
+    private void test1() {
+        // The resource variable "trv"'s Element is checked.
+        // Do not change the name of the variable.
+        try(TestResourceElement trv = this) {}
+    }
+
+    class VariableScanner extends TreeScanner<Void, CompilationUnitTree> {
+       private Trees trees;
+       private Element trvElement;
+
+       public VariableScanner(Trees trees) {
+           super();
+           this.trees = trees;
+       }
+       @Override
+       public Void visitVariable(VariableTree node, CompilationUnitTree cu) {
+           // if this is "trv", get it's element.
+           if (node.getName().contentEquals("trv")) {
+               trvElement = trees.getElement(trees.getPath(cu, node));
+           }
+           return super.visitVariable(node, cu);
+       }
+
+       Element getTrvElement() {
+           return trvElement;
+       }
+   }
+}
--- a/langtools/test/tools/javac/processing/model/element/TestResourceVariable.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/model/element/TestResourceVariable.java	Wed Jul 05 17:24:21 2017 +0200
@@ -23,11 +23,12 @@
 
 /*
  * @test
- * @bug  6911256 6964740
+ * @bug  6911256 6964740 6967842
  * @summary Test that the resource variable kind is appropriately set
  * @author  Joseph D. Darcy
- * @build TestResourceVariable
- * @compile/fail -processor TestResourceVariable -proc:only TestResourceVariable.java
+ * @library ../../../lib
+ * @build   JavacTestingAbstractProcessor TestResourceVariable
+ * @compile -processor TestResourceVariable -proc:only TestResourceVariable.java
  */
 
 // Bug should be filed for this misbehavior
@@ -48,8 +49,7 @@
  * resource of an ARM block and verify their kind tags are set
  * appropriately.
  */
-@SupportedAnnotationTypes("*")
-public class TestResourceVariable extends AbstractProcessor implements AutoCloseable {
+public class TestResourceVariable extends JavacTestingAbstractProcessor implements AutoCloseable {
     int resourceVariableCount = 0;
 
     public boolean process(Set<? extends TypeElement> annotations,
@@ -105,9 +105,4 @@
            return super.visitVariable(node, cu);
        }
    }
-
-   @Override
-   public SourceVersion getSupportedSourceVersion() {
-       return SourceVersion.latest();
-   }
 }
--- a/langtools/test/tools/javac/processing/model/element/TypeParamBounds.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/model/element/TypeParamBounds.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,8 @@
  * @bug     6423972
  * @summary Tests TypeParameter.getBounds.
  * @author  Scott Seligman
- * @build   TypeParamBounds
+ * @library ../../../lib
+ * @build   JavacTestingAbstractProcessor TypeParamBounds
  * @compile -processor TypeParamBounds -proc:only TypeParamBounds.java
  */
 
@@ -40,18 +41,7 @@
 import javax.lang.model.type.*;
 import javax.lang.model.util.*;
 
-@SupportedAnnotationTypes("*")
-public class TypeParamBounds extends AbstractProcessor {
-
-    Elements elements;
-    Types types;
-
-    public void init(ProcessingEnvironment penv) {
-        super.init(penv);
-        elements = penv.getElementUtils();
-        types = penv.getTypeUtils();
-    }
-
+public class TypeParamBounds extends JavacTestingAbstractProcessor {
     public boolean process(Set<? extends TypeElement> annoTypes,
                            RoundEnvironment round) {
         if (!round.processingOver())
@@ -59,11 +49,6 @@
         return true;
     }
 
-    @Override
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
-
     private void doit(Set<? extends TypeElement> annoTypes,
                       RoundEnvironment round) {
         TypeElement gen = elements.getTypeElement("TypeParamBounds.Gen");
@@ -91,7 +76,6 @@
 
 
     // Fodder for the processor
-
     static class Gen<T, U extends Object, V extends Number, W extends U,
                      X extends Runnable, Y extends CharSequence & Runnable,
                      Z extends Object & Runnable> {
--- a/langtools/test/tools/javac/processing/model/type/MirroredTypeEx/OverEager.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/model/type/MirroredTypeEx/OverEager.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
  * @bug     6362178
  * @summary MirroredType[s]Exception shouldn't be created too eagerly
  * @author  Scott Seligman
+ * @library ../../../../lib
+ * @build JavacTestingAbstractProcessor
  * @compile -g OverEager.java
  * @compile -processor OverEager -proc:only OverEager.java
  */
@@ -40,17 +42,7 @@
 
 @SupportedAnnotationTypes("IAm")
 @IAm(OverEager.class)
-public class OverEager extends AbstractProcessor {
-
-    Elements elements;
-    Types types;
-
-    public void init(ProcessingEnvironment penv) {
-        super.init(penv);
-        elements = penv.getElementUtils();
-        types =  penv.getTypeUtils();
-    }
-
+public class OverEager extends JavacTestingAbstractProcessor {
     public boolean process(Set<? extends TypeElement> annoTypes,
                            RoundEnvironment round) {
         if (!round.processingOver())
@@ -58,11 +50,6 @@
         return true;
     }
 
-    @Override
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
-
     private void doit(Set<? extends TypeElement> annoTypes,
                       RoundEnvironment round) {
         for (TypeElement t : typesIn(round.getRootElements())) {
--- a/langtools/test/tools/javac/processing/model/type/MirroredTypeEx/Plurality.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/model/type/MirroredTypeEx/Plurality.java	Wed Jul 05 17:24:21 2017 +0200
@@ -25,6 +25,8 @@
  * @test
  * @bug     6519115
  * @summary Verify MirroredTypeException vs MirroredTypesException is thrown
+ * @library ../../../../lib
+ * @build JavacTestingAbstractProcessor
  * @compile Plurality.java
  * @compile -processor Plurality -proc:only Plurality.java
  * @author  Joseph D. Darcy
@@ -38,25 +40,13 @@
 import javax.lang.model.type.*;
 import javax.lang.model.util.*;
 
-@SupportedAnnotationTypes("*")
 @P0
 @P1
 @P2
 @S1
-public class Plurality extends AbstractProcessor {
+public class Plurality extends JavacTestingAbstractProcessor {
     private boolean executed = false;
 
-    Elements elements;
-    Types types;
-
-    @Override
-    public void init(ProcessingEnvironment penv) {
-        super.init(penv);
-        elements = penv.getElementUtils();
-        types =  penv.getTypeUtils();
-    }
-
-
     public boolean process(Set<? extends TypeElement> annotations,
                            RoundEnvironment roundEnv) {
         if (!roundEnv.processingOver()) {
@@ -164,11 +154,6 @@
                                            toStringName);
         }
     }
-
-    @Override
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
 }
 
 @Retention(RetentionPolicy.RUNTIME)
--- a/langtools/test/tools/javac/processing/model/type/NoTypes.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/model/type/NoTypes.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
  * @bug     6418666 6423973 6453386
  * @summary Test the NoTypes: VOID, PACKAGE, NONE
  * @author  Scott Seligman
+ * @library ../../../lib
+ * @build JavacTestingAbstractProcessor
  * @compile -g NoTypes.java
  * @compile -processor NoTypes -proc:only NoTypes.java
  */
@@ -39,18 +41,7 @@
 
 import static javax.lang.model.type.TypeKind.*;
 
-@SupportedAnnotationTypes("*")
-public class NoTypes extends AbstractProcessor {
-
-    Elements elements;
-    Types types;
-
-    public void init(ProcessingEnvironment penv) {
-        super.init(penv);
-        elements = penv.getElementUtils();
-        types =  penv.getTypeUtils();
-    }
-
+public class NoTypes extends JavacTestingAbstractProcessor {
     public boolean process(Set<? extends TypeElement> annoTypes,
                            RoundEnvironment round) {
         if (!round.processingOver())
@@ -58,11 +49,6 @@
         return true;
     }
 
-    @Override
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
-
     private void doit(Set<? extends TypeElement> annoTypes,
                       RoundEnvironment round) {
 
--- a/langtools/test/tools/javac/processing/model/util/BinaryName.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/model/util/BinaryName.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,8 @@
  * @bug     6346251
  * @summary Test Elements.getBinaryName
  * @author  Scott Seligman
- * @build   BinaryName
+ * @library ../../../lib
+ * @build   JavacTestingAbstractProcessor BinaryName
  * @compile -processor BinaryName -proc:only BinaryName.java
  */
 
@@ -38,17 +39,8 @@
 
 import static javax.lang.model.util.ElementFilter.typesIn;
 
-@SupportedAnnotationTypes("*")
 @HelloIm("BinaryName")
-public class BinaryName extends AbstractProcessor {
-
-    Elements elements;
-
-    public void init(ProcessingEnvironment penv) {
-        super.init(penv);
-        elements = penv.getElementUtils();
-    }
-
+public class BinaryName extends JavacTestingAbstractProcessor {
     public boolean process(Set<? extends TypeElement> tes,
                            RoundEnvironment round) {
         if (round.processingOver()) return true;
--- a/langtools/test/tools/javac/processing/model/util/GetTypeElemBadArg.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/model/util/GetTypeElemBadArg.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,8 @@
  * @bug     6346506 6408241
  * @summary getTypeElement should tolerate a type that can't be found
  * @author  Scott Seligman
- * @build   GetTypeElemBadArg
+ * @library ../../../lib
+ * @build   JavacTestingAbstractProcessor GetTypeElemBadArg
  * @compile -processor GetTypeElemBadArg -proc:only GetTypeElemBadArg.java
  */
 
@@ -37,16 +38,7 @@
 import javax.lang.model.type.*;
 import javax.lang.model.util.*;
 
-@SupportedAnnotationTypes("*")
-public class GetTypeElemBadArg extends AbstractProcessor {
-
-    Elements elements;
-
-    public void init(ProcessingEnvironment penv) {
-        super.init(penv);
-        elements = penv.getElementUtils();
-    }
-
+public class GetTypeElemBadArg extends JavacTestingAbstractProcessor {
     public boolean process(Set<? extends TypeElement> tes,
                            RoundEnvironment round) {
         if (round.processingOver()) return true;
@@ -63,12 +55,6 @@
         return true;
     }
 
-
-    @Override
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
-
     private static void tellAbout(TypeElement t) {
         System.out.println(t);
         System.out.println(t.getClass());
--- a/langtools/test/tools/javac/processing/model/util/NoSupers.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/model/util/NoSupers.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,8 @@
  * @bug     6346453
  * @summary directSupertypes should return empty list if arg has no supertypes
  * @author  Scott Seligman
- * @build   NoSupers
+ * @library ../../../lib
+ * @build   JavacTestingAbstractProcessor NoSupers
  * @compile -processor NoSupers -proc:only NoSupers.java
  */
 
@@ -36,16 +37,7 @@
 import javax.lang.model.type.*;
 import javax.lang.model.util.*;
 
-@SupportedAnnotationTypes("*")
-public class NoSupers extends AbstractProcessor {
-
-    Types types;
-
-    public void init(ProcessingEnvironment penv) {
-        super.init(penv);
-        types = penv.getTypeUtils();
-    }
-
+public class NoSupers extends JavacTestingAbstractProcessor {
     public boolean process(Set<? extends TypeElement> tes,
                            RoundEnvironment round) {
         if (round.processingOver()) return true;
--- a/langtools/test/tools/javac/processing/model/util/OverridesSpecEx.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/model/util/OverridesSpecEx.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
  * @bug     6453386
  * @summary Verify that example code in Elements.overrides works as spec'ed.
  * @author  Scott Seligman
+ * @library ../../../lib
+ * @build JavacTestingAbstractProcessor
  * @compile -g OverridesSpecEx.java
  * @compile -processor OverridesSpecEx -proc:only OverridesSpecEx.java
  */
@@ -39,19 +41,7 @@
 
 import static javax.lang.model.util.ElementFilter.*;
 
-
-@SupportedAnnotationTypes("*")
-public class OverridesSpecEx extends AbstractProcessor {
-
-    Elements elements;
-    Types types;
-
-    public void init(ProcessingEnvironment penv) {
-        super.init(penv);
-        elements = penv.getElementUtils();
-        types =  penv.getTypeUtils();
-    }
-
+public class OverridesSpecEx extends JavacTestingAbstractProcessor {
     public boolean process(Set<? extends TypeElement> annoTypes,
                            RoundEnvironment round) {
         if (!round.processingOver())
@@ -59,11 +49,6 @@
         return true;
     }
 
-    @Override
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
-
     private void doit(Set<? extends TypeElement> annoTypes,
                       RoundEnvironment round) {
         TypeElement string = elements.getTypeElement("java.lang.String");
@@ -113,9 +98,7 @@
             throw new AssertionError("Bogus result");
     }
 
-
     // Fodder for the processor
-
     class A {
         public void m() {}
     }
--- a/langtools/test/tools/javac/processing/model/util/TypesBadArg.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/model/util/TypesBadArg.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,8 @@
  * @bug     6345812
  * @summary Validate argument kinds in Types utilities
  * @author  Scott Seligman
- * @build   TypesBadArg
+ * @library ../../../lib
+ * @build   JavacTestingAbstractProcessor TypesBadArg
  * @compile -processor TypesBadArg -proc:only TypesBadArg.java
  */
 
@@ -36,15 +37,9 @@
 import javax.lang.model.type.*;
 import javax.lang.model.util.*;
 
-@SupportedAnnotationTypes("*")
-public class TypesBadArg extends AbstractProcessor {
-
+public class TypesBadArg extends JavacTestingAbstractProcessor {
     boolean success = true;
 
-    public void init(ProcessingEnvironment penv) {
-        super.init(penv);
-    }
-
     public boolean process(Set<? extends TypeElement> tes,
                            RoundEnvironment round) {
         if (round.processingOver()) return true;
--- a/langtools/test/tools/javac/processing/model/util/deprecation/TestDeprecation.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/model/util/deprecation/TestDeprecation.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010 Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
  * @bug 6392818
  * @summary Tests Elements.isDeprecated(Element)
  * @author  Joseph D. Darcy
+ * @library ../../../../lib
+ * @build JavacTestingAbstractProcessor
  * @compile TestDeprecation.java
  * @compile -processor TestDeprecation -proc:only Dep1.java
  * @compile Dep1.java
@@ -47,8 +49,7 @@
  * getElementsAnnotatedWith is consistent with the expected results
  * stored in an AnnotatedElementInfo annotation.
  */
-@SupportedAnnotationTypes("*")
-public class TestDeprecation extends AbstractProcessor {
+public class TestDeprecation extends JavacTestingAbstractProcessor {
 
     public boolean process(Set<? extends TypeElement> annotations,
                            RoundEnvironment roundEnv) {
@@ -98,9 +99,4 @@
             return failure;
         }
     }
-
-    @Override
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
 }
--- a/langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,8 @@
  * @bug     6346973
  * @summary directSupertypes(t) should not return t
  * @author  Scott Seligman
- * @build   DirectSupersOfErr
+ * @library ../../../../lib
+ * @build   JavacTestingAbstractProcessor DirectSupersOfErr
  * @compile -processor DirectSupersOfErr -proc:only C1.java
  */
 
@@ -37,16 +38,7 @@
 import javax.lang.model.util.*;
 import static javax.lang.model.util.ElementFilter.*;
 
-@SupportedAnnotationTypes("*")
-public class DirectSupersOfErr extends AbstractProcessor {
-
-    Types types;
-
-    public void init(ProcessingEnvironment penv) {
-        super.init(penv);
-        types = penv.getTypeUtils();
-    }
-
+public class DirectSupersOfErr extends JavacTestingAbstractProcessor {
     public boolean process(Set<? extends TypeElement> tes,
                            RoundEnvironment round) {
         if (round.processingOver()) return true;
--- a/langtools/test/tools/javac/processing/model/util/elements/TestGetConstantExpression.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/model/util/elements/TestGetConstantExpression.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,8 @@
  * @bug 6471577 6517779
  * @summary Test Elements.getConstantExpression
  * @author  Joseph D. Darcy
- * @build TestGetConstantExpression
+ * @library ../../../../lib
+ * @build   JavacTestingAbstractProcessor TestGetConstantExpression
  * @compile -processor TestGetConstantExpression Foo.java
  */
 
@@ -44,10 +45,7 @@
 /**
  * Test basic workings of Elements.getConstantExpression.
  */
-@SupportedAnnotationTypes("*")
-public class TestGetConstantExpression extends AbstractProcessor {
-    private Elements eltUtils;
-    private Filer filer;
+public class TestGetConstantExpression extends JavacTestingAbstractProcessor {
     private int round = 1;
 
     /**
@@ -130,14 +128,4 @@
             return 0;
         }
     }
-
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
-
-    public void init(ProcessingEnvironment processingEnv) {
-        super.init(processingEnv);
-        eltUtils = processingEnv.getElementUtils();
-        filer    = processingEnv.getFiler();
-    }
 }
--- a/langtools/test/tools/javac/processing/model/util/elements/TestGetPackageOf.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/model/util/elements/TestGetPackageOf.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,8 @@
  * @bug 6453386
  * @summary Test Elements.getPackageOf
  * @author  Joseph D. Darcy
- * @build TestGetPackageOf
+ * @library ../../../../lib
+ * @build   JavacTestingAbstractProcessor TestGetPackageOf
  * @compile -processor TestGetPackageOf -proc:only TestGetPackageOf.java
  */
 
@@ -43,10 +44,7 @@
 /**
  * Test basic workings of Elements.getPackageOf
  */
-@SupportedAnnotationTypes("*")
-public class TestGetPackageOf extends AbstractProcessor {
-    private Elements eltUtils;
-
+public class TestGetPackageOf extends JavacTestingAbstractProcessor {
     /**
      * Check expected behavior on classes and packages.
      */
@@ -69,13 +67,4 @@
         }
         return true;
     }
-
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
-
-    public void init(ProcessingEnvironment processingEnv) {
-        super.init(processingEnv);
-        eltUtils = processingEnv.getElementUtils();
-    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/util/elements/doccomments/TestDocComments.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along 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 6877202 6986246
+ * @summary Elements.getDocComment() is not getting JavaDocComments
+ */
+
+import com.sun.source.tree.*;
+import com.sun.source.util.*;
+import java.io.*;
+import java.util.*;
+import javax.annotation.processing.*;
+import javax.lang.model.*;
+import javax.lang.model.element.*;
+import javax.lang.model.util.*;
+import javax.tools.*;
+
+/*
+ * For a mixture of pre-existing and generated source files, ensure that we can
+ * get the doc comments.
+ * The test uses both a standard ElementScanner to find all the elements being
+ * processed, and a TreeScanner to find all the local and anonymous inner classes
+ * as well.
+ * And, because the relevant code paths in the compiler are different for
+ * command line and JSR 199 invocation, the test covers both ways of invoking the
+ * compiler.
+ */
+
+@SupportedOptions("scan")
+@SupportedAnnotationTypes("*")
+public class TestDocComments extends AbstractProcessor {
+    enum CompileKind { API, CMD };
+    enum ScanKind { TREE, ELEMENT };
+
+    // ----- Main test driver: invoke compiler for the various test cases ------
+
+    public static void main(String... args) throws Exception {
+        for (CompileKind ck: CompileKind.values()) {
+            for (ScanKind sk: ScanKind.values()) {
+                try {
+                    test(ck, sk);
+                } catch (IOException e) {
+                    error(e.toString());
+                }
+            }
+        }
+
+        if (errors > 0)
+            throw new Exception(errors + " errors occurred");
+    }
+
+    static void test(CompileKind ck, ScanKind sk) throws IOException {
+        String testClasses = System.getProperty("test.classes");
+        String testSrc = System.getProperty("test.src");
+        File testDir = new File("test." + ck + "." + sk);
+        testDir.mkdirs();
+        String[] opts = {
+            "-d", testDir.getPath(),
+            "-implicit:none",
+            "-processor", TestDocComments.class.getName(),
+            "-processorpath", testClasses,
+            //"-XprintRounds",
+            "-Ascan=" + sk
+        };
+        File[] files = {
+            new File(testSrc, "a/First.java")
+        };
+
+        if (ck == CompileKind.API)
+            test_javac_api(opts, files);
+        else
+            test_javac_cmd(opts, files);
+    }
+
+    static void test_javac_api(String[] opts, File[] files) throws IOException {
+        System.err.println("test javac api: " + Arrays.asList(opts) + " " + Arrays.asList(files));
+        DiagnosticListener<JavaFileObject> dl = new DiagnosticListener<JavaFileObject>() {
+            public void report(Diagnostic diagnostic) {
+                error(diagnostic.toString());
+            }
+        };
+        JavaCompiler c = ToolProvider.getSystemJavaCompiler();
+        StandardJavaFileManager fm = c.getStandardFileManager(null, null, null);
+        Iterable<? extends JavaFileObject> units = fm.getJavaFileObjects(files);
+        JavacTask t = (JavacTask) c.getTask(null, fm, dl, Arrays.asList(opts), null, units);
+        t.parse();
+        t.analyze();
+    }
+
+    static void test_javac_cmd(String[] opts, File[] files) {
+        System.err.println("test javac cmd: " + Arrays.asList(opts) + " " + Arrays.asList(files));
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        List<String> args = new ArrayList<String>(Arrays.asList(opts));
+        for (File f: files)
+            args.add(f.getPath());
+        int rc = com.sun.tools.javac.Main.compile(args.toArray(new String[args.size()]), pw);
+        pw.close();
+        String out = sw.toString();
+        if (out.length() > 0)
+            System.err.println(out);
+        if (rc > 0)
+            error("Compilation failed: rc=" + rc);
+    }
+
+    static void error(String msg) {
+        System.err.println(msg);
+        errors++;
+        //throw new Error(msg);
+    }
+
+    static int errors;
+
+    // ----- Annotation processor: scan for elements and check doc comments ----
+
+    Map<String,String> options;
+    Filer filer;
+    Messager messager;
+    Elements elements;
+    Trees trees;
+    ScanKind skind;
+
+    int round = 0;
+
+    @Override
+    public SourceVersion getSupportedSourceVersion() {
+        return SourceVersion.latest();
+    }
+
+    @Override
+    public void init(ProcessingEnvironment pEnv) {
+        super.init(pEnv);
+        options = pEnv.getOptions();
+        filer = pEnv.getFiler();
+        messager = pEnv.getMessager();
+        elements = pEnv.getElementUtils();
+        trees = Trees.instance(processingEnv);
+        skind = ScanKind.valueOf(options.get("scan"));
+    }
+
+    @Override
+    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        round++;
+
+        // Scan elements using an appropriate scanner, and for each element found,
+        // call check(Element e) to verify the doc comment on that element
+        for (Element e: roundEnv.getRootElements()) {
+            System.err.println("scan " + skind + " " + e.getKind() + " " + e.getSimpleName());
+            if (skind == ScanKind.TREE) {
+                new TestTreeScanner().scan(trees.getPath(e), trees);
+            }  else
+                new TestElementScanner().scan(e);
+        }
+
+        // For a few rounds, generate new source files, so that we can check whether
+        // doc comments are correctly handled in subsequent processing rounds
+        final int MAX_ROUNDS = 3;
+        if (round <= MAX_ROUNDS) {
+            String pkg = "p";
+            String currClass = "Gen" + round;
+            String curr = pkg + "." + currClass;
+            String next = (round < MAX_ROUNDS) ? (pkg + ".Gen" + (round + 1)) : "z.Last";
+            StringBuilder text = new StringBuilder();
+            text.append("package ").append(pkg).append(";\n");
+            text.append("/** CLASS ").append(currClass).append(" */\n");
+            text.append("public class ").append(currClass).append(" {\n");
+            text.append("    /** CONSTRUCTOR <init> **/\n");
+            text.append("    ").append(currClass).append("() { }\n");
+            text.append("    /** FIELD x */\n");
+            text.append("    ").append(next).append(" x;\n");
+            text.append("    /** METHOD m */\n");
+            text.append("    void m() { }\n");
+            text.append("}\n");
+
+            try {
+                JavaFileObject fo = filer.createSourceFile(curr);
+                Writer out = fo.openWriter();
+                try {
+                    out.write(text.toString());
+                } finally {
+                    out.close();
+                }
+            } catch (IOException e) {
+                throw new Error(e);
+            }
+        }
+
+        return true;
+    }
+
+    /*
+     * Check that the doc comment on an element is as expected.
+     * This method is invoked for each element found by the scanners run by process.
+     */
+    void check(Element e) {
+        System.err.println("Checking " + e);
+
+        String dc = elements.getDocComment(e);
+        System.err.println("   found " + dc);
+
+        String expect = (e.getKind() + " " + e.getSimpleName()); // default
+
+        Name name = e.getSimpleName();
+        Element encl = e.getEnclosingElement();
+        Name enclName = encl.getSimpleName();
+        ElementKind enclKind = encl.getKind();
+        switch (e.getKind()) {
+            case PARAMETER:
+            case LOCAL_VARIABLE:
+                // doc comments not retained for these elements
+                expect = null;
+                break;
+
+            case CONSTRUCTOR:
+                if (enclName.length() == 0 || enclKind == ElementKind.ENUM) {
+                    // Enum constructor is synthetic
+                    expect = null;
+                }
+                break;
+
+            case METHOD:
+                if (enclKind == ElementKind.ENUM
+                        && (name.contentEquals("values") || name.contentEquals("valueOf"))) {
+                    // synthetic enum methods
+                    expect = null;
+                }
+                break;
+
+            case CLASS:
+                if (e.getSimpleName().length() == 0) {
+                    // anon inner class
+                    expect = null;
+                }
+                break;
+        }
+
+        System.err.println("  expect " + expect);
+
+        if (dc == null ? expect == null : dc.trim().equals(expect))
+            return;
+
+        if (dc == null)
+            messager.printMessage(Diagnostic.Kind.ERROR, "doc comment is null", e);
+        else {
+            messager.printMessage(Diagnostic.Kind.ERROR,
+                    "unexpected comment: \"" + dc + "\", expected \"" + expect + "\"", e);
+        }
+    }
+
+    // ----- Scanners to find elements -----------------------------------------
+
+    class TestElementScanner extends ElementScanner7<Void, Void> {
+        @Override
+        public Void visitExecutable(ExecutableElement e, Void _) {
+            check(e);
+            return super.visitExecutable(e, _);
+        }
+        @Override
+        public Void visitType(TypeElement e, Void _) {
+            check(e);
+            return super.visitType(e, _);
+        }
+        @Override
+        public Void visitVariable(VariableElement e, Void _) {
+            check(e);
+            return super.visitVariable(e, _);
+        }
+    }
+
+    class TestTreeScanner extends TreePathScanner<Void,Trees> {
+        @Override
+        public Void visitClass(ClassTree tree, Trees trees) {
+            check(trees.getElement(getCurrentPath()));
+            return super.visitClass(tree, trees);
+        }
+        @Override
+        public Void visitMethod(MethodTree tree, Trees trees) {
+            check(trees.getElement(getCurrentPath()));
+            return super.visitMethod(tree, trees);
+        }
+        @Override
+        public Void visitVariable(VariableTree tree, Trees trees) {
+            check(trees.getElement(getCurrentPath()));
+            return super.visitVariable(tree, trees);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/util/elements/doccomments/a/First.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along 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 a;
+
+/** CLASS First */
+public class First {
+    /** CONSTRUCTOR <init> */
+    First() { }
+
+    /** FIELD x */
+    p.Gen1 x;
+
+    /** METHOD m **/
+    void m(int i) {
+        /** CLASS Local */
+        class Local {
+            /** CONSTRUCTOR <init> */
+            Local() { }
+        }
+
+        Runnable r = new Runnable() {
+            /** METHOD run **/
+            public void run() { }
+        };
+
+    }
+
+    /** ENUM E */
+    enum E {
+        /** ENUM_CONSTANT e1 */
+        e1
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/util/elements/doccomments/z/Last.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along 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 z;
+
+// This class should be read last, implicitly. Therefore it should not
+// be subject to anno processing. If it is, the lack of doc comments should
+// be detected and will flag an error.
+public class Last {
+}
--- a/langtools/test/tools/javac/processing/model/util/filter/TestIterables.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/model/util/filter/TestIterables.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
  * @bug 6406164
  * @summary Test that ElementFilter iterable methods behave properly.
  * @author  Joseph D. Darcy
+ * @library ../../../../lib
+ * @build JavacTestingAbstractProcessor
  * @compile TestIterables.java
  * @compile -processor TestIterables -proc:only Foo1.java
  * @compile Foo1.java
@@ -51,9 +53,8 @@
  * results.
  */
 @SupportedAnnotationTypes("ExpectedElementCounts")
-@ExpectedElementCounts(methods=3)
-public class TestIterables extends AbstractProcessor {
-
+@ExpectedElementCounts(methods=2)
+public class TestIterables extends JavacTestingAbstractProcessor {
     public boolean process(Set<? extends TypeElement> annotations,
                            RoundEnvironment roundEnv) {
         if (!roundEnv.processingOver()) {
@@ -118,10 +119,4 @@
 
         return count1;
     }
-
-    @Override
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
-
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/options/Xprint.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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     6266828
+ * @summary JSR 269: Java Language Model API
+ * @author  Peter von der Ah\u00e9
+ */
+import javax.tools.JavaCompiler;
+import javax.tools.ToolProvider;
+
+public class Xprint {
+    public static void main(String[] args) {
+        JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
+        javac.run(System.in, null, null,
+                  "-Xprint",
+                  "com.sun.tools.javac.code.Types",
+                  "com.sun.tools.javac.parser.Parser",
+                  "java.util.EnumSet");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/options/XprintDocComments.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along 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 6861094
+ * @summary javac -Xprint <file> does not print comments
+ * @compile/ref=XprintDocComments.out -Xprint  XprintDocComments.java
+ */
+
+/**
+ * CLASS XprintDocComments
+ */
+class XPrintDocComments {
+    /**
+     * FIELD i;
+     */
+    int i;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/options/XprintDocComments.out	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,12 @@
+
+/**
+ * CLASS XprintDocComments
+ */
+class XPrintDocComments {
+
+  XPrintDocComments();
+  /**
+   * FIELD i;
+   */
+  int i;
+}
--- a/langtools/test/tools/javac/processing/warnings/TestSourceVersionWarnings.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/warnings/TestSourceVersionWarnings.java	Wed Jul 05 17:24:21 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -50,7 +50,8 @@
 
 /**
  * This processor returns the supported source level as indicated by
- * the "SourceLevel" option.
+ * the "SourceLevel" option; therefore, don't use
+ * JavacTestingAbstractProcessor which returns the latest source level.
  */
 @SupportedAnnotationTypes("*")
 @SupportedOptions("SourceVersion")
--- a/langtools/test/tools/javac/processing/werror/WError1.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/werror/WError1.java	Wed Jul 05 17:24:21 2017 +0200
@@ -24,6 +24,8 @@
 /*
  * @test 6403456
  * @summary -Werror should work with annotation processing
+ * @library ../../lib
+ * @build   JavacTestingAbstractProcessor
  * @compile WError1.java
  * @compile -proc:only -processor WError1 WError1.java
  * @compile/fail/ref=WError1.out -XDrawDiagnostics -Werror -proc:only -processor WError1 WError1.java
@@ -36,22 +38,15 @@
 import javax.lang.model.element.*;
 import javax.tools.*;
 
-@SupportedAnnotationTypes("*")
-public class WError1 extends AbstractProcessor {
+public class WError1 extends JavacTestingAbstractProcessor {
     @Override
     public boolean process(Set<? extends TypeElement> annotations,
                            RoundEnvironment roundEnv) {
-        Messager messager = processingEnv.getMessager();
         if (++round == 1) {
             messager.printMessage(Diagnostic.Kind.WARNING, "round 1");
         }
         return true;
     }
 
-    @Override
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
-
     int round = 0;
 }
--- a/langtools/test/tools/javac/processing/werror/WErrorGen.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/werror/WErrorGen.java	Wed Jul 05 17:24:21 2017 +0200
@@ -24,6 +24,8 @@
 /*
  * @test 6403456
  * @summary -Werror should work with annotation processing
+ * @library ../../lib
+ * @build   JavacTestingAbstractProcessor
  * @compile WErrorGen.java
  * @compile -proc:only -processor WErrorGen WErrorGen.java
  * @compile/fail/ref=WErrorGen.out -XDrawDiagnostics -Werror -Xlint:rawtypes -processor WErrorGen WErrorGen.java
@@ -36,12 +38,10 @@
 import javax.lang.model.element.*;
 import javax.tools.*;
 
-@SupportedAnnotationTypes("*")
-public class WErrorGen extends AbstractProcessor {
+public class WErrorGen extends JavacTestingAbstractProcessor {
     @Override
     public boolean process(Set<? extends TypeElement> annotations,
                            RoundEnvironment roundEnv) {
-        Filer filer = processingEnv.getFiler();
         if (++round == 1) {
             try {
                 JavaFileObject fo = filer.createSourceFile("Gen");
@@ -54,10 +54,5 @@
         return true;
     }
 
-    @Override
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
-
     int round = 0;
 }
--- a/langtools/test/tools/javac/processing/werror/WErrorLast.java	Wed Jul 05 17:23:40 2017 +0200
+++ b/langtools/test/tools/javac/processing/werror/WErrorLast.java	Wed Jul 05 17:24:21 2017 +0200
@@ -24,6 +24,8 @@
 /*
  * @test 6403456
  * @summary -Werror should work with annotation processing
+ * @library ../../lib
+ * @build   JavacTestingAbstractProcessor
  * @compile WErrorLast.java
  * @compile -proc:only -processor WErrorLast WErrorLast.java
  * @compile/fail/ref=WErrorLast.out -XDrawDiagnostics -Werror -proc:only -processor WErrorLast WErrorLast.java
@@ -36,20 +38,13 @@
 import javax.lang.model.element.*;
 import javax.tools.*;
 
-@SupportedAnnotationTypes("*")
-public class WErrorLast extends AbstractProcessor {
+public class WErrorLast extends JavacTestingAbstractProcessor {
     @Override
     public boolean process(Set<? extends TypeElement> annotations,
                            RoundEnvironment roundEnv) {
-        Messager messager = processingEnv.getMessager();
         if (roundEnv.processingOver()) {
             messager.printMessage(Diagnostic.Kind.WARNING, "last round");
         }
         return true;
     }
-
-    @Override
-    public SourceVersion getSupportedSourceVersion() {
-        return SourceVersion.latest();
-    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/tree/TreePosRoundsTest.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along 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 6985205 6986246
+ * @summary access to tree positions and doc comments may be lost across annotation processing rounds
+ * @build TreePosRoundsTest
+ * @compile -proc:only -processor TreePosRoundsTest TreePosRoundsTest.java
+ * @run main TreePosRoundsTest
+ */
+
+import java.io.*;
+import java.util.*;
+import javax.annotation.processing.*;
+import javax.lang.model.*;
+import javax.lang.model.element.*;
+import javax.tools.*;
+
+import com.sun.source.tree.*;
+import com.sun.source.util.*;
+import javax.tools.JavaCompiler.CompilationTask;
+
+// This test is an annotation processor that performs multiple rounds of
+// processing, and on each round, it checks that source positions are
+// available and correct.
+//
+// The test can be run directly as a processor from the javac command line
+// or via JSR 199 by invoking the main program.
+
+@SupportedAnnotationTypes("*")
+public class TreePosRoundsTest extends AbstractProcessor {
+    public static void main(String... args) throws Exception {
+        String testSrc = System.getProperty("test.src");
+        String testClasses = System.getProperty("test.classes");
+        JavaCompiler c = ToolProvider.getSystemJavaCompiler();
+        StandardJavaFileManager fm = c.getStandardFileManager(null, null, null);
+        String thisName = TreePosRoundsTest.class.getName();
+        File thisFile = new File(testSrc, thisName + ".java");
+        Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(thisFile);
+        List<String> options = Arrays.asList(
+                "-proc:only",
+                "-processor", thisName,
+                "-processorpath", testClasses);
+        CompilationTask t = c.getTask(null, fm, null, options, null, files);
+        boolean ok = t.call();
+        if (!ok)
+            throw new Exception("processing failed");
+    }
+
+    Filer filer;
+    Messager messager;
+    Trees trees;
+
+    @Override
+    public SourceVersion getSupportedSourceVersion() {
+        return SourceVersion.latest();
+    }
+
+    @Override
+    public void init(ProcessingEnvironment pEnv) {
+        super.init(pEnv);
+        filer = pEnv.getFiler();
+        messager = pEnv.getMessager();
+        trees = Trees.instance(pEnv);
+    }
+
+    int round = 0;
+
+    @Override
+    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        round++;
+
+        // Scan trees for elements, verifying source tree positions
+        for (Element e: roundEnv.getRootElements()) {
+            try {
+                TreePath p = trees.getPath(e);
+                new TestTreeScanner(p.getCompilationUnit(), trees).scan(trees.getPath(e), null);
+            } catch (IOException ex) {
+                messager.printMessage(Diagnostic.Kind.ERROR,
+                        "Cannot get source: " + ex, e);
+            }
+        }
+
+        final int MAXROUNDS = 3;
+        if (round < MAXROUNDS)
+            generateSource("Gen" + round);
+
+        return true;
+    }
+
+    void generateSource(String name) {
+        StringBuilder text = new StringBuilder();
+        text.append("class ").append(name).append("{\n");
+        text.append("    int one = 1;\n");
+        text.append("    int two = 2;\n");
+        text.append("    int three = one + two;\n");
+        text.append("}\n");
+
+        try {
+            JavaFileObject fo = filer.createSourceFile(name);
+            Writer out = fo.openWriter();
+            try {
+                out.write(text.toString());
+            } finally {
+                out.close();
+            }
+        } catch (IOException e) {
+            throw new Error(e);
+        }
+    }
+
+    class TestTreeScanner extends TreePathScanner<Void,Void> {
+        TestTreeScanner(CompilationUnitTree unit, Trees trees) throws IOException {
+            this.unit = unit;
+            JavaFileObject sf = unit.getSourceFile();
+            source = sf.getCharContent(true).toString();
+            sourcePositions = trees.getSourcePositions();
+        }
+
+        @Override
+        public Void visitVariable(VariableTree tree, Void _) {
+            check(getCurrentPath());
+            return super.visitVariable(tree, _);
+        }
+
+        void check(TreePath tp) {
+            Tree tree = tp.getLeaf();
+
+            String expect = tree.toString();
+            if (tree.getKind() == Tree.Kind.VARIABLE) {
+                // tree.toString() does not know enough context to add ";",
+                // so deal with that manually...
+                Tree.Kind enclKind = tp.getParentPath().getLeaf().getKind();
+                //System.err.println("  encl: " +enclKind);
+                if (enclKind == Tree.Kind.CLASS || enclKind == Tree.Kind.BLOCK)
+                    expect += ";";
+            }
+            //System.err.println("expect: " + expect);
+
+            int start = (int)sourcePositions.getStartPosition(unit, tree);
+            if (start == Diagnostic.NOPOS) {
+                messager.printMessage(Diagnostic.Kind.ERROR, "start pos not set for " + trim(tree));
+                return;
+            }
+
+            int end = (int)sourcePositions.getEndPosition(unit, tree);
+            if (end == Diagnostic.NOPOS) {
+                messager.printMessage(Diagnostic.Kind.ERROR, "end pos not set for " + trim(tree));
+                return;
+            }
+
+            String found = source.substring(start, end);
+            //System.err.println(" found: " + found);
+
+            // allow for long lines, in which case just compare beginning and
+            // end of the strings
+            boolean equal;
+            if (found.contains("\n")) {
+                String head = found.substring(0, found.indexOf("\n"));
+                String tail = found.substring(found.lastIndexOf("\n")).trim();
+                equal = expect.startsWith(head) && expect.endsWith(tail);
+            } else {
+                equal = expect.equals(found);
+            }
+
+            if (!equal) {
+                messager.printMessage(Diagnostic.Kind.ERROR,
+                        "unexpected value found: '" + found + "'; expected: '" + expect + "'");
+            }
+        }
+
+        String trim(Tree tree) {
+            final int MAXLEN = 32;
+            String s = tree.toString().replaceAll("\\s+", " ").trim();
+            return (s.length() < MAXLEN) ? s : s.substring(0, MAXLEN);
+
+        }
+
+        CompilationUnitTree unit;
+        SourcePositions sourcePositions;
+        String source;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javah/VersionTest.java	Wed Jul 05 17:24:21 2017 +0200
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along 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 6890226
+ * @summary javah -version is broken
+ */
+
+import java.io.*;
+import java.util.Locale;
+
+public class VersionTest {
+    public static void main(String... args) {
+        Locale prev = Locale.getDefault();
+        try {
+            Locale.setDefault(Locale.ENGLISH);
+            System.err.println(Locale.getDefault());
+            test("-version", "\\S+ version \"\\S+\"");
+            test("-fullversion", "\\S+ full version \"\\S+\"");
+        } finally {
+            Locale.setDefault(prev);
+        }
+    }
+
+    static void test(String option, String regex) {
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        String[] args = { option };
+        int rc = com.sun.tools.javah.Main.run(args, pw);
+        pw.close();
+        if (rc != 0)
+            throw new Error("javah failed: rc=" + rc);
+        String out = sw.toString().trim();
+        System.err.println(out);
+        if (!out.matches(regex))
+            throw new Error("output does not match pattern: " + regex);
+    }
+}
--- a/make/jprt.properties	Wed Jul 05 17:23:40 2017 +0200
+++ b/make/jprt.properties	Wed Jul 05 17:24:21 2017 +0200
@@ -25,49 +25,310 @@
 
 # Properties for jprt
 
-# Use whatever release that the submitted job requests
+# At submit time, the release supplied will be in jprt.submit.release
+#    and will be one of the official release names defined in jprt.
+#    jprt supports property value expansion using ${property.name} syntax.
+
+# This tells jprt what default release we want to build
 jprt.tools.default.release=${jprt.submit.release}
 
 # The different build flavors we want, we override here so we just get these 2
 jprt.build.flavors=product,fastdebug
 
-# Shortened list of vm tests
-jprt.test.targets=              \
-  *-product-*-jvm98,            \
-  *-product-*-scimark,          \
-  *-product-*-runThese,         \
-  *-product-*-GCBasher_default, \
-  *-product-*-GCOld_default,    \
-  *-product-*-jbb_default
+# Define the Windows we want (temporary)
+jprt.my.windows.i586.jdk7b107=windows_i586_5.0
+jprt.my.windows.i586.jdk7temp=windows_i586_5.0
+jprt.my.windows.i586.jdk7=windows_i586_5.1
+jprt.my.windows.i586=${jprt.my.windows.i586.${jprt.tools.default.release}}
+
+# Standard list of jprt build targets for this source tree
+jprt.build.targets= 						\
+    solaris_sparc_5.10-{product|fastdebug}, 			\
+    solaris_sparcv9_5.10-{product|fastdebug}, 			\
+    solaris_i586_5.10-{product|fastdebug}, 			\
+    solaris_x64_5.10-{product|fastdebug}, 			\
+    linux_i586_2.6-{product|fastdebug}, 			\
+    linux_x64_2.6-{product|fastdebug}, 				\
+    ${jprt.my.windows.i586}-{product|fastdebug}, 		\
+    windows_x64_5.2-{product|fastdebug}
+
+# User can select the test set with jprt submit "-testset name" option
+jprt.my.test.set=${jprt.test.set}
+
+# Default vm test targets (no fastdebug & limited c2 testing)
+jprt.vm.default.test.targets=              			\
+    								\
+    solaris_sparc_5.10-product-c1-jvm98, 			\
+    solaris_sparcv9_5.10-product-c2-jvm98, 			\
+    solaris_i586_5.10-product-c1-jvm98, 			\
+    solaris_x64_5.10-product-c2-jvm98, 				\
+    linux_i586_2.6-product-{c1|c2}-jvm98, 			\
+    linux_x64_2.6-product-c2-jvm98, 				\
+    ${jprt.my.windows.i586}-product-c1-jvm98, 			\
+    windows_x64_5.2-product-c2-jvm98, 				\
+    								\
+    solaris_sparc_5.10-product-c1-scimark, 			\
+    solaris_sparcv9_5.10-product-c2-scimark, 			\
+    solaris_i586_5.10-product-c1-scimark, 			\
+    solaris_x64_5.10-product-c2-scimark, 			\
+    linux_i586_2.6-product-{c1|c2}-scimark, 			\
+    linux_x64_2.6-product-c2-scimark, 				\
+    ${jprt.my.windows.i586}-product-c1-scimark, 		\
+    windows_x64_5.2-product-c2-scimark
 
-# Test targets in test/Makefile
-jprt.make.rule.test.targets=   \
-  *-product-*-langtools_jtreg, \
-  *-product-*-jdk_beans1,      \
-  *-product-*-jdk_beans2,      \
-  *-product-*-jdk_beans3,      \
-  *-product-*-jdk_io,          \
-  *-product-*-jdk_lang,        \
-  *-product-*-jdk_management1, \
-  *-product-*-jdk_management2, \
-  *-product-*-jdk_math,        \
-  *-product-*-jdk_misc,        \
-  *-product-*-jdk_net,         \
-  *-product-*-jdk_nio1,        \
-  *-product-*-jdk_nio2,        \
-  *-product-*-jdk_nio3,        \
-  *-product-*-jdk_security1,   \
-  *-product-*-jdk_security2,   \
-  *-product-*-jdk_security3,   \
-  *-product-*-jdk_text,        \
-  *-product-*-jdk_tools1,      \
-  *-product-*-jdk_tools2,      \
-  *-product-*-jdk_util
+# Default jdk test targets in test/Makefile (no fastdebug & limited c2 testing)
+jprt.make.rule.default.test.targets=				\
+    								\
+    solaris_sparc_5.10-product-c1-langtools_jtreg, 		\
+    solaris_sparcv9_5.10-product-c2-langtools_jtreg, 		\
+    solaris_i586_5.10-product-c1-langtools_jtreg, 		\
+    solaris_x64_5.10-product-c2-langtools_jtreg, 		\
+    linux_i586_2.6-product-{c1|c2}-langtools_jtreg, 		\
+    linux_x64_2.6-product-c2-langtools_jtreg, 			\
+    ${jprt.my.windows.i586}-product-c1-langtools_jtreg, 	\
+    windows_x64_5.2-product-c2-langtools_jtreg, 		\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_beans1, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_beans1, 		\
+    solaris_i586_5.10-product-c1-jdk_beans1, 			\
+    solaris_x64_5.10-product-c2-jdk_beans1, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_beans1, 			\
+    linux_x64_2.6-product-c2-jdk_beans1, 			\
+    ${jprt.my.windows.i586}-product-c1-jdk_beans1, 		\
+    windows_x64_5.2-product-c2-jdk_beans1, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_io, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_io, 			\
+    solaris_i586_5.10-product-c1-jdk_io, 			\
+    solaris_x64_5.10-product-c2-jdk_io, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_io, 			\
+    linux_x64_2.6-product-c2-jdk_io, 				\
+    ${jprt.my.windows.i586}-product-c1-jdk_io, 			\
+    windows_x64_5.2-product-c2-jdk_io, 				\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_lang, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_lang, 			\
+    solaris_i586_5.10-product-c1-jdk_lang, 			\
+    solaris_x64_5.10-product-c2-jdk_lang, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_lang, 			\
+    linux_x64_2.6-product-c2-jdk_lang, 				\
+    ${jprt.my.windows.i586}-product-c1-jdk_lang, 		\
+    windows_x64_5.2-product-c2-jdk_lang, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_math, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_math, 			\
+    solaris_i586_5.10-product-c1-jdk_math, 			\
+    solaris_x64_5.10-product-c2-jdk_math, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_math, 			\
+    linux_x64_2.6-product-c2-jdk_math, 				\
+    ${jprt.my.windows.i586}-product-c1-jdk_math, 		\
+    windows_x64_5.2-product-c2-jdk_math, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_misc, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_misc, 			\
+    solaris_i586_5.10-product-c1-jdk_misc, 			\
+    solaris_x64_5.10-product-c2-jdk_misc, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_misc, 			\
+    linux_x64_2.6-product-c2-jdk_misc, 				\
+    ${jprt.my.windows.i586}-product-c1-jdk_misc, 		\
+    windows_x64_5.2-product-c2-jdk_misc, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_net, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_net, 			\
+    solaris_i586_5.10-product-c1-jdk_net, 			\
+    solaris_x64_5.10-product-c2-jdk_net, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_net, 			\
+    linux_x64_2.6-product-c2-jdk_net, 				\
+    ${jprt.my.windows.i586}-product-c1-jdk_net, 		\
+    windows_x64_5.2-product-c2-jdk_net, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_nio1, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_nio1, 			\
+    solaris_i586_5.10-product-c1-jdk_nio1, 			\
+    solaris_x64_5.10-product-c2-jdk_nio1, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_nio1, 			\
+    linux_x64_2.6-product-c2-jdk_nio1, 				\
+    ${jprt.my.windows.i586}-product-c1-jdk_nio1, 		\
+    windows_x64_5.2-product-c2-jdk_nio1, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_nio2, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_nio2, 			\
+    solaris_i586_5.10-product-c1-jdk_nio2, 			\
+    solaris_x64_5.10-product-c2-jdk_nio2, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_nio2, 			\
+    linux_x64_2.6-product-c2-jdk_nio2, 				\
+    ${jprt.my.windows.i586}-product-c1-jdk_nio2, 		\
+    windows_x64_5.2-product-c2-jdk_nio2, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_nio3, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_nio3, 			\
+    solaris_i586_5.10-product-c1-jdk_nio3, 			\
+    solaris_x64_5.10-product-c2-jdk_nio3, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_nio3, 			\
+    linux_x64_2.6-product-c2-jdk_nio3, 				\
+    ${jprt.my.windows.i586}-product-c1-jdk_nio3, 		\
+    windows_x64_5.2-product-c2-jdk_nio3, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_security1, 		\
+    solaris_sparcv9_5.10-product-c2-jdk_security1, 		\
+    solaris_i586_5.10-product-c1-jdk_security1, 		\
+    solaris_x64_5.10-product-c2-jdk_security1, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_security1, 		\
+    linux_x64_2.6-product-c2-jdk_security1, 			\
+    ${jprt.my.windows.i586}-product-c1-jdk_security1, 		\
+    windows_x64_5.2-product-c2-jdk_security1, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_text, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_text, 			\
+    solaris_i586_5.10-product-c1-jdk_text, 			\
+    solaris_x64_5.10-product-c2-jdk_text, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_text, 			\
+    linux_x64_2.6-product-c2-jdk_text, 				\
+    ${jprt.my.windows.i586}-product-c1-jdk_text, 		\
+    windows_x64_5.2-product-c2-jdk_text, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_tools1, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_tools1, 		\
+    solaris_i586_5.10-product-c1-jdk_tools1, 			\
+    solaris_x64_5.10-product-c2-jdk_tools1, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_tools1, 			\
+    linux_x64_2.6-product-c2-jdk_tools1, 			\
+    ${jprt.my.windows.i586}-product-c1-jdk_tools1, 		\
+    windows_x64_5.2-product-c2-jdk_tools1, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_util, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_util, 			\
+    solaris_i586_5.10-product-c1-jdk_util, 			\
+    solaris_x64_5.10-product-c2-jdk_util, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_util, 			\
+    linux_x64_2.6-product-c2-jdk_util, 				\
+    ${jprt.my.windows.i586}-product-c1-jdk_util, 		\
+    windows_x64_5.2-product-c2-jdk_util
 
-# Not Ready Yet:
-#   *-product-*-jdk_awt
-#   *-product-*-jdk_rmi
-#   *-product-*-jdk_swing
+# All vm test targets (but still no fastdebug & limited c2 testing)
+jprt.vm.all.test.targets=    					\
+    								\
+   ${jprt.vm.default.test.targets}, 				\
+    								\
+    solaris_sparc_5.10-product-c1-runThese, 			\
+    solaris_sparcv9_5.10-product-c2-runThese, 			\
+    solaris_i586_5.10-product-c1-runThese, 			\
+    solaris_x64_5.10-product-c2-runThese, 			\
+    linux_i586_2.6-product-{c1|c2}-runThese, 			\
+    linux_x64_2.6-product-c2-runThese, 				\
+    ${jprt.my.windows.i586}-product-c1-runThese, 		\
+    windows_x64_5.2-product-c2-runThese, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jbb_default, 			\
+    solaris_sparcv9_5.10-product-c2-jbb_default, 		\
+    solaris_i586_5.10-product-c1-jbb_default, 			\
+    solaris_x64_5.10-product-c2-jbb_default, 			\
+    linux_i586_2.6-product-{c1|c2}-jbb_default, 		\
+    linux_x64_2.6-product-c2-jbb_default, 			\
+    ${jprt.my.windows.i586}-product-c1-jbb_default, 		\
+    windows_x64_5.2-product-c2-jbb_default
+
+# All jdk test targets (but still no fastdebug & limited c2 testing)
+jprt.make.rule.all.test.targets=    				\
+    								\
+   ${jprt.make.rule.default.test.targets}, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_awt, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_awt, 			\
+    solaris_i586_5.10-product-c1-jdk_awt, 			\
+    solaris_x64_5.10-product-c2-jdk_awt, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_awt, 			\
+    linux_x64_2.6-product-c2-jdk_awt, 				\
+    ${jprt.my.windows.i586}-product-c1-jdk_awt, 		\
+    windows_x64_5.2-product-c2-jdk_awt, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_beans2, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_beans2, 		\
+    solaris_i586_5.10-product-c1-jdk_beans2, 			\
+    solaris_x64_5.10-product-c2-jdk_beans2, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_beans2, 			\
+    linux_x64_2.6-product-c2-jdk_beans2, 			\
+    ${jprt.my.windows.i586}-product-c1-jdk_beans2, 		\
+    windows_x64_5.2-product-c2-jdk_beans2, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_beans3, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_beans3, 		\
+    solaris_i586_5.10-product-c1-jdk_beans3, 			\
+    solaris_x64_5.10-product-c2-jdk_beans3, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_beans3, 			\
+    linux_x64_2.6-product-c2-jdk_beans3, 			\
+    ${jprt.my.windows.i586}-product-c1-jdk_beans3, 		\
+    windows_x64_5.2-product-c2-jdk_beans3, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_management1, 		\
+    solaris_sparcv9_5.10-product-c2-jdk_management1, 		\
+    solaris_i586_5.10-product-c1-jdk_management1, 		\
+    solaris_x64_5.10-product-c2-jdk_management1, 		\
+    linux_i586_2.6-product-{c1|c2}-jdk_management1, 		\
+    linux_x64_2.6-product-c2-jdk_management1, 			\
+    ${jprt.my.windows.i586}-product-c1-jdk_management1, 	\
+    windows_x64_5.2-product-c2-jdk_management1, 		\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_management2, 		\
+    solaris_sparcv9_5.10-product-c2-jdk_management2, 		\
+    solaris_i586_5.10-product-c1-jdk_management2, 		\
+    solaris_x64_5.10-product-c2-jdk_management2, 		\
+    linux_i586_2.6-product-{c1|c2}-jdk_management2, 		\
+    linux_x64_2.6-product-c2-jdk_management2, 			\
+    ${jprt.my.windows.i586}-product-c1-jdk_management2, 	\
+    windows_x64_5.2-product-c2-jdk_management2, 		\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_rmi, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_rmi, 			\
+    solaris_i586_5.10-product-c1-jdk_rmi, 			\
+    solaris_x64_5.10-product-c2-jdk_rmi, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_rmi, 			\
+    linux_x64_2.6-product-c2-jdk_rmi, 				\
+    ${jprt.my.windows.i586}-product-c1-jdk_rmi, 		\
+    windows_x64_5.2-product-c2-jdk_rmi, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_security2, 		\
+    solaris_sparcv9_5.10-product-c2-jdk_security2, 		\
+    solaris_i586_5.10-product-c1-jdk_security2, 		\
+    solaris_x64_5.10-product-c2-jdk_security2, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_security2, 		\
+    linux_x64_2.6-product-c2-jdk_security2, 			\
+    ${jprt.my.windows.i586}-product-c1-jdk_security2, 		\
+    windows_x64_5.2-product-c2-jdk_security2, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_security3, 		\
+    solaris_sparcv9_5.10-product-c2-jdk_security3, 		\
+    solaris_i586_5.10-product-c1-jdk_security3, 		\
+    solaris_x64_5.10-product-c2-jdk_security3, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_security3, 		\
+    linux_x64_2.6-product-c2-jdk_security3, 			\
+    ${jprt.my.windows.i586}-product-c1-jdk_security3, 		\
+    windows_x64_5.2-product-c2-jdk_security3, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_swing, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_swing, 			\
+    solaris_i586_5.10-product-c1-jdk_swing, 			\
+    solaris_x64_5.10-product-c2-jdk_swing, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_swing, 			\
+    linux_x64_2.6-product-c2-jdk_swing, 			\
+    ${jprt.my.windows.i586}-product-c1-jdk_swing, 		\
+    windows_x64_5.2-product-c2-jdk_swing, 			\
+    								\
+    solaris_sparc_5.10-product-c1-jdk_tools2, 			\
+    solaris_sparcv9_5.10-product-c2-jdk_tools2, 		\
+    solaris_i586_5.10-product-c1-jdk_tools2, 			\
+    solaris_x64_5.10-product-c2-jdk_tools2, 			\
+    linux_i586_2.6-product-{c1|c2}-jdk_tools2, 			\
+    linux_x64_2.6-product-c2-jdk_tools2, 			\
+    ${jprt.my.windows.i586}-product-c1-jdk_tools2, 		\
+    windows_x64_5.2-product-c2-jdk_tools2
+
+# Select list to use (allow for testset to be empty too)
+jprt.make.rule..test.targets=${jprt.make.rule.default.test.targets} 
+jprt.make.rule.test.targets=${jprt.make.rule.${jprt.my.test.set}.test.targets} 
+jprt.vm..test.targets=${jprt.vm.default.test.targets} 
+jprt.vm.test.targets=${jprt.vm.${jprt.my.test.set}.test.targets} 
+jprt.test.targets=${jprt.vm.test.targets} 
 
 # Directories to be excluded from the source bundles
 jprt.bundle.exclude.src.dirs=build dist webrev