Merge
authoramurillo
Thu, 28 Apr 2016 23:08:16 -0700
changeset 38127 2ab00cd4556e
parent 38125 1ad0239b6e4a (current diff)
parent 38126 c3706b502779 (diff)
child 38128 22391eb0c22d
Merge
hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp
hotspot/src/share/vm/prims/jvmtiExport.cpp
jdk/make/launcher/Launcher-jdk.jvmstat.rmi.gmk
jdk/src/java.base/share/classes/jdk/net/ExtendedSocketOptions.java
jdk/src/java.base/share/classes/jdk/net/NetworkPermission.java
jdk/src/java.base/share/classes/jdk/net/SocketFlow.java
jdk/src/java.base/share/classes/jdk/net/Sockets.java
jdk/src/java.base/share/classes/jdk/net/package-info.java
jdk/src/java.base/share/classes/sun/net/ExtendedOptionsImpl.java
jdk/src/java.base/share/classes/sun/security/action/GetBooleanSecurityPropertyAction.java
jdk/src/java.base/unix/native/libnet/ExtendedOptionsImpl.c
jdk/src/java.base/windows/native/libnet/ExtendedOptionsImpl.c
jdk/src/java.desktop/share/classes/sun/swing/UIClientPropertyKey.java
jdk/src/java.desktop/unix/native/common/awt/extutil.h
jdk/src/java.desktop/unix/native/libawt_headless/awt/VDrawingArea.c
jdk/src/java.desktop/unix/native/libawt_headless/awt/VDrawingArea.h
jdk/src/java.desktop/unix/native/libawt_headless/awt/VDrawingAreaP.h
jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/ExtractedImage.java
jdk/src/jdk.jvmstat.rmi/share/classes/module-info.java
jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/RemoteHost.java
jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/RemoteVm.java
jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/package.html
jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostProvider.java
jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostRmiService.java
jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/PerfDataBuffer.java
jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteMonitoredVm.java
jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteVmManager.java
jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/package.html
jdk/src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/Jstatd.java
jdk/src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/RemoteHostImpl.java
jdk/src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/RemoteVmImpl.java
jdk/src/jdk.unsupported/share/classes/sun/misc/ManagedLocalsThread.java
jdk/test/java/util/ServiceLoader/modules/BasicTest.java
jdk/test/sanity/client/lib/Jemmy2Ext/src/org/jemmy2ext/JemmyExt.java
langtools/test/tools/javac/SerialWarn.java
langtools/test/tools/javac/SerialWarn.out
langtools/test/tools/javac/positions/T6253161.java
langtools/test/tools/javac/positions/T6253161.out
langtools/test/tools/javac/positions/T6253161a.java
langtools/test/tools/javac/positions/T6253161a.out
nashorn/test/script/basic/yield.js
--- a/.hgtags	Fri Apr 29 04:44:08 2016 +0200
+++ b/.hgtags	Thu Apr 28 23:08:16 2016 -0700
@@ -357,3 +357,5 @@
 7359994942f8d8e723b584d66a3a92c2e9e95e5c jdk-9+112
 6072af7a98be3922f26bdce71b53bb3646cb2ac9 jdk-9+113
 c84d0cce090e161d736de69e941830adf8c2f87a jdk-9+114
+8d78fb40648dd221ce4ef19f9d5aa41ee1a3a884 jdk-9+115
+84aba7335005a3a47751dcf1f37935f97df9f99a jdk-9+116
--- a/.hgtags-top-repo	Fri Apr 29 04:44:08 2016 +0200
+++ b/.hgtags-top-repo	Thu Apr 28 23:08:16 2016 -0700
@@ -357,3 +357,5 @@
 03543a758cd5890f2266e4b9678378a925dde22a jdk-9+112
 55b6d550828d1223b364e6ead4a56e56411c56df jdk-9+113
 1d992540870ff33fe6cc550443388588df9b9e4f jdk-9+114
+09617ce980b99d49abfd54dacfed353c47e2a115 jdk-9+115
+6743a8e0cab7b5f6f4a0575f6664892f0ab740af jdk-9+116
--- a/common/autoconf/basics.m4	Fri Apr 29 04:44:08 2016 +0200
+++ b/common/autoconf/basics.m4	Thu Apr 28 23:08:16 2016 -0700
@@ -749,8 +749,8 @@
   BASIC_PREPEND_TO_PATH([PATH],$EXTRA_PATH)
 
   if test "x$OPENJDK_BUILD_OS" = "xsolaris"; then
-    # Add extra search paths on solaris for utilities like ar and as etc...
-    PATH="$PATH:/usr/ccs/bin:/usr/sfw/bin:/opt/csw/bin"
+    # Add extra search paths on solaris for utilities like ar, as, dtrace etc...
+    PATH="$PATH:/usr/ccs/bin:/usr/sfw/bin:/opt/csw/bin:/usr/sbin"
   fi
 
   AC_MSG_CHECKING([for sysroot])
@@ -777,7 +777,7 @@
     # Create a default ./build/target-variant-debuglevel output root.
     if test "x${CONF_NAME}" = x; then
       AC_MSG_RESULT([in default location])
-      CONF_NAME="${OPENJDK_TARGET_OS}-${OPENJDK_TARGET_CPU}-${JDK_VARIANT}-${ANDED_JVM_VARIANTS}-${DEBUG_LEVEL}"
+      CONF_NAME="${OPENJDK_TARGET_OS}-${OPENJDK_TARGET_CPU}-${JDK_VARIANT}-${JVM_VARIANTS_WITH_AND}-${DEBUG_LEVEL}"
     else
       AC_MSG_RESULT([in build directory with custom name])
     fi
@@ -1037,6 +1037,7 @@
   BASIC_PATH_PROGS(HG, hg)
   BASIC_PATH_PROGS(STAT, stat)
   BASIC_PATH_PROGS(TIME, time)
+  BASIC_PATH_PROGS(DTRACE, dtrace)
   BASIC_PATH_PROGS(PATCH, [gpatch patch])
   # Check if it's GNU time
   IS_GNU_TIME=`$TIME --version 2>&1 | $GREP 'GNU time'`
--- a/common/autoconf/boot-jdk.m4	Fri Apr 29 04:44:08 2016 +0200
+++ b/common/autoconf/boot-jdk.m4	Thu Apr 28 23:08:16 2016 -0700
@@ -397,6 +397,7 @@
   ADD_JVM_ARG_IF_OK([-XX:+UseSerialGC],boot_jdk_jvmargs_small,[$JAVA])
   ADD_JVM_ARG_IF_OK([-Xms32M],boot_jdk_jvmargs_small,[$JAVA])
   ADD_JVM_ARG_IF_OK([-Xmx512M],boot_jdk_jvmargs_small,[$JAVA])
+  ADD_JVM_ARG_IF_OK([-XX:TieredStopAtLevel=1],boot_jdk_jvmargs_small,[$JAVA])
 
   AC_MSG_RESULT([$boot_jdk_jvmargs_small])
 
--- a/common/autoconf/build-performance.m4	Fri Apr 29 04:44:08 2016 +0200
+++ b/common/autoconf/build-performance.m4	Thu Apr 28 23:08:16 2016 -0700
@@ -364,6 +364,9 @@
   elif test "x$ICECC" != "x"; then
     AC_MSG_RESULT([no, does not work effectively with icecc])
     USE_PRECOMPILED_HEADER=0
+  elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+    AC_MSG_RESULT([no, does not work with Solaris Studio])
+    USE_PRECOMPILED_HEADER=0
   else
     AC_MSG_RESULT([yes])
   fi
--- a/common/autoconf/buildjdk-spec.gmk.in	Fri Apr 29 04:44:08 2016 +0200
+++ b/common/autoconf/buildjdk-spec.gmk.in	Thu Apr 28 23:08:16 2016 -0700
@@ -57,6 +57,12 @@
 OPENJDK_TARGET_CPU_ENDIAN := @OPENJDK_BUILD_CPU_ENDIAN@
 OPENJDK_TARGET_CPU_LEGACY := @OPENJDK_BUILD_CPU_LEGACY@
 
+HOTSPOT_TARGET_OS := @HOTSPOT_BUILD_OS@
+HOTSPOT_TARGET_OS_TYPE := @HOTSPOT_BUILD_OS_TYPE@
+HOTSPOT_TARGET_CPU := @HOTSPOT_BUILD_CPU@
+HOTSPOT_TARGET_CPU_ARCH := @HOTSPOT_BUILD_CPU_ARCH@
+HOTSPOT_TARGET_CPU_DEFINE := @HOTSPOT_BUILD_CPU_DEFINE@
+
 CFLAGS_JDKLIB := @OPENJDK_BUILD_CFLAGS_JDKLIB@
 CXXFLAGS_JDKLIB := @OPENJDK_BUILD_CXXFLAGS_JDKLIB@
 LDFLAGS_JDKLIB := @OPENJDK_BUILD_LDFLAGS_JDKLIB@
@@ -65,6 +71,11 @@
 LDFLAGS_JDKEXE := @OPENJDK_BUILD_LDFLAGS_JDKEXE@
 OPENJDK_TARGET_CPU_JLI_CFLAGS := @OPENJDK_BUILD_CPU_JLI_CFLAGS@
 
+JVM_CFLAGS := @OPENJDK_BUILD_JVM_CFLAGS@
+JVM_LDFLAGS := @OPENJDK_BUILD_JVM_LDFLAGS@
+JVM_ASFLAGS := @OPENJDK_BUILD_JVM_ASFLAGS@
+JVM_LIBS := @OPENJDK_BUILD_JVM_LIBS@
+
 # The compiler for the build platform is likely not warning compatible with the official
 # compiler.
 WARNINGS_AS_ERRORS := false
--- a/common/autoconf/configure	Fri Apr 29 04:44:08 2016 +0200
+++ b/common/autoconf/configure	Thu Apr 28 23:08:16 2016 -0700
@@ -283,7 +283,7 @@
 
 EOT
 
-    # Print additional help, e.g. a list of toolchains.
+    # Print additional help, e.g. a list of toolchains and JVM features.
     # This must be done by the autoconf script.
     ( CONFIGURE_PRINT_ADDITIONAL_HELP=true . $conf_script_to_run PRINTF=printf )
 
--- a/common/autoconf/configure.ac	Fri Apr 29 04:44:08 2016 +0200
+++ b/common/autoconf/configure.ac	Thu Apr 28 23:08:16 2016 -0700
@@ -95,10 +95,8 @@
 
 # These are needed to be able to create a configuration name (and thus the output directory)
 JDKOPT_SETUP_JDK_VARIANT
-HOTSPOT_SETUP_JVM_INTERPRETER
+JDKOPT_SETUP_DEBUG_LEVEL
 HOTSPOT_SETUP_JVM_VARIANTS
-JDKOPT_SETUP_DEBUG_LEVEL
-HOTSPOT_SETUP_DEBUG_LEVEL
 
 # With basic setup done, call the custom early hook.
 CUSTOM_EARLY_HOOK
@@ -135,7 +133,6 @@
 # We need build & target for this.
 JDKOPT_SETUP_JDK_OPTIONS
 JDKOPT_SETUP_JLINK_OPTIONS
-HOTSPOT_SETUP_HOTSPOT_OPTIONS
 JDKVER_SETUP_JDK_VERSION_NUMBERS
 
 ###############################################################################
@@ -207,6 +204,10 @@
 JDKOPT_SETUP_DEBUG_SYMBOLS
 JDKOPT_SETUP_CODE_COVERAGE
 
+# Need toolchain to setup dtrace
+HOTSPOT_SETUP_DTRACE
+HOTSPOT_SETUP_JVM_FEATURES
+
 ###############################################################################
 #
 # Check dependencies for external and internal libraries.
@@ -225,7 +226,7 @@
 #
 ###############################################################################
 
-HOTSPOT_SETUP_BUILD_TWEAKS
+HOTSPOT_SETUP_LEGACY_BUILD
 JDKOPT_DETECT_INTREE_EC
 JDKOPT_ENABLE_DISABLE_FAILURE_HANDLER
 
@@ -268,6 +269,9 @@
 # At the end, call the custom hook. (Dummy macro if no custom sources available)
 CUSTOM_LATE_HOOK
 
+# This needs to be done after CUSTOM_LATE_HOOK since we can setup custom features.
+HOTSPOT_VALIDATE_JVM_FEATURES
+
 # We're messing a bit with internal autoconf variables to put the config.status
 # in the output directory instead of the current directory.
 CONFIG_STATUS="$CONFIGURESUPPORT_OUTPUTDIR/config.status"
--- a/common/autoconf/flags.m4	Fri Apr 29 04:44:08 2016 +0200
+++ b/common/autoconf/flags.m4	Thu Apr 28 23:08:16 2016 -0700
@@ -61,6 +61,10 @@
   AC_SUBST(LEGACY_EXTRA_CXXFLAGS)
   AC_SUBST(LEGACY_EXTRA_LDFLAGS)
 
+  AC_SUBST(EXTRA_CFLAGS)
+  AC_SUBST(EXTRA_CXXFLAGS)
+  AC_SUBST(EXTRA_LDFLAGS)
+
   # The global CFLAGS and LDLAGS variables are used by configure tests and
   # should include the extra parameters
   CFLAGS="$EXTRA_CFLAGS"
@@ -211,8 +215,10 @@
   # On Windows, we need to set RC flags.
   if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
     RC_FLAGS="-nologo -l0x409"
+    JVM_RCFLAGS="-nologo"
     if test "x$DEBUG_LEVEL" = xrelease; then
       RC_FLAGS="$RC_FLAGS -DNDEBUG"
+      JVM_RCFLAGS="$JVM_RCFLAGS -DNDEBUG"
     fi
 
     # The version variables used to create RC_FLAGS may be overridden
@@ -228,8 +234,19 @@
         -D\"JDK_COPYRIGHT=Copyright \xA9 $COPYRIGHT_YEAR\" \
         -D\"JDK_NAME=\$(PRODUCT_NAME) \$(JDK_RC_PLATFORM_NAME) \$(VERSION_MAJOR)\" \
         -D\"JDK_FVER=\$(subst .,\$(COMMA),\$(VERSION_NUMBER_FOUR_POSITIONS))\""
+
+    JVM_RCFLAGS="$JVM_RCFLAGS \
+        -D\"HS_BUILD_ID=\$(VERSION_STRING)\" \
+        -D\"HS_COMPANY=\$(COMPANY_NAME)\" \
+        -D\"JDK_DOTVER=\$(VERSION_NUMBER_FOUR_POSITIONS)\" \
+        -D\"HS_COPYRIGHT=Copyright $COPYRIGHT_YEAR\" \
+        -D\"HS_NAME=\$(PRODUCT_NAME) \$(VERSION_SHORT)\" \
+        -D\"JDK_VER=\$(subst .,\$(COMMA),\$(VERSION_NUMBER_FOUR_POSITIONS))\" \
+        -D\"HS_FNAME=jvm.dll\" \
+        -D\"HS_INTERNAL_NAME=jvm\""
   fi
   AC_SUBST(RC_FLAGS)
+  AC_SUBST(JVM_RCFLAGS)
 
   if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
     # silence copyright notice and other headers.
@@ -237,7 +254,7 @@
   fi
 ])
 
-AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_FOR_LIBS],
+AC_DEFUN([FLAGS_SETUP_COMPILER_FLAGS_FOR_LIBS],
 [
   ###############################################################################
   #
@@ -255,6 +272,7 @@
         SHARED_LIBRARY_FLAGS ='-undefined dynamic_lookup'
       else
         SHARED_LIBRARY_FLAGS="-dynamiclib -compatibility_version 1.0.0 -current_version 1.0.0 $PICFLAG"
+        JVM_CFLAGS="$JVM_CFLAGS $PICFLAG"
       fi
       SET_EXECUTABLE_ORIGIN='-Wl,-rpath,@loader_path/.'
       SET_SHARED_LIBRARY_ORIGIN="$SET_EXECUTABLE_ORIGIN"
@@ -280,6 +298,10 @@
       SET_SHARED_LIBRARY_ORIGIN="$SET_EXECUTABLE_ORIGIN"
       SET_SHARED_LIBRARY_NAME='-Wl,-install_name,@rpath/[$]1'
       SET_SHARED_LIBRARY_MAPFILE='-Wl,-exported_symbols_list,[$]1'
+
+      if test "x$STATIC_BUILD" = xfalse; then
+        JVM_CFLAGS="$JVM_CFLAGS -fPIC"
+      fi
     else
       # Default works for linux, might work on other platforms as well.
       PICFLAG='-fPIC'
@@ -339,11 +361,6 @@
   AC_SUBST(SET_SHARED_LIBRARY_MAPFILE)
   AC_SUBST(SHARED_LIBRARY_FLAGS)
 
-  if test "x$OPENJDK_TARGET_OS" = xsolaris; then
-    CFLAGS_JDK="${CFLAGS_JDK} -D__solaris__"
-    CXXFLAGS_JDK="${CXXFLAGS_JDK} -D__solaris__"
-    CFLAGS_JDKLIB_EXTRA='-xstrconst'
-  fi
   # The (cross) compiler is now configured, we can now test capabilities
   # of the target platform.
 ])
@@ -434,6 +451,22 @@
   AC_SUBST(CFLAGS_DEBUG_SYMBOLS)
   AC_SUBST(CXXFLAGS_DEBUG_SYMBOLS)
 
+  # Debug symbols for JVM_CFLAGS
+  if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+    JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -xs"
+    if test "x$DEBUG_LEVEL" = xslowdebug; then
+      JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -g"
+    else
+      # -g0 does not disable inlining, which -g does.
+      JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -g0"
+    fi
+  elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+    JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -Z7 -d2Zi+"
+  else
+    JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -g"
+  fi
+  AC_SUBST(JVM_CFLAGS_SYMBOLS)
+
   # bounds, memory and behavior checking options
   if test "x$TOOLCHAIN_TYPE" = xgcc; then
     case $DEBUG_LEVEL in
@@ -444,7 +477,7 @@
       # no adjustment
       ;;
     slowdebug )
-      # FIXME: By adding this to C(XX)FLAGS_DEBUG_OPTIONS it
+      # FIXME: By adding this to C(XX)FLAGS_DEBUG_OPTIONS/JVM_CFLAGS_SYMBOLS it
       # get's added conditionally on whether we produce debug symbols or not.
       # This is most likely not really correct.
 
@@ -455,40 +488,59 @@
 
       CFLAGS_DEBUG_OPTIONS="$STACK_PROTECTOR_CFLAG --param ssp-buffer-size=1"
       CXXFLAGS_DEBUG_OPTIONS="$STACK_PROTECTOR_CFLAG --param ssp-buffer-size=1"
+      if test "x$STACK_PROTECTOR_CFLAG" != x; then
+        JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS $STACK_PROTECTOR_CFLAG --param ssp-buffer-size=1"
+      fi
       ;;
     esac
   fi
 
+  if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+    if test "x$DEBUG_LEVEL" != xrelease; then
+      if test "x$OPENJDK_TARGET_CPU" = xx86_64; then
+        JVM_CFLAGS="$JVM_CFLAGS -homeparams"
+      fi
+    fi
+  fi
+
   # Optimization levels
   if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
     CC_HIGHEST="$CC_HIGHEST -fns -fsimple -fsingle -xbuiltin=%all -xdepend -xrestrict -xlibmil"
 
     if test "x$OPENJDK_TARGET_CPU_ARCH" = "xx86"; then
       # FIXME: seems we always set -xregs=no%frameptr; put it elsewhere more global?
+      C_O_FLAG_HIGHEST_JVM="-xO4"
       C_O_FLAG_HIGHEST="-xO4 -Wu,-O4~yz $CC_HIGHEST -xalias_level=basic -xregs=no%frameptr"
       C_O_FLAG_HI="-xO4 -Wu,-O4~yz -xregs=no%frameptr"
       C_O_FLAG_NORM="-xO2 -Wu,-O2~yz -xregs=no%frameptr"
       C_O_FLAG_DEBUG="-xregs=no%frameptr"
+      C_O_FLAG_DEBUG_JVM=""
       C_O_FLAG_NONE="-xregs=no%frameptr"
+      CXX_O_FLAG_HIGHEST_JVM="-xO4"
       CXX_O_FLAG_HIGHEST="-xO4 -Qoption ube -O4~yz $CC_HIGHEST -xregs=no%frameptr"
       CXX_O_FLAG_HI="-xO4 -Qoption ube -O4~yz -xregs=no%frameptr"
       CXX_O_FLAG_NORM="-xO2 -Qoption ube -O2~yz -xregs=no%frameptr"
       CXX_O_FLAG_DEBUG="-xregs=no%frameptr"
+      CXX_O_FLAG_DEBUG_JVM=""
       CXX_O_FLAG_NONE="-xregs=no%frameptr"
       if test "x$OPENJDK_TARGET_CPU_BITS" = "x32"; then
         C_O_FLAG_HIGHEST="$C_O_FLAG_HIGHEST -xchip=pentium"
         CXX_O_FLAG_HIGHEST="$CXX_O_FLAG_HIGHEST -xchip=pentium"
       fi
     elif test "x$OPENJDK_TARGET_CPU_ARCH" = "xsparc"; then
+      C_O_FLAG_HIGHEST_JVM="-xO4"
       C_O_FLAG_HIGHEST="-xO4 -Wc,-Qrm-s -Wc,-Qiselect-T0 $CC_HIGHEST -xalias_level=basic -xprefetch=auto,explicit -xchip=ultra"
       C_O_FLAG_HI="-xO4 -Wc,-Qrm-s -Wc,-Qiselect-T0"
       C_O_FLAG_NORM="-xO2 -Wc,-Qrm-s -Wc,-Qiselect-T0"
       C_O_FLAG_DEBUG=""
+      C_O_FLAG_DEBUG_JVM=""
       C_O_FLAG_NONE=""
+      CXX_O_FLAG_HIGHEST_JVM="-xO4"
       CXX_O_FLAG_HIGHEST="-xO4 -Qoption cg -Qrm-s -Qoption cg -Qiselect-T0 $CC_HIGHEST -xprefetch=auto,explicit -xchip=ultra"
       CXX_O_FLAG_HI="-xO4 -Qoption cg -Qrm-s -Qoption cg -Qiselect-T0"
       CXX_O_FLAG_NORM="-xO2 -Qoption cg -Qrm-s -Qoption cg -Qiselect-T0"
       CXX_O_FLAG_DEBUG=""
+      CXX_O_FLAG_DEBUG_JVM=""
       CXX_O_FLAG_NONE=""
     fi
   else
@@ -498,48 +550,75 @@
       if test "x$OPENJDK_TARGET_OS" = xmacosx; then
         # On MacOSX we optimize for size, something
         # we should do for all platforms?
+        C_O_FLAG_HIGHEST_JVM="-Os"
         C_O_FLAG_HIGHEST="-Os"
         C_O_FLAG_HI="-Os"
         C_O_FLAG_NORM="-Os"
+        C_O_FLAG_SIZE="-Os"
       else
+        C_O_FLAG_HIGHEST_JVM="-O3"
         C_O_FLAG_HIGHEST="-O3"
         C_O_FLAG_HI="-O3"
         C_O_FLAG_NORM="-O2"
+        C_O_FLAG_SIZE="-Os"
       fi
       C_O_FLAG_DEBUG="-O0"
+      if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+        C_O_FLAG_DEBUG_JVM=""
+      elif test "x$OPENJDK_TARGET_OS" = xlinux; then
+        C_O_FLAG_DEBUG_JVM="-O0"
+      fi
       C_O_FLAG_NONE="-O0"
     elif test "x$TOOLCHAIN_TYPE" = xclang; then
       if test "x$OPENJDK_TARGET_OS" = xmacosx; then
         # On MacOSX we optimize for size, something
         # we should do for all platforms?
+        C_O_FLAG_HIGHEST_JVM="-Os"
         C_O_FLAG_HIGHEST="-Os"
         C_O_FLAG_HI="-Os"
         C_O_FLAG_NORM="-Os"
+        C_O_FLAG_SIZE="-Os"
       else
+        C_O_FLAG_HIGHEST_JVM="-O3"
         C_O_FLAG_HIGHEST="-O3"
         C_O_FLAG_HI="-O3"
         C_O_FLAG_NORM="-O2"
+        C_O_FLAG_SIZE="-Os"
       fi
       C_O_FLAG_DEBUG="-O0"
+      if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+        C_O_FLAG_DEBUG_JVM=""
+      elif test "x$OPENJDK_TARGET_OS" = xlinux; then
+        C_O_FLAG_DEBUG_JVM="-O0"
+      fi
       C_O_FLAG_NONE="-O0"
     elif test "x$TOOLCHAIN_TYPE" = xxlc; then
+      C_O_FLAG_HIGHEST_JVM="-O3"
       C_O_FLAG_HIGHEST="-O3"
       C_O_FLAG_HI="-O3 -qstrict"
       C_O_FLAG_NORM="-O2"
       C_O_FLAG_DEBUG="-qnoopt"
+      # FIXME: Value below not verified.
+      C_O_FLAG_DEBUG_JVM=""
       C_O_FLAG_NONE="-qnoopt"
     elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+      C_O_FLAG_HIGHEST_JVM="-O2 -Oy-"
       C_O_FLAG_HIGHEST="-O2"
       C_O_FLAG_HI="-O1"
       C_O_FLAG_NORM="-O1"
       C_O_FLAG_DEBUG="-Od"
+      C_O_FLAG_DEBUG_JVM=""
       C_O_FLAG_NONE="-Od"
+      C_O_FLAG_SIZE="-Os"
     fi
+    CXX_O_FLAG_HIGHEST_JVM="$C_O_FLAG_HIGHEST_JVM"
     CXX_O_FLAG_HIGHEST="$C_O_FLAG_HIGHEST"
     CXX_O_FLAG_HI="$C_O_FLAG_HI"
     CXX_O_FLAG_NORM="$C_O_FLAG_NORM"
     CXX_O_FLAG_DEBUG="$C_O_FLAG_DEBUG"
+    CXX_O_FLAG_DEBUG_JVM="$C_O_FLAG_DEBUG_JVM"
     CXX_O_FLAG_NONE="$C_O_FLAG_NONE"
+    CXX_O_FLAG_SIZE="$C_O_FLAG_SIZE"
   fi
 
   # Adjust optimization flags according to debug level.
@@ -554,51 +633,105 @@
       ;;
     slowdebug )
       # Disable optimization
+      C_O_FLAG_HIGHEST_JVM="$C_O_FLAG_DEBUG_JVM"
       C_O_FLAG_HIGHEST="$C_O_FLAG_DEBUG"
       C_O_FLAG_HI="$C_O_FLAG_DEBUG"
       C_O_FLAG_NORM="$C_O_FLAG_DEBUG"
+      C_O_FLAG_SIZE="$C_O_FLAG_DEBUG"
+      CXX_O_FLAG_HIGHEST_JVM="$CXX_O_FLAG_DEBUG_JVM"
       CXX_O_FLAG_HIGHEST="$CXX_O_FLAG_DEBUG"
       CXX_O_FLAG_HI="$CXX_O_FLAG_DEBUG"
       CXX_O_FLAG_NORM="$CXX_O_FLAG_DEBUG"
+      CXX_O_FLAG_SIZE="$CXX_O_FLAG_DEBUG"
       ;;
   esac
 
+  AC_SUBST(C_O_FLAG_HIGHEST_JVM)
   AC_SUBST(C_O_FLAG_HIGHEST)
   AC_SUBST(C_O_FLAG_HI)
   AC_SUBST(C_O_FLAG_NORM)
   AC_SUBST(C_O_FLAG_DEBUG)
   AC_SUBST(C_O_FLAG_NONE)
+  AC_SUBST(C_O_FLAG_SIZE)
+  AC_SUBST(CXX_O_FLAG_HIGHEST_JVM)
   AC_SUBST(CXX_O_FLAG_HIGHEST)
   AC_SUBST(CXX_O_FLAG_HI)
   AC_SUBST(CXX_O_FLAG_NORM)
   AC_SUBST(CXX_O_FLAG_DEBUG)
   AC_SUBST(CXX_O_FLAG_NONE)
+  AC_SUBST(CXX_O_FLAG_SIZE)
 ])
 
-AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK],
+
+AC_DEFUN([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK],
+[
+
+  FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK_HELPER([TARGET])
+  FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK_HELPER([BUILD], [OPENJDK_BUILD_])
+
+  # Tests are only ever compiled for TARGET
+  # Flags for compiling test libraries
+  CFLAGS_TESTLIB="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK $PICFLAG $CFLAGS_JDKLIB_EXTRA"
+  CXXFLAGS_TESTLIB="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK $PICFLAG $CXXFLAGS_JDKLIB_EXTRA"
+
+  # Flags for compiling test executables
+  CFLAGS_TESTEXE="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK"
+  CXXFLAGS_TESTEXE="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK"
+
+  AC_SUBST(CFLAGS_TESTLIB)
+  AC_SUBST(CFLAGS_TESTEXE)
+  AC_SUBST(CXXFLAGS_TESTLIB)
+  AC_SUBST(CXXFLAGS_TESTEXE)
+
+  LDFLAGS_TESTLIB="$LDFLAGS_JDKLIB"
+  LDFLAGS_TESTEXE="$LDFLAGS_JDKEXE"
+
+  AC_SUBST(LDFLAGS_TESTLIB)
+  AC_SUBST(LDFLAGS_TESTEXE)
+
+])
+
+################################################################################
+# $1 - Either BUILD or TARGET to pick the correct OS/CPU variables to check
+#      conditionals against.
+# $2 - Optional prefix for each variable defined.
+AC_DEFUN([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK_HELPER],
 [
   # Special extras...
   if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
-    if test "x$OPENJDK_TARGET_CPU_ARCH" = "xsparc"; then
-      CFLAGS_JDKLIB_EXTRA="${CFLAGS_JDKLIB_EXTRA} -xregs=no%appl"
-      CXXFLAGS_JDKLIB_EXTRA="${CXXFLAGS_JDKLIB_EXTRA} -xregs=no%appl"
+    if test "x$OPENJDK_$1_CPU_ARCH" = "xsparc"; then
+      $2CFLAGS_JDKLIB_EXTRA="${$2CFLAGS_JDKLIB_EXTRA} -xregs=no%appl"
+      $2CXXFLAGS_JDKLIB_EXTRA="${$2CXXFLAGS_JDKLIB_EXTRA} -xregs=no%appl"
     fi
-    CFLAGS_JDKLIB_EXTRA="${CFLAGS_JDKLIB_EXTRA} -errtags=yes -errfmt"
-    CXXFLAGS_JDKLIB_EXTRA="${CXXFLAGS_JDKLIB_EXTRA} -errtags=yes -errfmt"
+    $2CFLAGS_JDKLIB_EXTRA="${$2CFLAGS_JDKLIB_EXTRA} -errtags=yes -errfmt"
+    $2CXXFLAGS_JDKLIB_EXTRA="${$2CXXFLAGS_JDKLIB_EXTRA} -errtags=yes -errfmt"
   elif test "x$TOOLCHAIN_TYPE" = xxlc; then
+    $2CFLAGS_JDK="${$2CFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
+    $2CXXFLAGS_JDK="${$2CXXFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
+  elif test "x$TOOLCHAIN_TYPE" = xgcc; then
+    $2CXXSTD_CXXFLAG="-std=gnu++98"
+    FLAGS_CXX_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [[$]$2CXXSTD_CXXFLAG -Werror],
+    						 IF_FALSE: [$2CXXSTD_CXXFLAG=""])
+    $2CXXFLAGS_JDK="${$2CXXFLAGS_JDK} ${$2CXXSTD_CXXFLAG}"
+    AC_SUBST([$2CXXSTD_CXXFLAG])
+  fi
+  if test "x$OPENJDK_TARGET_OS" = xsolaris; then
+    $2CFLAGS_JDK="${$2CFLAGS_JDK} -D__solaris__"
+    $2CXXFLAGS_JDK="${$2CXXFLAGS_JDK} -D__solaris__"
+    $2CFLAGS_JDKLIB_EXTRA='-xstrconst'
     CFLAGS_JDK="${CFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
     CXXFLAGS_JDK="${CXXFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
-  elif test "x$TOOLCHAIN_TYPE" = xgcc; then
-    CXXSTD_CXXFLAG="-std=gnu++98"
-    FLAGS_CXX_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [$CXXSTD_CXXFLAG -Werror],
-    						 IF_FALSE: [CXXSTD_CXXFLAG=""])
-    CXXFLAGS_JDK="${CXXFLAGS_JDK} ${CXXSTD_CXXFLAG}"
-    AC_SUBST([CXXSTD_CXXFLAG])
   fi
 
-  CFLAGS_JDK="${CFLAGS_JDK} $EXTRA_CFLAGS"
-  CXXFLAGS_JDK="${CXXFLAGS_JDK} $EXTRA_CXXFLAGS"
-  LDFLAGS_JDK="${LDFLAGS_JDK} $EXTRA_LDFLAGS"
+  if test "x$OPENJDK_TARGET_OS" = xsolaris; then
+    $2CFLAGS_JDK="${$2CFLAGS_JDK} -D__solaris__"
+    $2CXXFLAGS_JDK="${$2CXXFLAGS_JDK} -D__solaris__"
+    $2CFLAGS_JDKLIB_EXTRA='-xstrconst'
+  fi
+
+  $2CFLAGS_JDK="${$2CFLAGS_JDK} ${$2EXTRA_CFLAGS}"
+  $2CXXFLAGS_JDK="${$2CXXFLAGS_JDK} ${$2EXTRA_CXXFLAGS}"
+  $2LDFLAGS_JDK="${$2LDFLAGS_JDK} ${$2EXTRA_LDFLAGS}"
 
   ###############################################################################
   #
@@ -607,79 +740,94 @@
   #
 
   # Setup compiler/platform specific flags into
-  #    CFLAGS_JDK    - C Compiler flags
-  #    CXXFLAGS_JDK  - C++ Compiler flags
-  #    COMMON_CCXXFLAGS_JDK - common to C and C++
+  #    $2CFLAGS_JDK    - C Compiler flags
+  #    $2CXXFLAGS_JDK  - C++ Compiler flags
+  #    $2COMMON_CCXXFLAGS_JDK - common to C and C++
   if test "x$TOOLCHAIN_TYPE" = xgcc; then
-    if test "x$OPENJDK_TARGET_CPU" = xx86; then
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_GNU_SOURCE"
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_REENTRANT"
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -fcheck-new"
+    if test "x$OPENJDK_$1_CPU" = xx86; then
       # Force compatibility with i586 on 32 bit intel platforms.
-      COMMON_CCXXFLAGS="${COMMON_CCXXFLAGS} -march=i586"
+      $2COMMON_CCXXFLAGS="${$2COMMON_CCXXFLAGS} -march=i586"
+      $2JVM_CFLAGS="[$]$2JVM_CFLAGS -march=i586"
     fi
-    COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS $COMMON_CCXXFLAGS_JDK -Wall -Wextra -Wno-unused -Wno-unused-parameter -Wformat=2 \
+    $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS [$]$2COMMON_CCXXFLAGS_JDK -Wall -Wextra -Wno-unused -Wno-unused-parameter -Wformat=2 \
         -pipe -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE"
-    case $OPENJDK_TARGET_CPU_ARCH in
+    case $OPENJDK_$1_CPU_ARCH in
       arm )
         # on arm we don't prevent gcc to omit frame pointer but do prevent strict aliasing
-        CFLAGS_JDK="${CFLAGS_JDK} -fno-strict-aliasing"
+        $2CFLAGS_JDK="${$2CFLAGS_JDK} -fno-strict-aliasing"
         ;;
       ppc )
         # on ppc we don't prevent gcc to omit frame pointer but do prevent strict aliasing
-        CFLAGS_JDK="${CFLAGS_JDK} -fno-strict-aliasing"
+        $2CFLAGS_JDK="${$2CFLAGS_JDK} -fno-strict-aliasing"
         ;;
       * )
-        COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer"
-        CFLAGS_JDK="${CFLAGS_JDK} -fno-strict-aliasing"
+        $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer"
+        $2CFLAGS_JDK="${$2CFLAGS_JDK} -fno-strict-aliasing"
         ;;
     esac
     TOOLCHAIN_CHECK_COMPILER_VERSION(VERSION: 6, IF_AT_LEAST: FLAGS_SETUP_GCC6_COMPILER_FLAGS)
   elif test "x$TOOLCHAIN_TYPE" = xclang; then
-    if test "x$OPENJDK_TARGET_OS" = xlinux; then
-      if test "x$OPENJDK_TARGET_CPU" = xx86; then
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_GNU_SOURCE"
+
+    # Restrict the debug information created by Clang to avoid
+    # too big object files and speed the build up a little bit
+    # (see http://llvm.org/bugs/show_bug.cgi?id=7554)
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -flimit-debug-info"
+    if test "x$OPENJDK_$1_OS" = xlinux; then
+      if test "x$OPENJDK_$1_CPU" = xx86; then
         # Force compatibility with i586 on 32 bit intel platforms.
-        COMMON_CCXXFLAGS="${COMMON_CCXXFLAGS} -march=i586"
+        $2COMMON_CCXXFLAGS="${$2COMMON_CCXXFLAGS} -march=i586"
+        $2JVM_CFLAGS="[$]$2JVM_CFLAGS -march=i586"
       fi
-      COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS $COMMON_CCXXFLAGS_JDK -Wall -Wextra -Wno-unused -Wno-unused-parameter -Wformat=2 \
+      $2JVM_CFLAGS="[$]$2JVM_CFLAGS -Wno-sometimes-uninitialized"
+      $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS [$]$2COMMON_CCXXFLAGS_JDK -Wall -Wextra -Wno-unused -Wno-unused-parameter -Wformat=2 \
           -pipe -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE"
-      case $OPENJDK_TARGET_CPU_ARCH in
+      case $OPENJDK_$1_CPU_ARCH in
         ppc )
           # on ppc we don't prevent gcc to omit frame pointer but do prevent strict aliasing
-          CFLAGS_JDK="${CFLAGS_JDK} -fno-strict-aliasing"
+          $2CFLAGS_JDK="${$2CFLAGS_JDK} -fno-strict-aliasing"
           ;;
         * )
-          COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer"
-          CFLAGS_JDK="${CFLAGS_JDK} -fno-strict-aliasing"
+          $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer"
+          $2CFLAGS_JDK="${$2CFLAGS_JDK} -fno-strict-aliasing"
           ;;
       esac
     fi
   elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
-    COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS $COMMON_CCXXFLAGS_JDK -DTRACING -DMACRO_MEMSYS_OPS -DBREAKPTS"
-    if test "x$OPENJDK_TARGET_CPU_ARCH" = xx86; then
-      COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -DcpuIntel -Di586 -D$OPENJDK_TARGET_CPU_LEGACY_LIB"
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -DSPARC_WORKS"
+    $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS [$]$2COMMON_CCXXFLAGS_JDK -DTRACING -DMACRO_MEMSYS_OPS -DBREAKPTS"
+    if test "x$OPENJDK_$1_CPU_ARCH" = xx86; then
+      $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -DcpuIntel -Di586 -D$OPENJDK_$1_CPU_LEGACY_LIB"
     fi
 
-    CFLAGS_JDK="$CFLAGS_JDK -xc99=%none -xCC -errshort=tags -Xa -v -mt -W0,-noglobal"
-    CXXFLAGS_JDK="$CXXFLAGS_JDK -errtags=yes +w -mt -features=no%except -DCC_NOEX -norunpath -xnolib"
+    $2CFLAGS_JDK="[$]$2CFLAGS_JDK -xc99=%none -xCC -errshort=tags -Xa -v -mt -W0,-noglobal"
+    $2CXXFLAGS_JDK="[$]$2CXXFLAGS_JDK -errtags=yes +w -mt -features=no%except -DCC_NOEX -norunpath -xnolib"
   elif test "x$TOOLCHAIN_TYPE" = xxlc; then
-    CFLAGS_JDK="$CFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC"
-    CXXFLAGS_JDK="$CXXFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC"
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_REENTRANT -D__STDC_FORMAT_MACROS"
+    $2CFLAGS_JDK="[$]$2CFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC"
+    $2CXXFLAGS_JDK="[$]$2CXXFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC"
   elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
-    COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS $COMMON_CCXXFLAGS_JDK \
+    $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS [$]$2COMMON_CCXXFLAGS_JDK \
         -MD -Zc:wchar_t- -W3 -wd4800 \
         -DWIN32_LEAN_AND_MEAN \
         -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE \
         -D_WINSOCK_DEPRECATED_NO_WARNINGS \
         -DWIN32 -DIAL"
-    if test "x$OPENJDK_TARGET_CPU" = xx86_64; then
-      COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_AMD64_ -Damd64"
+    if test "x$OPENJDK_$1_CPU" = xx86_64; then
+      $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D_AMD64_ -Damd64"
     else
-      COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_X86_ -Dx86"
+      $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D_X86_ -Dx86"
     fi
     # If building with Visual Studio 2010, we can still use _STATIC_CPPLIB to
     # avoid bundling msvcpNNN.dll. Doesn't work with newer versions of visual
     # studio.
     if test "x$TOOLCHAIN_VERSION" = "x2010"; then
       STATIC_CPPLIB_FLAGS="-D_STATIC_CPPLIB -D_DISABLE_DEPRECATE_STATIC_CPPLIB"
-      COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK $STATIC_CPPLIB_FLAGS"
+      $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK $STATIC_CPPLIB_FLAGS"
+      $2JVM_CFLAGS="[$]$2JVM_CFLAGS $STATIC_CPPLIB_FLAGS"
     fi
   fi
 
@@ -688,8 +836,8 @@
   # Adjust flags according to debug level.
   case $DEBUG_LEVEL in
     fastdebug | slowdebug )
-      CFLAGS_JDK="$CFLAGS_JDK $CFLAGS_DEBUG_SYMBOLS $CFLAGS_DEBUG_OPTIONS"
-      CXXFLAGS_JDK="$CXXFLAGS_JDK $CXXFLAGS_DEBUG_SYMBOLS $CXXFLAGS_DEBUG_OPTIONS"
+      $2CFLAGS_JDK="[$]$2CFLAGS_JDK $CFLAGS_DEBUG_SYMBOLS $CFLAGS_DEBUG_OPTIONS"
+      $2CXXFLAGS_JDK="[$]$2CXXFLAGS_JDK $CXXFLAGS_DEBUG_SYMBOLS $CXXFLAGS_DEBUG_OPTIONS"
       JAVAC_FLAGS="$JAVAC_FLAGS -g"
       ;;
     release )
@@ -703,58 +851,142 @@
   # -D is universally accepted.
 
   # Setup endianness
-  if test "x$OPENJDK_TARGET_CPU_ENDIAN" = xlittle; then
+  if test "x$OPENJDK_$1_CPU_ENDIAN" = xlittle; then
     # The macro _LITTLE_ENDIAN needs to be defined the same to avoid the
     #   Sun C compiler warning message: warning: macro redefined: _LITTLE_ENDIAN
     #   (The Solaris X86 system defines this in file /usr/include/sys/isa_defs.h).
     #   Note: -Dmacro         is the same as    #define macro 1
     #         -Dmacro=        is the same as    #define macro
-    if test "x$OPENJDK_TARGET_OS" = xsolaris; then
-      COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_LITTLE_ENDIAN="
+    if test "x$OPENJDK_$1_OS" = xsolaris; then
+      $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D_LITTLE_ENDIAN="
     else
-      COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_LITTLE_ENDIAN"
+      $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D_LITTLE_ENDIAN"
     fi
   else
     # Same goes for _BIG_ENDIAN. Do we really need to set *ENDIAN on Solaris if they
     # are defined in the system?
-    if test "x$OPENJDK_TARGET_OS" = xsolaris; then
-      COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_BIG_ENDIAN="
+    if test "x$OPENJDK_$1_OS" = xsolaris; then
+      $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D_BIG_ENDIAN="
     else
-      COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_BIG_ENDIAN"
+      $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D_BIG_ENDIAN"
     fi
   fi
 
   # Setup target OS define. Use OS target name but in upper case.
-  OPENJDK_TARGET_OS_UPPERCASE=`$ECHO $OPENJDK_TARGET_OS | $TR 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
-  COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D$OPENJDK_TARGET_OS_UPPERCASE"
+  OPENJDK_$1_OS_UPPERCASE=`$ECHO $OPENJDK_$1_OS | $TR 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D$OPENJDK_$1_OS_UPPERCASE"
 
   # Setup target CPU
-  OPENJDK_TARGET_CCXXFLAGS_JDK="$OPENJDK_TARGET_CCXXFLAGS_JDK \
-      $ADD_LP64 \
-      -DARCH='\"$OPENJDK_TARGET_CPU_LEGACY\"' -D$OPENJDK_TARGET_CPU_LEGACY"
-  OPENJDK_BUILD_CCXXFLAGS_JDK="$OPENJDK_BUILD_CCXXFLAGS_JDK \
-      $OPENJDK_BUILD_ADD_LP64 \
-      -DARCH='\"$OPENJDK_BUILD_CPU_LEGACY\"' -D$OPENJDK_BUILD_CPU_LEGACY"
+  $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK \
+      $OPENJDK_$1_ADD_LP64 \
+      -DARCH='\"$OPENJDK_$1_CPU_LEGACY\"' -D$OPENJDK_$1_CPU_LEGACY"
 
   # Setup debug/release defines
   if test "x$DEBUG_LEVEL" = xrelease; then
-    COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -DNDEBUG"
-    if test "x$OPENJDK_TARGET_OS" = xsolaris; then
-      COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -DTRIMMED"
+    $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -DNDEBUG"
+    if test "x$OPENJDK_$1_OS" = xsolaris; then
+      $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -DTRIMMED"
     fi
   else
-    COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -DDEBUG"
+    $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -DDEBUG"
   fi
 
   # Set some additional per-OS defines.
-  if test "x$OPENJDK_TARGET_OS" = xmacosx; then
-    COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT"
-  elif test "x$OPENJDK_TARGET_OS" = xbsd; then
-    COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE"
+  if test "x$OPENJDK_$1_OS" = xlinux; then
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -DLINUX"
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -pipe -fPIC -fno-rtti -fno-exceptions \
+        -fvisibility=hidden -fno-strict-aliasing -fno-omit-frame-pointer"
+  elif test "x$OPENJDK_$1_OS" = xsolaris; then
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -DSOLARIS"
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -template=no%extdef -features=no%split_init \
+        -D_Crun_inline_placement -library=%none -KPIC -mt -xwe -features=no%except"
+  elif test "x$OPENJDK_$1_OS" = xmacosx; then
+    $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT"
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_ALLBSD_SOURCE"
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_DARWIN_C_SOURCE -D_XOPEN_SOURCE"
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -fno-rtti -fno-exceptions -fvisibility=hidden \
+        -mno-omit-leaf-frame-pointer -mstack-alignment=16 -pipe -fno-strict-aliasing \
+        -DMAC_OS_X_VERSION_MAX_ALLOWED=1070 -mmacosx-version-min=10.7.0 \
+        -fno-omit-frame-pointer"
+  elif test "x$OPENJDK_$1_OS" = xaix; then
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -DAIX"
+    # We may need '-qminimaltoc' or '-qpic=large -bbigtoc' if the TOC overflows.
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -qtune=balanced -qhot=level=1 -qinline \
+        -qinlglue -qalias=noansi -qstrict -qtls=default -qlanglvl=c99vla \
+        -qlanglvl=noredefmac -qnortti -qnoeh -qignerrno"
+  elif test "x$OPENJDK_$1_OS" = xbsd; then
+    $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE"
+  elif test "x$OPENJDK_$1_OS" = xwindows; then
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_WINDOWS -DWIN32 -D_JNI_IMPLEMENTATION_"
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -nologo -W3 -MD -MP"
+  fi
+
+  # Set some additional per-CPU defines.
+  if test "x$OPENJDK_$1_OS-$OPENJDK_$1_CPU" = xwindows-x86; then
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -arch:IA32"
+  elif test "x$OPENJDK_$1_CPU" = xsparcv9; then
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -xarch=sparc"
+  elif test "x$OPENJDK_$1_CPU" = xppc64; then
+    if test "x$OPENJDK_$1_OS" = xlinux; then
+      $2JVM_CFLAGS="[$]$2JVM_CFLAGS -minsert-sched-nops=regroup_exact -mno-multiple -mno-string"
+      # fixes `relocation truncated to fit' error for gcc 4.1.
+      $2JVM_CFLAGS="[$]$2JVM_CFLAGS -mminimal-toc"
+      # Use ppc64 instructions, but schedule for power5
+      $2JVM_CFLAGS="[$]$2JVM_CFLAGS -mcpu=powerpc64 -mtune=power5"
+    elif test "x$OPENJDK_$1_OS" = xaix; then
+      $2JVM_CFLAGS="[$]$2JVM_CFLAGS -qarch=ppc64"
+    fi
+  elif test "x$OPENJDK_$1_CPU" = xppc64le; then
+    if test "x$OPENJDK_$1_OS" = xlinux; then
+      $2JVM_CFLAGS="[$]$2JVM_CFLAGS -minsert-sched-nops=regroup_exact -mno-multiple -mno-string"
+      # Little endian machine uses ELFv2 ABI.
+      $2JVM_CFLAGS="[$]$2JVM_CFLAGS -DABI_ELFv2"
+      # Use Power8, this is the first CPU to support PPC64 LE with ELFv2 ABI.
+      $2JVM_CFLAGS="[$]$2JVM_CFLAGS -mcpu=power7 -mtune=power8"
+    fi
+  fi
+
+  if test "x$OPENJDK_$1_CPU_ENDIAN" = xlittle; then
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -DVM_LITTLE_ENDIAN"
+  fi
+
+  if test "x$OPENJDK_$1_CPU_BITS" = x64; then
+    if test "x$OPENJDK_$1_OS" != xsolaris && test "x$OPENJDK_$1_OS" != xaix; then
+      # Solaris does not have _LP64=1 in the old build.
+      # xlc on AIX defines _LP64=1 by default and issues a warning if we redefine it.
+      $2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_LP64=1"
+    fi
+  fi
+
+  # Set $2JVM_CFLAGS warning handling
+  if test "x$OPENJDK_$1_OS" = xlinux; then
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -Wpointer-arith -Wsign-compare -Wunused-function \
+        -Wunused-value -Woverloaded-virtual"
+
+    if test "x$TOOLCHAIN_TYPE" = xgcc; then
+      TOOLCHAIN_CHECK_COMPILER_VERSION(VERSION: [4.8],
+          IF_AT_LEAST: [
+            # These flags either do not work or give spurious warnings prior to gcc 4.8.
+            $2JVM_CFLAGS="[$]$2JVM_CFLAGS -Wno-format-zero-length -Wtype-limits -Wuninitialized"
+          ]
+      )
+    fi
+    if ! HOTSPOT_CHECK_JVM_VARIANT(zero) && ! HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
+      # Non-zero builds have stricter warnings
+      $2JVM_CFLAGS="[$]$2JVM_CFLAGS -Wreturn-type -Wundef -Wformat=2"
+    else
+      if test "x$TOOLCHAIN_TYPE" = xclang; then
+        # Some versions of llvm do not like -Wundef
+        $2JVM_CFLAGS="[$]$2JVM_CFLAGS -Wno-undef"
+      fi
+    fi
+  elif test "x$OPENJDK_$1_OS" = xmacosx; then
+    $2JVM_CFLAGS="[$]$2JVM_CFLAGS -Wno-deprecated -Wpointer-arith \
+        -Wsign-compare -Wundef -Wunused-function -Wformat=2"
   fi
 
   # Additional macosx handling
-  if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+  if test "x$OPENJDK_$1_OS" = xmacosx; then
     # Setting these parameters makes it an error to link to macosx APIs that are
     # newer than the given OS version and makes the linked binaries compatible
     # even if built on a newer version of the OS.
@@ -765,108 +997,112 @@
     # The macro takes the version with no dots, ex: 1070
     # Let the flags variables get resolved in make for easier override on make
     # command line.
-    COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -DMAC_OS_X_VERSION_MAX_ALLOWED=\$(subst .,,\$(MACOSX_VERSION_MIN)) -mmacosx-version-min=\$(MACOSX_VERSION_MIN)"
-    LDFLAGS_JDK="$LDFLAGS_JDK -mmacosx-version-min=\$(MACOSX_VERSION_MIN)"
+    $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -DMAC_OS_X_VERSION_MAX_ALLOWED=\$(subst .,,\$(MACOSX_VERSION_MIN)) -mmacosx-version-min=\$(MACOSX_VERSION_MIN)"
+    $2LDFLAGS_JDK="[$]$2LDFLAGS_JDK -mmacosx-version-min=\$(MACOSX_VERSION_MIN)"
   fi
 
   # Setup some hard coded includes
-  COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK \
+  $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK \
       -I${JDK_TOPDIR}/src/java.base/share/native/include \
-      -I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS/native/include \
-      -I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS_TYPE/native/include \
+      -I${JDK_TOPDIR}/src/java.base/$OPENJDK_$1_OS/native/include \
+      -I${JDK_TOPDIR}/src/java.base/$OPENJDK_$1_OS_TYPE/native/include \
       -I${JDK_TOPDIR}/src/java.base/share/native/libjava \
-      -I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS_TYPE/native/libjava"
+      -I${JDK_TOPDIR}/src/java.base/$OPENJDK_$1_OS_TYPE/native/libjava"
 
   # The shared libraries are compiled using the picflag.
-  CFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
-      $CFLAGS_JDK $EXTRA_CFLAGS_JDK $PICFLAG $CFLAGS_JDKLIB_EXTRA"
-  CXXFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
-      $CXXFLAGS_JDK $EXTRA_CXXFLAGS_JDK $PICFLAG $CXXFLAGS_JDKLIB_EXTRA"
+  $2CFLAGS_JDKLIB="[$]$2COMMON_CCXXFLAGS_JDK \
+      [$]$2CFLAGS_JDK [$]$2EXTRA_CFLAGS_JDK $PICFLAG [$]$2CFLAGS_JDKLIB_EXTRA"
+  $2CXXFLAGS_JDKLIB="[$]$2COMMON_CCXXFLAGS_JDK \
+      [$]$2CXXFLAGS_JDK [$]$2EXTRA_CXXFLAGS_JDK $PICFLAG [$]$2CXXFLAGS_JDKLIB_EXTRA"
 
   # Executable flags
-  CFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
-      $CFLAGS_JDK $EXTRA_CFLAGS_JDK"
-  CXXFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
-      $CXXFLAGS_JDK $EXTRA_CXXFLAGS_JDK"
-
-  # The corresponding flags for building for the build platform. This is still an
-  # approximation, we only need something that runs on this machine when cross
-  # compiling the product.
-  OPENJDK_BUILD_CFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK \
-      $PICFLAG $CFLAGS_JDKLIB_EXTRA"
-  OPENJDK_BUILD_CXXFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK \
-      $PICFLAG $CXXFLAGS_JDKLIB_EXTRA"
-  OPENJDK_BUILD_CFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK"
-  OPENJDK_BUILD_CXXFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK"
+  $2CFLAGS_JDKEXE="[$]$2COMMON_CCXXFLAGS_JDK [$]$2CFLAGS_JDK [$]$2EXTRA_CFLAGS_JDK"
+  $2CXXFLAGS_JDKEXE="[$]$2COMMON_CCXXFLAGS_JDK [$]$2CXXFLAGS_JDK [$]$2EXTRA_CXXFLAGS_JDK"
 
-  AC_SUBST(CFLAGS_JDKLIB)
-  AC_SUBST(CFLAGS_JDKEXE)
-  AC_SUBST(CXXFLAGS_JDKLIB)
-  AC_SUBST(CXXFLAGS_JDKEXE)
-  AC_SUBST(OPENJDK_BUILD_CFLAGS_JDKLIB)
-  AC_SUBST(OPENJDK_BUILD_CFLAGS_JDKEXE)
-  AC_SUBST(OPENJDK_BUILD_CXXFLAGS_JDKLIB)
-  AC_SUBST(OPENJDK_BUILD_CXXFLAGS_JDKEXE)
-
-  # Flags for compiling test libraries
-  CFLAGS_TESTLIB="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK $PICFLAG $CFLAGS_JDKLIB_EXTRA"
-  CXXFLAGS_TESTLIB="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK $PICFLAG $CXXFLAGS_JDKLIB_EXTRA"
-
-  # Flags for compiling test executables
-  CFLAGS_TESTEXE="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK"
-  CXXFLAGS_TESTEXE="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK"
-
-  AC_SUBST(CFLAGS_TESTLIB)
-  AC_SUBST(CFLAGS_TESTEXE)
-  AC_SUBST(CXXFLAGS_TESTLIB)
-  AC_SUBST(CXXFLAGS_TESTEXE)
+  AC_SUBST($2CFLAGS_JDKLIB)
+  AC_SUBST($2CFLAGS_JDKEXE)
+  AC_SUBST($2CXXFLAGS_JDKLIB)
+  AC_SUBST($2CXXFLAGS_JDKEXE)
 
   # Setup LDFLAGS et al.
   #
 
   if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
     LDFLAGS_MICROSOFT="-nologo -opt:ref"
-    LDFLAGS_JDK="$LDFLAGS_JDK $LDFLAGS_MICROSOFT -incremental:no"
-    if test "x$OPENJDK_TARGET_CPU_BITS" = "x32"; then
+    $2LDFLAGS_JDK="[$]$2LDFLAGS_JDK $LDFLAGS_MICROSOFT -incremental:no"
+    $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LDFLAGS_MICROSOFT -opt:icf,8 -subsystem:windows -base:0x8000000"
+    if test "x$OPENJDK_$1_CPU_BITS" = "x32"; then
       LDFLAGS_SAFESH="-safeseh"
-      LDFLAGS_JDK="$LDFLAGS_JDK $LDFLAGS_SAFESH"
+      $2LDFLAGS_JDK="[$]$2LDFLAGS_JDK $LDFLAGS_SAFESH"
+      $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LDFLAGS_SAFESH"
+      # NOTE: Old build added -machine. Probably not needed.
+      $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS -machine:I386"
+    else
+      $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS -machine:AMD64"
+    fi
+  elif test "x$TOOLCHAIN_TYPE" = xclang; then
+      $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS -mno-omit-leaf-frame-pointer -mstack-alignment=16 -stdlib=libstdc++ -fPIC"
+      if test "x$OPENJDK_$1_OS" = xmacosx; then
+        # FIXME: We should really generalize SET_SHARED_LIBRARY_ORIGIN instead.
+        $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS -Wl,-rpath,@loader_path/. -Wl,-rpath,@loader_path/.."
     fi
   elif test "x$TOOLCHAIN_TYPE" = xgcc; then
     # If this is a --hash-style=gnu system, use --hash-style=both, why?
     # We have previously set HAS_GNU_HASH if this is the case
     if test -n "$HAS_GNU_HASH"; then
-      LDFLAGS_HASH_STYLE="-Wl,--hash-style=both"
-      LDFLAGS_JDK="${LDFLAGS_JDK} $LDFLAGS_HASH_STYLE"
+      $2LDFLAGS_HASH_STYLE="-Wl,--hash-style=both"
+      $2LDFLAGS_JDK="${$2LDFLAGS_JDK} [$]$2LDFLAGS_HASH_STYLE"
+      $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS [$]$2LDFLAGS_HASH_STYLE"
     fi
-    if test "x$OPENJDK_TARGET_OS" = xlinux; then
+      if test "x$OPENJDK_$1_OS" = xmacosx; then
+        $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS -Wl,-rpath,@loader_path/. -Wl,-rpath,@loader_path/.."
+    fi
+    if test "x$OPENJDK_$1_OS" = xlinux; then
       # And since we now know that the linker is gnu, then add -z defs, to forbid
       # undefined symbols in object files.
       LDFLAGS_NO_UNDEF_SYM="-Wl,-z,defs"
-      LDFLAGS_JDK="${LDFLAGS_JDK} $LDFLAGS_NO_UNDEF_SYM"
+      $2LDFLAGS_JDK="${$2LDFLAGS_JDK} $LDFLAGS_NO_UNDEF_SYM"
+      $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS  $LDFLAGS_NO_UNDEF_SYM"
+      LDFLAGS_NO_EXEC_STACK="-Wl,-z,noexecstack"
+      $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LDFLAGS_NO_EXEC_STACK"
+      if test "x$OPENJDK_$1_CPU" = xx86; then
+        $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS -march=i586"
+      fi
       case $DEBUG_LEVEL in
         release )
           # tell linker to optimize libraries.
           # Should this be supplied to the OSS linker as well?
           LDFLAGS_DEBUGLEVEL_release="-Wl,-O1"
-          LDFLAGS_JDK="${LDFLAGS_JDK} $LDFLAGS_DEBUGLEVEL_release"
+          $2LDFLAGS_JDK="${$2LDFLAGS_JDK} $LDFLAGS_DEBUGLEVEL_release"
+          $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LDFLAGS_DEBUGLEVEL_release"
+          if test "x$HAS_LINKER_RELRO" = "xtrue"; then
+            $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LINKER_RELRO_FLAG"
+          fi
           ;;
         slowdebug )
+          # Hotspot always let the linker optimize
+          $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS -Wl,-O1"
           if test "x$HAS_LINKER_NOW" = "xtrue"; then
             # do relocations at load
-            LDFLAGS_JDK="$LDFLAGS_JDK $LINKER_NOW_FLAG"
-            LDFLAGS_CXX_JDK="$LDFLAGS_CXX_JDK $LINKER_NOW_FLAG"
+            $2LDFLAGS_JDK="[$]$2LDFLAGS_JDK $LINKER_NOW_FLAG"
+            $2LDFLAGS_CXX_JDK="[$]$2LDFLAGS_CXX_JDK $LINKER_NOW_FLAG"
+            $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LINKER_NOW_FLAG"
           fi
           if test "x$HAS_LINKER_RELRO" = "xtrue"; then
             # mark relocations read only
-            LDFLAGS_JDK="$LDFLAGS_JDK $LINKER_RELRO_FLAG"
-            LDFLAGS_CXX_JDK="$LDFLAGS_CXX_JDK $LINKER_RELRO_FLAG"
+            $2LDFLAGS_JDK="[$]$2LDFLAGS_JDK $LINKER_RELRO_FLAG"
+            $2LDFLAGS_CXX_JDK="[$]$2LDFLAGS_CXX_JDK $LINKER_RELRO_FLAG"
+            $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LINKER_RELRO_FLAG"
           fi
           ;;
         fastdebug )
+          # Hotspot always let the linker optimize
+          $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS -Wl,-O1"
           if test "x$HAS_LINKER_RELRO" = "xtrue"; then
             # mark relocations read only
-            LDFLAGS_JDK="$LDFLAGS_JDK $LINKER_RELRO_FLAG"
-            LDFLAGS_CXX_JDK="$LDFLAGS_CXX_JDK $LINKER_RELRO_FLAG"
+            $2LDFLAGS_JDK="[$]$2LDFLAGS_JDK $LINKER_RELRO_FLAG"
+            $2LDFLAGS_CXX_JDK="[$]$2LDFLAGS_CXX_JDK $LINKER_RELRO_FLAG"
+            $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LINKER_RELRO_FLAG"
           fi
           ;;
         * )
@@ -876,85 +1112,122 @@
     fi
   elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
     LDFLAGS_SOLSTUDIO="-Wl,-z,defs"
-    LDFLAGS_JDK="$LDFLAGS_JDK $LDFLAGS_SOLSTUDIO -xildoff -ztext"
+    $2LDFLAGS_JDK="[$]$2LDFLAGS_JDK $LDFLAGS_SOLSTUDIO -xildoff -ztext"
     LDFLAGS_CXX_SOLSTUDIO="-norunpath"
-    LDFLAGS_CXX_JDK="$LDFLAGS_CXX_JDK $LDFLAGS_CXX_SOLSTUDIO -xnolib"
+    $2LDFLAGS_CXX_JDK="[$]$2LDFLAGS_CXX_JDK $LDFLAGS_CXX_SOLSTUDIO -xnolib"
+    $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LDFLAGS_SOLSTUDIO -library=%none -mt $LDFLAGS_CXX_SOLSTUDIO -z noversion"
+    if test "x$OPENJDK_$1_CPU_ARCH" = "xsparc"; then
+      $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS -xarch=sparc"
+    fi
   elif test "x$TOOLCHAIN_TYPE" = xxlc; then
     LDFLAGS_XLC="-b64 -brtl -bnolibpath -bexpall -bernotok"
-    LDFLAGS_JDK="${LDFLAGS_JDK} $LDFLAGS_XLC"
+    $2LDFLAGS_JDK="${$2LDFLAGS_JDK} $LDFLAGS_XLC"
+    $2JVM_LDFLAGS="[$]$2JVM_LDFLAGS $LDFLAGS_XLC"
   fi
 
   # Customize LDFLAGS for executables
 
-  LDFLAGS_JDKEXE="${LDFLAGS_JDK}"
+  $2LDFLAGS_JDKEXE="${$2LDFLAGS_JDK}"
 
   if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
-    if test "x$OPENJDK_TARGET_CPU_BITS" = "x64"; then
+    if test "x$OPENJDK_$1_CPU_BITS" = "x64"; then
       LDFLAGS_STACK_SIZE=1048576
     else
       LDFLAGS_STACK_SIZE=327680
     fi
-    LDFLAGS_JDKEXE="${LDFLAGS_JDKEXE} /STACK:$LDFLAGS_STACK_SIZE"
-  elif test "x$OPENJDK_TARGET_OS" = xlinux; then
-    LDFLAGS_JDKEXE="$LDFLAGS_JDKEXE -Wl,--allow-shlib-undefined"
+    $2LDFLAGS_JDKEXE="${$2LDFLAGS_JDKEXE} /STACK:$LDFLAGS_STACK_SIZE"
+  elif test "x$OPENJDK_$1_OS" = xlinux; then
+    $2LDFLAGS_JDKEXE="[$]$2LDFLAGS_JDKEXE -Wl,--allow-shlib-undefined"
   fi
 
-  OPENJDK_BUILD_LDFLAGS_JDKEXE="${LDFLAGS_JDKEXE}"
-  LDFLAGS_JDKEXE="${LDFLAGS_JDKEXE} ${EXTRA_LDFLAGS_JDK}"
+  $2LDFLAGS_JDKEXE="${$2LDFLAGS_JDKEXE} ${$2EXTRA_LDFLAGS_JDK}"
 
   # Customize LDFLAGS for libs
-  LDFLAGS_JDKLIB="${LDFLAGS_JDK}"
+  $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDK}"
 
-  LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} ${SHARED_LIBRARY_FLAGS}"
+  $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} ${SHARED_LIBRARY_FLAGS}"
   if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
-    LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} \
+    $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} \
         -libpath:${OUTPUT_ROOT}/support/modules_libs/java.base"
-    JDKLIB_LIBS=""
+    $2JDKLIB_LIBS=""
   else
-    LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} \
-        -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)"
+    $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} \
+        -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)"
 
+    if test "x$1" = "xTARGET"; then
     # On some platforms (mac) the linker warns about non existing -L dirs.
     # Add server first if available. Linking aginst client does not always produce the same results.
-    # Only add client dir if client is being built. Add minimal (note not minimal1) if only building minimal1.
+      # Only add client/minimal dir if client/minimal is being built.
     # Default to server for other variants.
-    if test "x$JVM_VARIANT_SERVER" = xtrue; then
-      LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
-    elif test "x$JVM_VARIANT_CLIENT" = xtrue; then
-      LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/client"
-    elif test "x$JVM_VARIANT_MINIMAL1" = xtrue; then
-      LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/minimal"
+      if HOTSPOT_CHECK_JVM_VARIANT(server); then
+        $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)/server"
+      elif HOTSPOT_CHECK_JVM_VARIANT(client); then
+        $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)/client"
+      elif HOTSPOT_CHECK_JVM_VARIANT(minimal); then
+        $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)/minimal"
     else
-      LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
+        $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)/server"
+    fi
+    elif test "x$1" = "xBUILD"; then
+      # When building a buildjdk, it's always only the server variant
+      $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} \
+          -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_$1_CPU_LIBDIR)/server"
     fi
 
-    JDKLIB_LIBS="-ljava -ljvm"
+    $2JDKLIB_LIBS="-ljava -ljvm"
     if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
-      JDKLIB_LIBS="$JDKLIB_LIBS -lc"
+      $2JDKLIB_LIBS="[$]$2JDKLIB_LIBS -lc"
     fi
 
-    # When building a buildjdk, it's always only the server variant
-    OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} \
-        -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
   fi
 
-  OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} ${LDFLAGS_JDKLIB}"
-  LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} ${EXTRA_LDFLAGS_JDK}"
+  # Set $2JVM_LIBS (per os)
+  if test "x$OPENJDK_$1_OS" = xlinux; then
+    $2JVM_LIBS="[$]$2JVM_LIBS -lm -ldl -lpthread"
+  elif test "x$OPENJDK_$1_OS" = xsolaris; then
+    # FIXME: This hard-coded path is not really proper.
+    if test "x$OPENJDK_$1_CPU" = xx86_64; then
+      $2SOLARIS_LIBM_LIBS="/usr/lib/amd64/libm.so.1"
+    elif test "x$OPENJDK_$1_CPU" = xsparcv9; then
+      $2SOLARIS_LIBM_LIBS="/usr/lib/sparcv9/libm.so.1"
+    fi
+    $2JVM_LIBS="[$]$2JVM_LIBS -lsocket -lsched -ldl $SOLARIS_LIBM_LIBS -lCrun \
+        -lthread -ldoor -lc -ldemangle -lnsl -lkstat -lrt"
+  elif test "x$OPENJDK_$1_OS" = xmacosx; then
+    $2JVM_LIBS="[$]$2JVM_LIBS -lm"
+  elif test "x$OPENJDK_$1_OS" = xaix; then
+    $2JVM_LIBS="[$]$2JVM_LIBS -Wl,-lC_r -lm -ldl -lpthread"
+  elif test "x$OPENJDK_$1_OS" = xbsd; then
+    $2JVM_LIBS="[$]$2JVM_LIBS -lm"
+  elif test "x$OPENJDK_$1_OS" = xwindows; then
+    $2JVM_LIBS="[$]$2JVM_LIBS kernel32.lib user32.lib gdi32.lib winspool.lib \
+        comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib \
+        wsock32.lib winmm.lib version.lib psapi.lib"
+    fi
 
-  AC_SUBST(LDFLAGS_JDKLIB)
-  AC_SUBST(LDFLAGS_JDKEXE)
-  AC_SUBST(OPENJDK_BUILD_LDFLAGS_JDKLIB)
-  AC_SUBST(OPENJDK_BUILD_LDFLAGS_JDKEXE)
-  AC_SUBST(JDKLIB_LIBS)
-  AC_SUBST(JDKEXE_LIBS)
-  AC_SUBST(LDFLAGS_CXX_JDK)
-  AC_SUBST(LDFLAGS_HASH_STYLE)
+  # Set $2JVM_ASFLAGS
+  if test "x$OPENJDK_$1_OS" = xlinux; then
+    if test "x$OPENJDK_$1_CPU" = xx86; then
+      $2JVM_ASFLAGS="[$]$2JVM_ASFLAGS -march=i586"
+    fi
+  elif test "x$OPENJDK_$1_OS" = xmacosx; then
+    $2JVM_ASFLAGS="[$]$2JVM_ASFLAGS -x assembler-with-cpp -mno-omit-leaf-frame-pointer -mstack-alignment=16"
+  fi
+
+  $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} ${$2EXTRA_LDFLAGS_JDK}"
 
-  LDFLAGS_TESTLIB="$LDFLAGS_JDKLIB"
-  LDFLAGS_TESTEXE="$LDFLAGS_JDKEXE"
+  AC_SUBST($2LDFLAGS_JDKLIB)
+  AC_SUBST($2LDFLAGS_JDKEXE)
+  AC_SUBST($2JDKLIB_LIBS)
+  AC_SUBST($2JDKEXE_LIBS)
+  AC_SUBST($2LDFLAGS_CXX_JDK)
+  AC_SUBST($2LDFLAGS_HASH_STYLE)
 
-  AC_SUBST(LDFLAGS_TESTLIB)
-  AC_SUBST(LDFLAGS_TESTEXE)
+  AC_SUBST($2JVM_CFLAGS)
+  AC_SUBST($2JVM_LDFLAGS)
+  AC_SUBST($2JVM_ASFLAGS)
+  AC_SUBST($2JVM_LIBS)
+
 ])
 
 # FLAGS_C_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [ARGUMENT], IF_TRUE: [RUN-IF-TRUE],
--- a/common/autoconf/generated-configure.sh	Fri Apr 29 04:44:08 2016 +0200
+++ b/common/autoconf/generated-configure.sh	Thu Apr 28 23:08:16 2016 -0700
@@ -652,7 +652,21 @@
 NUM_CORES
 BUILD_FAILURE_HANDLER
 ENABLE_INTREE_EC
+JVM_VARIANT_CORE
+JVM_VARIANT_ZEROSHARK
+JVM_VARIANT_ZERO
+JVM_VARIANT_HOTSPOT
+JVM_VARIANT_MINIMAL1
+JVM_VARIANT_CLIENT
+JVM_VARIANT_SERVER
+JVM_VARIANTS_COMMA
+TEST_IN_BUILD
 HOTSPOT_MAKE_ARGS
+MACOSX_UNIVERSAL
+DEBUG_CLASSFILES
+FASTDEBUG
+VARIANT
+USE_NEW_HOTSPOT_BUILD
 LIBZIP_CAN_USE_MMAP
 LIBDL
 LIBM
@@ -688,6 +702,15 @@
 STATIC_CXX_SETTING
 FIXPATH_DETACH_FLAG
 FIXPATH
+VALID_JVM_FEATURES
+JVM_FEATURES_custom
+JVM_FEATURES_zeroshark
+JVM_FEATURES_zero
+JVM_FEATURES_minimal
+JVM_FEATURES_core
+JVM_FEATURES_client
+JVM_FEATURES_server
+INCLUDE_DTRACE
 GCOV_ENABLED
 STRIP_POLICY
 DEBUG_BINARIES
@@ -703,22 +726,35 @@
 ZERO_ARCHFLAG
 LDFLAGS_TESTEXE
 LDFLAGS_TESTLIB
+CXXFLAGS_TESTEXE
+CXXFLAGS_TESTLIB
+CFLAGS_TESTEXE
+CFLAGS_TESTLIB
+OPENJDK_BUILD_JVM_LIBS
+OPENJDK_BUILD_JVM_ASFLAGS
+OPENJDK_BUILD_JVM_LDFLAGS
+OPENJDK_BUILD_JVM_CFLAGS
+OPENJDK_BUILD_LDFLAGS_HASH_STYLE
+OPENJDK_BUILD_LDFLAGS_CXX_JDK
+OPENJDK_BUILD_JDKEXE_LIBS
+OPENJDK_BUILD_JDKLIB_LIBS
+OPENJDK_BUILD_LDFLAGS_JDKEXE
+OPENJDK_BUILD_LDFLAGS_JDKLIB
+OPENJDK_BUILD_CXXFLAGS_JDKEXE
+OPENJDK_BUILD_CXXFLAGS_JDKLIB
+OPENJDK_BUILD_CFLAGS_JDKEXE
+OPENJDK_BUILD_CFLAGS_JDKLIB
+OPENJDK_BUILD_CXXSTD_CXXFLAG
+JVM_LIBS
+JVM_ASFLAGS
+JVM_LDFLAGS
+JVM_CFLAGS
 LDFLAGS_HASH_STYLE
 LDFLAGS_CXX_JDK
 JDKEXE_LIBS
 JDKLIB_LIBS
-OPENJDK_BUILD_LDFLAGS_JDKEXE
-OPENJDK_BUILD_LDFLAGS_JDKLIB
 LDFLAGS_JDKEXE
 LDFLAGS_JDKLIB
-CXXFLAGS_TESTEXE
-CXXFLAGS_TESTLIB
-CFLAGS_TESTEXE
-CFLAGS_TESTLIB
-OPENJDK_BUILD_CXXFLAGS_JDKEXE
-OPENJDK_BUILD_CXXFLAGS_JDKLIB
-OPENJDK_BUILD_CFLAGS_JDKEXE
-OPENJDK_BUILD_CFLAGS_JDKLIB
 CXXFLAGS_JDKEXE
 CXXFLAGS_JDKLIB
 CFLAGS_JDKEXE
@@ -727,16 +763,21 @@
 NO_LIFETIME_DSE_CFLAG
 NO_NULL_POINTER_CHECK_CFLAG
 CXXSTD_CXXFLAG
+CXX_O_FLAG_SIZE
 CXX_O_FLAG_NONE
 CXX_O_FLAG_DEBUG
 CXX_O_FLAG_NORM
 CXX_O_FLAG_HI
 CXX_O_FLAG_HIGHEST
+CXX_O_FLAG_HIGHEST_JVM
+C_O_FLAG_SIZE
 C_O_FLAG_NONE
 C_O_FLAG_DEBUG
 C_O_FLAG_NORM
 C_O_FLAG_HI
 C_O_FLAG_HIGHEST
+C_O_FLAG_HIGHEST_JVM
+JVM_CFLAGS_SYMBOLS
 CXXFLAGS_DEBUG_SYMBOLS
 CFLAGS_DEBUG_SYMBOLS
 CXX_FLAG_DEPS
@@ -748,6 +789,7 @@
 SET_EXECUTABLE_ORIGIN
 CXX_FLAG_REORDER
 C_FLAG_REORDER
+JVM_RCFLAGS
 RC_FLAGS
 AR_OUT_OPTION
 LD_OUT_OPTION
@@ -760,6 +802,7 @@
 COMPILER_TARGET_BITS_FLAG
 JT_HOME
 JTREGEXE
+HOTSPOT_TOOLCHAIN_TYPE
 USING_BROKEN_SUSE_LD
 PACKAGE_PATH
 USE_CLANG
@@ -822,6 +865,9 @@
 CYGWIN_LINK
 SYSROOT_LDFLAGS
 SYSROOT_CFLAGS
+EXTRA_LDFLAGS
+EXTRA_CXXFLAGS
+EXTRA_CFLAGS
 LEGACY_EXTRA_LDFLAGS
 LEGACY_EXTRA_CXXFLAGS
 LEGACY_EXTRA_CFLAGS
@@ -878,12 +924,12 @@
 VERSION_MAJOR
 MACOSX_BUNDLE_ID_BASE
 MACOSX_BUNDLE_NAME_BASE
+HOTSPOT_VM_DISTRO
 COMPANY_NAME
 JDK_RC_PLATFORM_NAME
 PRODUCT_SUFFIX
 PRODUCT_NAME
 LAUNCHER_NAME
-TEST_IN_BUILD
 JLINK_KEEP_PACKAGED_MODULES
 COPYRIGHT_YEAR
 COMPRESS_JARS
@@ -905,6 +951,7 @@
 DSYMUTIL
 IS_GNU_TIME
 PATCH
+DTRACE
 TIME
 STAT
 HG
@@ -928,20 +975,10 @@
 SPEC
 SDKROOT
 XCODEBUILD
-BUILD_VARIANT_RELEASE
-DEBUG_CLASSFILES
-FASTDEBUG
-VARIANT
+VALID_JVM_VARIANTS
+JVM_VARIANTS
 DEBUG_LEVEL
-MACOSX_UNIVERSAL
-JVM_VARIANT_CORE
-JVM_VARIANT_ZEROSHARK
-JVM_VARIANT_ZERO
-JVM_VARIANT_MINIMAL1
-JVM_VARIANT_CLIENT
-JVM_VARIANT_SERVER
-JVM_VARIANTS
-JVM_INTERPRETER
+HOTSPOT_DEBUG_LEVEL
 JDK_VARIANT
 SET_OPENJDK
 USERNAME
@@ -950,16 +987,29 @@
 TOPDIR
 PATH_SEP
 ZERO_ARCHDEF
+HOTSPOT_BUILD_CPU_DEFINE
+HOTSPOT_BUILD_CPU_ARCH
+HOTSPOT_BUILD_CPU
+HOTSPOT_BUILD_OS_TYPE
+HOTSPOT_BUILD_OS
+OPENJDK_BUILD_OS_EXPORT_DIR
+OPENJDK_BUILD_CPU_JLI_CFLAGS
+OPENJDK_BUILD_CPU_OSARCH
+OPENJDK_BUILD_CPU_ISADIR
+OPENJDK_BUILD_CPU_LIBDIR
+OPENJDK_BUILD_CPU_LEGACY_LIB
+OPENJDK_BUILD_CPU_LEGACY
+HOTSPOT_TARGET_CPU_DEFINE
+HOTSPOT_TARGET_CPU_ARCH
+HOTSPOT_TARGET_CPU
+HOTSPOT_TARGET_OS_TYPE
+HOTSPOT_TARGET_OS
 DEFINE_CROSS_COMPILE_ARCH
 LP64
 OPENJDK_TARGET_OS_EXPORT_DIR
-OPENJDK_BUILD_CPU_JLI_CFLAGS
 OPENJDK_TARGET_CPU_JLI_CFLAGS
 OPENJDK_TARGET_CPU_OSARCH
 OPENJDK_TARGET_CPU_ISADIR
-OPENJDK_BUILD_CPU_LIBDIR
-OPENJDK_BUILD_CPU_LEGACY_LIB
-OPENJDK_BUILD_CPU_LEGACY
 OPENJDK_TARGET_CPU_LIBDIR
 OPENJDK_TARGET_CPU_LEGACY_LIB
 OPENJDK_TARGET_CPU_LEGACY
@@ -1089,10 +1139,9 @@
 enable_openjdk_only
 with_custom_make_dir
 with_jdk_variant
-with_jvm_interpreter
-with_jvm_variants
 enable_debug
 with_debug_level
+with_jvm_variants
 with_devkit
 with_sys_root
 with_sysroot
@@ -1108,7 +1157,6 @@
 enable_unlimited_crypto
 with_copyright_year
 enable_keep_packaged_modules
-enable_hotspot_test_in_build
 with_milestone
 with_update_version
 with_user_release_suffix
@@ -1148,6 +1196,9 @@
 enable_debug_symbols
 enable_zip_debug_info
 enable_native_coverage
+enable_dtrace
+with_jvm_features
+with_jvm_interpreter
 with_stdc__lib
 with_msvcr_dll
 with_msvcp_dll
@@ -1173,6 +1224,8 @@
 with_dxsdk
 with_dxsdk_lib
 with_dxsdk_include
+enable_new_hotspot_build
+enable_hotspot_test_in_build
 enable_jtreg_failure_handler
 with_num_cores
 with_memory_size
@@ -1246,6 +1299,7 @@
 HG
 STAT
 TIME
+DTRACE
 PATCH
 DSYMUTIL
 XATTR
@@ -1925,8 +1979,6 @@
                           Enable unlimited crypto policy [disabled]
   --disable-keep-packaged-modules
                           Do not keep packaged modules in jdk image [enable]
-  --enable-hotspot-test-in-build
-                          run the Queens test after Hotspot build [disabled]
   --enable-static-build   enable static library build [disabled]
   --disable-warnings-as-errors
                           do not consider native warnings to be an error
@@ -1938,10 +1990,18 @@
   --enable-native-coverage
                           enable native compilation with code coverage
                           data[disabled]
+  --enable-dtrace[=yes/no/auto]
+                          enable dtrace. Default is auto, where dtrace is
+                          enabled if all dependencies are present.
   --disable-freetype-bundling
                           disable bundling of the freetype library with the
                           build result [enabled on Windows or when using
                           --with-freetype, disabled otherwise]
+  --disable-new-hotspot-build
+                          disable the new hotspot build system (use the old)
+                          [enabled]
+  --enable-hotspot-test-in-build
+                          run the Queens test after Hotspot build [disabled]
   --enable-jtreg-failure-handler
                           forces build of the jtreg failure handler to be
                           enabled, missing dependencies become fatal errors.
@@ -1967,11 +2027,11 @@
   --with-custom-make-dir  Deprecated. Option is kept for backwards
                           compatibility and is ignored
   --with-jdk-variant      JDK variant to build (normal) [normal]
-  --with-jvm-interpreter  JVM interpreter to build (template, cpp) [template]
-  --with-jvm-variants     JVM variants (separated by commas) to build (server,
-                          client, minimal1, zero, zeroshark, core) [server]
   --with-debug-level      set the debug level (release, fastdebug, slowdebug,
                           optimized) [release]
+  --with-jvm-variants     JVM variants (separated by commas) to build
+                          (server,client,minimal,core,zero,zeroshark,custom)
+                          [server]
   --with-devkit           use this devkit for compilers, tools and resources
   --with-sys-root         alias for --with-sysroot for backwards compatability
   --with-sysroot          use this directory as sysroot
@@ -2058,6 +2118,10 @@
   --with-native-debug-symbols
                           set the native debug symbol configuration (none,
                           internal, external, zipped) [varying]
+  --with-jvm-features     additional JVM features to enable (separated by
+                          comma), use '--help' to show possible values [none]
+  --with-jvm-interpreter  Deprecated. Option is kept for backwards
+                          compatibility and is ignored
   --with-stdc++lib=<static>,<dynamic>,<default>
                           force linking of the C++ runtime on Linux to either
                           static or dynamic, default is static with dynamic as
@@ -2178,6 +2242,7 @@
   HG          Override default value for HG
   STAT        Override default value for STAT
   TIME        Override default value for TIME
+  DTRACE      Override default value for DTRACE
   PATCH       Override default value for PATCH
   DSYMUTIL    Override default value for DSYMUTIL
   XATTR       Override default value for XATTR
@@ -3977,6 +4042,13 @@
 
 
 
+
+################################################################################
+# $1 - Either BUILD or TARGET to pick the correct OS/CPU variables to check
+#      conditionals against.
+# $2 - Optional prefix for each variable defined.
+
+
 # FLAGS_C_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [ARGUMENT], IF_TRUE: [RUN-IF-TRUE],
 #                                  IF_FALSE: [RUN-IF-FALSE])
 # ------------------------------------------------------------
@@ -4101,6 +4173,8 @@
       PKGHANDLER_COMMAND="sudo apt-get install libX11-dev libxext-dev libxrender-dev libxtst-dev libxt-dev" ;;
     ccache)
       PKGHANDLER_COMMAND="sudo apt-get install ccache" ;;
+    dtrace)
+      PKGHANDLER_COMMAND="sudo apt-get install systemtap-sdt-dev" ;;
   esac
 }
 
@@ -4170,37 +4244,66 @@
 # questions.
 #
 
+# All valid JVM features, regardless of platform
+VALID_JVM_FEATURES="compiler1 compiler2 zero shark minimal dtrace jvmti jvmci \
+    fprof vm-structs jni-check services management all-gcs nmt cds static-build"
+
+# All valid JVM variants
+VALID_JVM_VARIANTS="server client minimal core zero zeroshark custom"
+
 ###############################################################################
-# Check which interpreter of the JVM we want to build.
-# Currently we have:
-#    template: Template interpreter (the default)
-#    cpp     : C++ interpreter
+# Check if the specified JVM variant should be built. To be used in shell if
+# constructs, like this:
+# if HOTSPOT_CHECK_JVM_VARIANT(server); then
+#
+# Only valid to use after HOTSPOT_SETUP_JVM_VARIANTS has setup variants.
+
+# Definition kept in one line to allow inlining in if statements.
+# Additional [] needed to keep m4 from mangling shell constructs.
+
+
+###############################################################################
+# Check if the specified JVM features are explicitly enabled. To be used in
+# shell if constructs, like this:
+# if HOTSPOT_CHECK_JVM_FEATURE(jvmti); then
+#
+# Only valid to use after HOTSPOT_SETUP_JVM_FEATURES has setup features.
+
+# Definition kept in one line to allow inlining in if statements.
+# Additional [] needed to keep m4 from mangling shell constructs.
 
 
 ###############################################################################
-# Check which variants of the JVM that we want to build.
-# Currently we have:
-#    server: normal interpreter and a C2 or tiered C1/C2 compiler
-#    client: normal interpreter and C1 (no C2 compiler) (only 32-bit platforms)
-#    minimal1: reduced form of client with optional VM services and features stripped out
-#    zero: no machine code interpreter, no compiler
-#    zeroshark: zero interpreter and shark/llvm compiler backend
-#    core: interpreter only, no compiler (only works on some platforms)
-
+# Check which variants of the JVM that we want to build. Available variants are:
+#   server: normal interpreter, and a tiered C1/C2 compiler
+#   client: normal interpreter, and C1 (no C2 compiler)
+#   minimal: reduced form of client with optional features stripped out
+#   core: normal interpreter only, no compiler
+#   zero: C++ based interpreter only, no compiler
+#   zeroshark: C++ based interpreter, and a llvm-based compiler
+#   custom: baseline JVM with no default features
+#
 
 
 ###############################################################################
-# Setup legacy vars/targets and new vars to deal with different debug levels.
-#
-#    release: no debug information, all optimizations, no asserts.
-#    optimized: no debug information, all optimizations, no asserts, HotSpot target is 'optimized'.
-#    fastdebug: debug information (-g), all optimizations, all asserts
-#    slowdebug: debug information (-g), no optimizations, all asserts
-#
-
-
-
-
+# Check if dtrace should be enabled and has all prerequisites present.
+#
+
+
+###############################################################################
+# Set up all JVM features for each JVM variant.
+#
+
+
+###############################################################################
+# Validate JVM features once all setup is complete, including custom setup.
+#
+
+
+###############################################################################
+# Support for old hotspot build. Remove once new hotspot build has proven
+# to work satisfactory.
+#
 
 
 #
@@ -4543,7 +4646,7 @@
 
 
 #
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, 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
@@ -4627,7 +4730,7 @@
 
 
 #
-# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, 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
@@ -4678,6 +4781,9 @@
 #
 
 
+# $1 - Either TARGET or BUILD to setup the variables for.
+
+
 
 
 #%%% Build and target systems %%%
@@ -4964,7 +5070,7 @@
 #CUSTOM_AUTOCONF_INCLUDE
 
 # Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1460963400
+DATE_WHEN_GENERATED=1462204427
 
 ###############################################################################
 #
@@ -4989,6 +5095,13 @@
       TOOLCHAIN_DESCRIPTION=${!toolchain_var_name}
       $PRINTF "  %-10s  %s\n" $toolchain "$TOOLCHAIN_DESCRIPTION"
     done
+    $PRINTF "\n"
+
+    # Print available jvm features
+    $PRINTF "The following JVM features are available as arguments to --with-jvm-features.\n"
+    $PRINTF "Which are valid to use depends on the target platform.\n  "
+    $PRINTF "%s " $VALID_JVM_FEATURES
+    $PRINTF "\n"
 
     # And now exit directly
     exit 0
@@ -15229,6 +15342,7 @@
 
 
 
+
   # Also store the legacy naming of the cpu.
   # Ie i586 and amd64 instead of x86 and x86_64
   OPENJDK_TARGET_CPU_LEGACY="$OPENJDK_TARGET_CPU"
@@ -15259,37 +15373,6 @@
   fi
 
 
-  # Now do the same for OPENJDK_BUILD_CPU...
-  # Also store the legacy naming of the cpu.
-  # Ie i586 and amd64 instead of x86 and x86_64
-  OPENJDK_BUILD_CPU_LEGACY="$OPENJDK_BUILD_CPU"
-  if test "x$OPENJDK_BUILD_CPU" = xx86; then
-    OPENJDK_BUILD_CPU_LEGACY="i586"
-  elif test "x$OPENJDK_BUILD_OS" != xmacosx && test "x$OPENJDK_BUILD_CPU" = xx86_64; then
-    # On all platforms except MacOSX replace x86_64 with amd64.
-    OPENJDK_BUILD_CPU_LEGACY="amd64"
-  fi
-
-
-  # And the second legacy naming of the cpu.
-  # Ie i386 and amd64 instead of x86 and x86_64.
-  OPENJDK_BUILD_CPU_LEGACY_LIB="$OPENJDK_BUILD_CPU"
-  if test "x$OPENJDK_BUILD_CPU" = xx86; then
-    OPENJDK_BUILD_CPU_LEGACY_LIB="i386"
-  elif test "x$OPENJDK_BUILD_CPU" = xx86_64; then
-    OPENJDK_BUILD_CPU_LEGACY_LIB="amd64"
-  fi
-
-
-  # This is the name of the cpu (but using i386 and amd64 instead of
-  # x86 and x86_64, respectively), preceeded by a /, to be used when
-  # locating libraries. On macosx, it's empty, though.
-  OPENJDK_BUILD_CPU_LIBDIR="/$OPENJDK_BUILD_CPU_LEGACY_LIB"
-  if test "x$OPENJDK_BUILD_OS" = xmacosx; then
-    OPENJDK_BUILD_CPU_LIBDIR=""
-  fi
-
-
   # OPENJDK_TARGET_CPU_ISADIR is normally empty. On 64-bit Solaris systems, it is set to
   # /amd64 or /sparcv9. This string is appended to some library paths, like this:
   # /usr/lib${OPENJDK_TARGET_CPU_ISADIR}/libexample.so
@@ -15332,6 +15415,144 @@
   fi
 
 
+  if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+      OPENJDK_TARGET_OS_EXPORT_DIR=macosx
+  else
+      OPENJDK_TARGET_OS_EXPORT_DIR=${OPENJDK_TARGET_OS_TYPE}
+  fi
+
+
+  if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+    A_LP64="LP64:="
+    # -D_LP64=1 is only set on linux and mac. Setting on windows causes diff in
+    # unpack200.exe
+    if test "x$OPENJDK_TARGET_OS" = xlinux || test "x$OPENJDK_TARGET_OS" = xmacosx; then
+      OPENJDK_TARGET_ADD_LP64="-D_LP64=1"
+    fi
+  fi
+  LP64=$A_LP64
+
+
+  if test "x$COMPILE_TYPE" = "xcross"; then
+    # FIXME: ... or should this include reduced builds..?
+    DEFINE_CROSS_COMPILE_ARCH="CROSS_COMPILE_ARCH:=$OPENJDK_TARGET_CPU_LEGACY"
+  else
+    DEFINE_CROSS_COMPILE_ARCH=""
+  fi
+
+
+  # Convert openjdk platform names to hotspot names
+
+  HOTSPOT_TARGET_OS=${OPENJDK_TARGET_OS}
+  if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+    HOTSPOT_TARGET_OS=bsd
+  fi
+
+
+  HOTSPOT_TARGET_OS_TYPE=${OPENJDK_TARGET_OS_TYPE}
+  if test "x$OPENJDK_TARGET_OS_TYPE" = xunix; then
+    HOTSPOT_TARGET_OS_TYPE=posix
+  fi
+
+
+  HOTSPOT_TARGET_CPU=${OPENJDK_TARGET_CPU}
+  if test "x$OPENJDK_TARGET_CPU" = xx86; then
+    HOTSPOT_TARGET_CPU=x86_32
+  elif test "x$OPENJDK_TARGET_CPU" = xsparcv9; then
+    HOTSPOT_TARGET_CPU=sparc
+  elif test "x$OPENJDK_TARGET_CPU" = xppc64; then
+    HOTSPOT_TARGET_CPU=ppc_64
+  elif test "x$OPENJDK_TARGET_CPU" = xppc64le; then
+    HOTSPOT_TARGET_CPU=ppc_64
+  fi
+
+
+  # This is identical with OPENJDK_*, but define anyway for consistency.
+  HOTSPOT_TARGET_CPU_ARCH=${OPENJDK_TARGET_CPU_ARCH}
+
+
+  # Setup HOTSPOT_TARGET_CPU_DEFINE
+  if test "x$OPENJDK_TARGET_CPU" = xx86; then
+    HOTSPOT_TARGET_CPU_DEFINE=IA32
+  elif test "x$OPENJDK_TARGET_CPU" = xx86_64; then
+    HOTSPOT_TARGET_CPU_DEFINE=AMD64
+  elif test "x$OPENJDK_TARGET_CPU" = xsparcv9; then
+    HOTSPOT_TARGET_CPU_DEFINE=SPARC
+  elif test "x$OPENJDK_TARGET_CPU" = xaarch64; then
+    HOTSPOT_TARGET_CPU_DEFINE=AARCH64
+  elif test "x$OPENJDK_TARGET_CPU" = xppc64; then
+    HOTSPOT_TARGET_CPU_DEFINE=PPC64
+  elif test "x$OPENJDK_TARGET_CPU" = xppc64le; then
+    HOTSPOT_TARGET_CPU_DEFINE=PPC64
+
+  # The cpu defines below are for zero, we don't support them directly.
+  elif test "x$OPENJDK_TARGET_CPU" = xsparc; then
+    HOTSPOT_TARGET_CPU_DEFINE=SPARC
+  elif test "x$OPENJDK_TARGET_CPU" = xppc; then
+    HOTSPOT_TARGET_CPU_DEFINE=PPC32
+  elif test "x$OPENJDK_TARGET_CPU" = xs390; then
+    HOTSPOT_TARGET_CPU_DEFINE=S390
+  elif test "x$OPENJDK_TARGET_CPU" = xs390x; then
+    HOTSPOT_TARGET_CPU_DEFINE=S390
+  fi
+
+
+
+
+  # Also store the legacy naming of the cpu.
+  # Ie i586 and amd64 instead of x86 and x86_64
+  OPENJDK_BUILD_CPU_LEGACY="$OPENJDK_BUILD_CPU"
+  if test "x$OPENJDK_BUILD_CPU" = xx86; then
+    OPENJDK_BUILD_CPU_LEGACY="i586"
+  elif test "x$OPENJDK_BUILD_OS" != xmacosx && test "x$OPENJDK_BUILD_CPU" = xx86_64; then
+    # On all platforms except MacOSX replace x86_64 with amd64.
+    OPENJDK_BUILD_CPU_LEGACY="amd64"
+  fi
+
+
+  # And the second legacy naming of the cpu.
+  # Ie i386 and amd64 instead of x86 and x86_64.
+  OPENJDK_BUILD_CPU_LEGACY_LIB="$OPENJDK_BUILD_CPU"
+  if test "x$OPENJDK_BUILD_CPU" = xx86; then
+    OPENJDK_BUILD_CPU_LEGACY_LIB="i386"
+  elif test "x$OPENJDK_BUILD_CPU" = xx86_64; then
+    OPENJDK_BUILD_CPU_LEGACY_LIB="amd64"
+  fi
+
+
+  # This is the name of the cpu (but using i386 and amd64 instead of
+  # x86 and x86_64, respectively), preceeded by a /, to be used when
+  # locating libraries. On macosx, it's empty, though.
+  OPENJDK_BUILD_CPU_LIBDIR="/$OPENJDK_BUILD_CPU_LEGACY_LIB"
+  if test "x$OPENJDK_BUILD_OS" = xmacosx; then
+    OPENJDK_BUILD_CPU_LIBDIR=""
+  fi
+
+
+  # OPENJDK_BUILD_CPU_ISADIR is normally empty. On 64-bit Solaris systems, it is set to
+  # /amd64 or /sparcv9. This string is appended to some library paths, like this:
+  # /usr/lib${OPENJDK_BUILD_CPU_ISADIR}/libexample.so
+  OPENJDK_BUILD_CPU_ISADIR=""
+  if test "x$OPENJDK_BUILD_OS" = xsolaris; then
+    if test "x$OPENJDK_BUILD_CPU" = xx86_64; then
+      OPENJDK_BUILD_CPU_ISADIR="/amd64"
+    elif test "x$OPENJDK_BUILD_CPU" = xsparcv9; then
+      OPENJDK_BUILD_CPU_ISADIR="/sparcv9"
+    fi
+  fi
+
+
+  # Setup OPENJDK_BUILD_CPU_OSARCH, which is used to set the os.arch Java system property
+  OPENJDK_BUILD_CPU_OSARCH="$OPENJDK_BUILD_CPU"
+  if test "x$OPENJDK_BUILD_OS" = xlinux && test "x$OPENJDK_BUILD_CPU" = xx86; then
+    # On linux only, we replace x86 with i386.
+    OPENJDK_BUILD_CPU_OSARCH="i386"
+  elif test "x$OPENJDK_BUILD_OS" != xmacosx && test "x$OPENJDK_BUILD_CPU" = xx86_64; then
+    # On all platforms except macosx, we replace x86_64 with amd64.
+    OPENJDK_BUILD_CPU_OSARCH="amd64"
+  fi
+
+
   OPENJDK_BUILD_CPU_JLI="$OPENJDK_BUILD_CPU"
   if test "x$OPENJDK_BUILD_CPU" = xx86; then
     OPENJDK_BUILD_CPU_JLI="i386"
@@ -15350,47 +15571,94 @@
   fi
 
 
-  if test "x$OPENJDK_TARGET_OS" = xmacosx; then
-      OPENJDK_TARGET_OS_EXPORT_DIR=macosx
-  else
-      OPENJDK_TARGET_OS_EXPORT_DIR=${OPENJDK_TARGET_OS_TYPE}
-  fi
-
-
-  if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+  if test "x$OPENJDK_BUILD_OS" = xmacosx; then
+      OPENJDK_BUILD_OS_EXPORT_DIR=macosx
+  else
+      OPENJDK_BUILD_OS_EXPORT_DIR=${OPENJDK_BUILD_OS_TYPE}
+  fi
+
+
+  if test "x$OPENJDK_BUILD_CPU_BITS" = x64; then
     A_LP64="LP64:="
     # -D_LP64=1 is only set on linux and mac. Setting on windows causes diff in
     # unpack200.exe
-    if test "x$OPENJDK_TARGET_OS" = xlinux || test "x$OPENJDK_TARGET_OS" = xmacosx; then
-      ADD_LP64="-D_LP64=1"
+    if test "x$OPENJDK_BUILD_OS" = xlinux || test "x$OPENJDK_BUILD_OS" = xmacosx; then
+      OPENJDK_BUILD_ADD_LP64="-D_LP64=1"
     fi
   fi
   LP64=$A_LP64
 
-  if test "x$OPENJDK_BUILD_CPU_BITS" = x64; then
-    if test "x$OPENJDK_BUILD_OS" = xlinux || test "x$OPENJDK_BUILD_OS" = xmacosx; then
-      OPENJDK_BUILD_ADD_LP64="-D_LP64=1"
-    fi
-  fi
 
   if test "x$COMPILE_TYPE" = "xcross"; then
     # FIXME: ... or should this include reduced builds..?
-    DEFINE_CROSS_COMPILE_ARCH="CROSS_COMPILE_ARCH:=$OPENJDK_TARGET_CPU_LEGACY"
+    DEFINE_CROSS_COMPILE_ARCH="CROSS_COMPILE_ARCH:=$OPENJDK_BUILD_CPU_LEGACY"
   else
     DEFINE_CROSS_COMPILE_ARCH=""
   fi
 
 
-  # ZERO_ARCHDEF is used to enable architecture-specific code
-  case "${OPENJDK_TARGET_CPU}" in
-    ppc)     ZERO_ARCHDEF=PPC32 ;;
-    ppc64)   ZERO_ARCHDEF=PPC64 ;;
-    s390*)   ZERO_ARCHDEF=S390  ;;
-    sparc*)  ZERO_ARCHDEF=SPARC ;;
-    x86_64*) ZERO_ARCHDEF=AMD64 ;;
-    x86)     ZERO_ARCHDEF=IA32  ;;
-    *)      ZERO_ARCHDEF=$(echo "${OPENJDK_TARGET_CPU_LEGACY_LIB}" | tr a-z A-Z)
-  esac
+  # Convert openjdk platform names to hotspot names
+
+  HOTSPOT_BUILD_OS=${OPENJDK_BUILD_OS}
+  if test "x$OPENJDK_BUILD_OS" = xmacosx; then
+    HOTSPOT_BUILD_OS=bsd
+  fi
+
+
+  HOTSPOT_BUILD_OS_TYPE=${OPENJDK_BUILD_OS_TYPE}
+  if test "x$OPENJDK_BUILD_OS_TYPE" = xunix; then
+    HOTSPOT_BUILD_OS_TYPE=posix
+  fi
+
+
+  HOTSPOT_BUILD_CPU=${OPENJDK_BUILD_CPU}
+  if test "x$OPENJDK_BUILD_CPU" = xx86; then
+    HOTSPOT_BUILD_CPU=x86_32
+  elif test "x$OPENJDK_BUILD_CPU" = xsparcv9; then
+    HOTSPOT_BUILD_CPU=sparc
+  elif test "x$OPENJDK_BUILD_CPU" = xppc64; then
+    HOTSPOT_BUILD_CPU=ppc_64
+  elif test "x$OPENJDK_BUILD_CPU" = xppc64le; then
+    HOTSPOT_BUILD_CPU=ppc_64
+  fi
+
+
+  # This is identical with OPENJDK_*, but define anyway for consistency.
+  HOTSPOT_BUILD_CPU_ARCH=${OPENJDK_BUILD_CPU_ARCH}
+
+
+  # Setup HOTSPOT_BUILD_CPU_DEFINE
+  if test "x$OPENJDK_BUILD_CPU" = xx86; then
+    HOTSPOT_BUILD_CPU_DEFINE=IA32
+  elif test "x$OPENJDK_BUILD_CPU" = xx86_64; then
+    HOTSPOT_BUILD_CPU_DEFINE=AMD64
+  elif test "x$OPENJDK_BUILD_CPU" = xsparcv9; then
+    HOTSPOT_BUILD_CPU_DEFINE=SPARC
+  elif test "x$OPENJDK_BUILD_CPU" = xaarch64; then
+    HOTSPOT_BUILD_CPU_DEFINE=AARCH64
+  elif test "x$OPENJDK_BUILD_CPU" = xppc64; then
+    HOTSPOT_BUILD_CPU_DEFINE=PPC64
+  elif test "x$OPENJDK_BUILD_CPU" = xppc64le; then
+    HOTSPOT_BUILD_CPU_DEFINE=PPC64
+
+  # The cpu defines below are for zero, we don't support them directly.
+  elif test "x$OPENJDK_BUILD_CPU" = xsparc; then
+    HOTSPOT_BUILD_CPU_DEFINE=SPARC
+  elif test "x$OPENJDK_BUILD_CPU" = xppc; then
+    HOTSPOT_BUILD_CPU_DEFINE=PPC32
+  elif test "x$OPENJDK_BUILD_CPU" = xs390; then
+    HOTSPOT_BUILD_CPU_DEFINE=S390
+  elif test "x$OPENJDK_BUILD_CPU" = xs390x; then
+    HOTSPOT_BUILD_CPU_DEFINE=S390
+  fi
+
+
+
+
+  # ZERO_ARCHDEF is used to enable architecture-specific code.
+  # This is used in legacy hotspot build.
+  ZERO_ARCHDEF="$HOTSPOT_TARGET_CPU_DEFINE"
+
 
 
 
@@ -15929,98 +16197,6 @@
 $as_echo "$JDK_VARIANT" >&6; }
 
 
-
-# Check whether --with-jvm-interpreter was given.
-if test "${with_jvm_interpreter+set}" = set; then :
-  withval=$with_jvm_interpreter;
-fi
-
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking which interpreter of the JVM to build" >&5
-$as_echo_n "checking which interpreter of the JVM to build... " >&6; }
-  if test "x$with_jvm_interpreter" = x; then
-    JVM_INTERPRETER="template"
-  else
-    JVM_INTERPRETER="$with_jvm_interpreter"
-  fi
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JVM_INTERPRETER" >&5
-$as_echo "$JVM_INTERPRETER" >&6; }
-
-  if test "x$JVM_INTERPRETER" != xtemplate && test "x$JVM_INTERPRETER" != xcpp; then
-    as_fn_error $? "The available JVM interpreters are: template, cpp" "$LINENO" 5
-  fi
-
-
-
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variants of the JVM to build" >&5
-$as_echo_n "checking which variants of the JVM to build... " >&6; }
-
-# Check whether --with-jvm-variants was given.
-if test "${with_jvm_variants+set}" = set; then :
-  withval=$with_jvm_variants;
-fi
-
-
-  if test "x$with_jvm_variants" = x; then
-    with_jvm_variants="server"
-  fi
-
-  JVM_VARIANTS=",$with_jvm_variants,"
-  TEST_VARIANTS=`$ECHO "$JVM_VARIANTS" | $SED -e 's/server,//' -e 's/client,//'  -e 's/minimal1,//' -e 's/zero,//' -e 's/zeroshark,//' -e 's/core,//'`
-
-  if test "x$TEST_VARIANTS" != "x,"; then
-    as_fn_error $? "The available JVM variants are: server, client, minimal1, zero, zeroshark, core" "$LINENO" 5
-  fi
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_jvm_variants" >&5
-$as_echo "$with_jvm_variants" >&6; }
-
-  JVM_VARIANT_SERVER=`$ECHO "$JVM_VARIANTS" | $SED -e '/,server,/!s/.*/false/g' -e '/,server,/s/.*/true/g'`
-  JVM_VARIANT_CLIENT=`$ECHO "$JVM_VARIANTS" | $SED -e '/,client,/!s/.*/false/g' -e '/,client,/s/.*/true/g'`
-  JVM_VARIANT_MINIMAL1=`$ECHO "$JVM_VARIANTS" | $SED -e '/,minimal1,/!s/.*/false/g' -e '/,minimal1,/s/.*/true/g'`
-  JVM_VARIANT_ZERO=`$ECHO "$JVM_VARIANTS" | $SED -e '/,zero,/!s/.*/false/g' -e '/,zero,/s/.*/true/g'`
-  JVM_VARIANT_ZEROSHARK=`$ECHO "$JVM_VARIANTS" | $SED -e '/,zeroshark,/!s/.*/false/g' -e '/,zeroshark,/s/.*/true/g'`
-  JVM_VARIANT_CORE=`$ECHO "$JVM_VARIANTS" | $SED -e '/,core,/!s/.*/false/g' -e '/,core,/s/.*/true/g'`
-
-  if test "x$JVM_VARIANT_CLIENT" = xtrue; then
-    if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
-      as_fn_error $? "You cannot build a client JVM for a 64-bit machine." "$LINENO" 5
-    fi
-  fi
-  if test "x$JVM_VARIANT_MINIMAL1" = xtrue; then
-    if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
-      as_fn_error $? "You cannot build a minimal JVM for a 64-bit machine." "$LINENO" 5
-    fi
-  fi
-
-  # Replace the commas with AND for use in the build directory name.
-  ANDED_JVM_VARIANTS=`$ECHO "$JVM_VARIANTS" | $SED -e 's/^,//' -e 's/,$//' -e 's/,/AND/g'`
-  COUNT_VARIANTS=`$ECHO "$JVM_VARIANTS" | $SED -e 's/server,/1/' -e 's/client,/1/' -e 's/minimal1,/1/' -e 's/zero,/1/' -e 's/zeroshark,/1/' -e 's/core,/1/'`
-  if test "x$COUNT_VARIANTS" != "x,1"; then
-    BUILDING_MULTIPLE_JVM_VARIANTS=yes
-  else
-    BUILDING_MULTIPLE_JVM_VARIANTS=no
-  fi
-
-  if test "x$JVM_VARIANT_ZERO" = xtrue && test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = xyes; then
-    as_fn_error $? "You cannot build multiple variants with zero." "$LINENO" 5
-  fi
-
-
-
-
-
-
-
-
-
-  if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then
-    MACOSX_UNIVERSAL="true"
-  fi
-
-
-
-
   DEBUG_LEVEL="release"
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking which debug level to use" >&5
 $as_echo_n "checking which debug level to use... " >&6; }
@@ -16056,105 +16232,88 @@
     as_fn_error $? "Allowed debug levels are: release, fastdebug, slowdebug and optimized" "$LINENO" 5
   fi
 
-
-  case $DEBUG_LEVEL in
-    release )
-      VARIANT="OPT"
-      FASTDEBUG="false"
-      DEBUG_CLASSFILES="false"
-      BUILD_VARIANT_RELEASE=""
-      HOTSPOT_DEBUG_LEVEL="product"
-      HOTSPOT_EXPORT="product"
-      ;;
-    fastdebug )
-      VARIANT="DBG"
-      FASTDEBUG="true"
-      DEBUG_CLASSFILES="true"
-      BUILD_VARIANT_RELEASE="-fastdebug"
-      HOTSPOT_DEBUG_LEVEL="fastdebug"
-      HOTSPOT_EXPORT="fastdebug"
-      ;;
-    slowdebug )
-      VARIANT="DBG"
-      FASTDEBUG="false"
-      DEBUG_CLASSFILES="true"
-      BUILD_VARIANT_RELEASE="-debug"
-      HOTSPOT_DEBUG_LEVEL="debug"
-      HOTSPOT_EXPORT="debug"
-      ;;
-    optimized )
-      VARIANT="OPT"
-      FASTDEBUG="false"
-      DEBUG_CLASSFILES="false"
-      BUILD_VARIANT_RELEASE="-optimized"
-      HOTSPOT_DEBUG_LEVEL="optimized"
-      HOTSPOT_EXPORT="optimized"
-      ;;
-  esac
-
-  # The debug level 'optimized' is a little special because it is currently only
-  # applicable to the HotSpot build where it means to build a completely
-  # optimized version of the VM without any debugging code (like for the
-  # 'release' debug level which is called 'product' in the HotSpot build) but
-  # with the exception that it can contain additional code which is otherwise
-  # protected by '#ifndef PRODUCT' macros. These 'optimized' builds are used to
-  # test new and/or experimental features which are not intended for customer
-  # shipment. Because these new features need to be tested and benchmarked in
-  # real world scenarios, we want to build the containing JDK at the 'release'
-  # debug level.
+  # Translate DEBUG_LEVEL to debug level used by Hotspot
+  HOTSPOT_DEBUG_LEVEL="$DEBUG_LEVEL"
+  if test "x$DEBUG_LEVEL" = xrelease; then
+    HOTSPOT_DEBUG_LEVEL="product"
+  elif test "x$DEBUG_LEVEL" = xslowdebug; then
+    HOTSPOT_DEBUG_LEVEL="debug"
+  fi
+
   if test "x$DEBUG_LEVEL" = xoptimized; then
+    # The debug level 'optimized' is a little special because it is currently only
+    # applicable to the HotSpot build where it means to build a completely
+    # optimized version of the VM without any debugging code (like for the
+    # 'release' debug level which is called 'product' in the HotSpot build) but
+    # with the exception that it can contain additional code which is otherwise
+    # protected by '#ifndef PRODUCT' macros. These 'optimized' builds are used to
+    # test new and/or experimental features which are not intended for customer
+    # shipment. Because these new features need to be tested and benchmarked in
+    # real world scenarios, we want to build the containing JDK at the 'release'
+    # debug level.
     DEBUG_LEVEL="release"
   fi
 
-  #####
-  # Generate the legacy makefile targets for hotspot.
-  # The hotspot api for selecting the build artifacts, really, needs to be improved.
-  # JDK-7195896 will fix this on the hotspot side by using the JVM_VARIANT_* variables to
-  # determine what needs to be built. All we will need to set here is all_product, all_fastdebug etc
-  # But until then ...
-  HOTSPOT_TARGET=""
-
-  if test "x$JVM_VARIANT_SERVER" = xtrue; then
-    HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL} "
-  fi
-
-  if test "x$JVM_VARIANT_CLIENT" = xtrue; then
-    HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}1 "
-  fi
-
-  if test "x$JVM_VARIANT_MINIMAL1" = xtrue; then
-    HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}minimal1 "
-  fi
-
-  if test "x$JVM_VARIANT_ZERO" = xtrue; then
-    HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}zero "
-  fi
-
-  if test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then
-    HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}shark "
-  fi
-
-  if test "x$JVM_VARIANT_CORE" = xtrue; then
-    HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}core "
-  fi
-
-  HOTSPOT_TARGET="$HOTSPOT_TARGET docs export_$HOTSPOT_EXPORT"
-
-  # On Macosx universal binaries are produced, but they only contain
-  # 64 bit intel. This invalidates control of which jvms are built
-  # from configure, but only server is valid anyway. Fix this
-  # when hotspot makefiles are rewritten.
-  if test "x$MACOSX_UNIVERSAL" = xtrue; then
-    HOTSPOT_TARGET=universal_${HOTSPOT_EXPORT}
-  fi
-
-  #####
-
-
-
-
-
-
+
+
+
+
+
+# Check whether --with-jvm-variants was given.
+if test "${with_jvm_variants+set}" = set; then :
+  withval=$with_jvm_variants;
+fi
+
+
+  if test "x$with_jvm_variants" = x; then
+    with_jvm_variants="server"
+  fi
+  JVM_VARIANTS_OPT="$with_jvm_variants"
+
+  # Has the user listed more than one variant?
+  # Additional [] needed to keep m4 from mangling shell constructs.
+  if  [[ "$JVM_VARIANTS_OPT" =~ "," ]] ; then
+    BUILDING_MULTIPLE_JVM_VARIANTS=true
+  else
+    BUILDING_MULTIPLE_JVM_VARIANTS=false
+  fi
+  # Replace the commas with AND for use in the build directory name.
+  JVM_VARIANTS_WITH_AND=`$ECHO "$JVM_VARIANTS_OPT" | $SED -e 's/,/AND/g'`
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variants of the JVM to build" >&5
+$as_echo_n "checking which variants of the JVM to build... " >&6; }
+  # JVM_VARIANTS is a space-separated list.
+  # Also use minimal, not minimal1 (which is kept for backwards compatibility).
+  JVM_VARIANTS=`$ECHO $JVM_VARIANTS_OPT | $SED -e 's/,/ /g' -e 's/minimal1/minimal/'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JVM_VARIANTS" >&5
+$as_echo "$JVM_VARIANTS" >&6; }
+
+  # Check that the selected variants are valid
+
+  # grep filter function inspired by a comment to http://stackoverflow.com/a/1617326
+  INVALID_VARIANTS=`$GREP -Fvx "${VALID_JVM_VARIANTS// /$'\n'}" <<< "${JVM_VARIANTS// /$'\n'}"`
+  if test "x$INVALID_VARIANTS" != x; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: Unknown variant(s) specified: $INVALID_VARIANTS" >&5
+$as_echo "$as_me: Unknown variant(s) specified: $INVALID_VARIANTS" >&6;}
+    as_fn_error $? "The available JVM variants are: $VALID_JVM_VARIANTS" "$LINENO" 5
+  fi
+
+  # All "special" variants share the same output directory ("server")
+  VALID_MULTIPLE_JVM_VARIANTS="server client minimal"
+  INVALID_MULTIPLE_VARIANTS=`$GREP -Fvx "${VALID_MULTIPLE_JVM_VARIANTS// /$'\n'}" <<< "${JVM_VARIANTS// /$'\n'}"`
+  if  test "x$INVALID_MULTIPLE_VARIANTS" != x && test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = xtrue; then
+    as_fn_error $? "You cannot build multiple variants with anything else than $VALID_MULTIPLE_JVM_VARIANTS." "$LINENO" 5
+  fi
+
+
+
+
+  if   [[ " $JVM_VARIANTS " =~ " zero " ]]   ||   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
+    # zero behaves as a platform and rewrites these values. This is really weird. :(
+    # We are guaranteed that we do not build any other variants when building zero.
+    HOTSPOT_TARGET_CPU=zero
+    HOTSPOT_TARGET_CPU_ARCH=zero
+  fi
 
 
 # With basic setup done, call the custom early hook.
@@ -16603,8 +16762,8 @@
 
 
   if test "x$OPENJDK_BUILD_OS" = "xsolaris"; then
-    # Add extra search paths on solaris for utilities like ar and as etc...
-    PATH="$PATH:/usr/ccs/bin:/usr/sfw/bin:/opt/csw/bin"
+    # Add extra search paths on solaris for utilities like ar, as, dtrace etc...
+    PATH="$PATH:/usr/ccs/bin:/usr/sfw/bin:/opt/csw/bin:/usr/sbin"
   fi
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
@@ -16643,7 +16802,7 @@
     if test "x${CONF_NAME}" = x; then
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: in default location" >&5
 $as_echo "in default location" >&6; }
-      CONF_NAME="${OPENJDK_TARGET_OS}-${OPENJDK_TARGET_CPU}-${JDK_VARIANT}-${ANDED_JVM_VARIANTS}-${DEBUG_LEVEL}"
+      CONF_NAME="${OPENJDK_TARGET_OS}-${OPENJDK_TARGET_CPU}-${JDK_VARIANT}-${JVM_VARIANTS_WITH_AND}-${DEBUG_LEVEL}"
     else
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: in build directory with custom name" >&5
 $as_echo "in build directory with custom name" >&6; }
@@ -22143,6 +22302,203 @@
   # Publish this variable in the help.
 
 
+  if [ -z "${DTRACE+x}" ]; then
+    # The variable is not set by user, try to locate tool using the code snippet
+    for ac_prog in dtrace
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_DTRACE+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $DTRACE in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_DTRACE="$DTRACE" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_DTRACE="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+DTRACE=$ac_cv_path_DTRACE
+if test -n "$DTRACE"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DTRACE" >&5
+$as_echo "$DTRACE" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$DTRACE" && break
+done
+
+  else
+    # The variable is set, but is it from the command line or the environment?
+
+    # Try to remove the string !DTRACE! from our list.
+    try_remove_var=${CONFIGURE_OVERRIDDEN_VARIABLES//!DTRACE!/}
+    if test "x$try_remove_var" = "x$CONFIGURE_OVERRIDDEN_VARIABLES"; then
+      # If it failed, the variable was not from the command line. Ignore it,
+      # but warn the user (except for BASH, which is always set by the calling BASH).
+      if test "xDTRACE" != xBASH; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring value of DTRACE from the environment. Use command line variables instead." >&5
+$as_echo "$as_me: WARNING: Ignoring value of DTRACE from the environment. Use command line variables instead." >&2;}
+      fi
+      # Try to locate tool using the code snippet
+      for ac_prog in dtrace
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_DTRACE+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $DTRACE in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_DTRACE="$DTRACE" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_DTRACE="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+DTRACE=$ac_cv_path_DTRACE
+if test -n "$DTRACE"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DTRACE" >&5
+$as_echo "$DTRACE" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$DTRACE" && break
+done
+
+    else
+      # If it succeeded, then it was overridden by the user. We will use it
+      # for the tool.
+
+      # First remove it from the list of overridden variables, so we can test
+      # for unknown variables in the end.
+      CONFIGURE_OVERRIDDEN_VARIABLES="$try_remove_var"
+
+      # Check if we try to supply an empty value
+      if test "x$DTRACE" = x; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: Setting user supplied tool DTRACE= (no value)" >&5
+$as_echo "$as_me: Setting user supplied tool DTRACE= (no value)" >&6;}
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DTRACE" >&5
+$as_echo_n "checking for DTRACE... " >&6; }
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5
+$as_echo "disabled" >&6; }
+      else
+        # Check if the provided tool contains a complete path.
+        tool_specified="$DTRACE"
+        tool_basename="${tool_specified##*/}"
+        if test "x$tool_basename" = "x$tool_specified"; then
+          # A command without a complete path is provided, search $PATH.
+          { $as_echo "$as_me:${as_lineno-$LINENO}: Will search for user supplied tool DTRACE=$tool_basename" >&5
+$as_echo "$as_me: Will search for user supplied tool DTRACE=$tool_basename" >&6;}
+          # Extract the first word of "$tool_basename", so it can be a program name with args.
+set dummy $tool_basename; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_DTRACE+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $DTRACE in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_DTRACE="$DTRACE" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_DTRACE="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+DTRACE=$ac_cv_path_DTRACE
+if test -n "$DTRACE"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DTRACE" >&5
+$as_echo "$DTRACE" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+          if test "x$DTRACE" = x; then
+            as_fn_error $? "User supplied tool $tool_basename could not be found" "$LINENO" 5
+          fi
+        else
+          # Otherwise we believe it is a complete path. Use it as it is.
+          { $as_echo "$as_me:${as_lineno-$LINENO}: Will use user supplied tool DTRACE=$tool_specified" >&5
+$as_echo "$as_me: Will use user supplied tool DTRACE=$tool_specified" >&6;}
+          { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DTRACE" >&5
+$as_echo_n "checking for DTRACE... " >&6; }
+          if test ! -x "$tool_specified"; then
+            { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+            as_fn_error $? "User supplied tool DTRACE=$tool_specified does not exist or is not executable" "$LINENO" 5
+          fi
+          { $as_echo "$as_me:${as_lineno-$LINENO}: result: $tool_specified" >&5
+$as_echo "$tool_specified" >&6; }
+        fi
+      fi
+    fi
+
+  fi
+
+
+
+
+  # Publish this variable in the help.
+
+
   if [ -z "${PATCH+x}" ]; then
     # The variable is not set by user, try to locate tool using the code snippet
     for ac_prog in gpatch patch
@@ -23422,10 +23778,7 @@
 
   # Should we build the serviceability agent (SA)?
   INCLUDE_SA=true
-  if test "x$JVM_VARIANT_ZERO" = xtrue ; then
-    INCLUDE_SA=false
-  fi
-  if test "x$JVM_VARIANT_ZEROSHARK" = xtrue ; then
+  if   [[ " $JVM_VARIANTS " =~ " zero " ]]   ||   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
     INCLUDE_SA=false
   fi
   if test "x$OPENJDK_TARGET_OS" = xaix ; then
@@ -23487,22 +23840,6 @@
 
 
 
-  # Control wether Hotspot runs Queens test after build.
-  # Check whether --enable-hotspot-test-in-build was given.
-if test "${enable_hotspot_test_in_build+set}" = set; then :
-  enableval=$enable_hotspot_test_in_build;
-else
-  enable_hotspot_test_in_build=no
-fi
-
-  if test "x$enable_hotspot_test_in_build" = "xyes"; then
-    TEST_IN_BUILD=true
-  else
-    TEST_IN_BUILD=false
-  fi
-
-
-
   # Warn user that old version arguments are deprecated.
 
 
@@ -23553,6 +23890,7 @@
 
 
 
+
   # Override version from arguments
 
   # If --with-version-string is set, process it first. It is possible to
@@ -30625,6 +30963,10 @@
 
 
 
+
+
+
+
   # The global CFLAGS and LDLAGS variables are used by configure tests and
   # should include the extra parameters
   CFLAGS="$EXTRA_CFLAGS"
@@ -46752,6 +47094,17 @@
   fi
 
 
+  # Setup hotspot lecagy names for toolchains
+  HOTSPOT_TOOLCHAIN_TYPE=$TOOLCHAIN_TYPE
+  if test "x$TOOLCHAIN_TYPE" = xclang; then
+    HOTSPOT_TOOLCHAIN_TYPE=gcc
+  elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+    HOTSPOT_TOOLCHAIN_TYPE=sparcWorks
+  elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+    HOTSPOT_TOOLCHAIN_TYPE=visCPP
+  fi
+
+
 
 # Setup the JTReg Regression Test Harness.
 
@@ -47231,8 +47584,10 @@
   # On Windows, we need to set RC flags.
   if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
     RC_FLAGS="-nologo -l0x409"
+    JVM_RCFLAGS="-nologo"
     if test "x$DEBUG_LEVEL" = xrelease; then
       RC_FLAGS="$RC_FLAGS -DNDEBUG"
+      JVM_RCFLAGS="$JVM_RCFLAGS -DNDEBUG"
     fi
 
     # The version variables used to create RC_FLAGS may be overridden
@@ -47248,7 +47603,18 @@
         -D\"JDK_COPYRIGHT=Copyright \xA9 $COPYRIGHT_YEAR\" \
         -D\"JDK_NAME=\$(PRODUCT_NAME) \$(JDK_RC_PLATFORM_NAME) \$(VERSION_MAJOR)\" \
         -D\"JDK_FVER=\$(subst .,\$(COMMA),\$(VERSION_NUMBER_FOUR_POSITIONS))\""
-  fi
+
+    JVM_RCFLAGS="$JVM_RCFLAGS \
+        -D\"HS_BUILD_ID=\$(VERSION_STRING)\" \
+        -D\"HS_COMPANY=\$(COMPANY_NAME)\" \
+        -D\"JDK_DOTVER=\$(VERSION_NUMBER_FOUR_POSITIONS)\" \
+        -D\"HS_COPYRIGHT=Copyright $COPYRIGHT_YEAR\" \
+        -D\"HS_NAME=\$(PRODUCT_NAME) \$(VERSION_SHORT)\" \
+        -D\"JDK_VER=\$(subst .,\$(COMMA),\$(VERSION_NUMBER_FOUR_POSITIONS))\" \
+        -D\"HS_FNAME=jvm.dll\" \
+        -D\"HS_INTERNAL_NAME=jvm\""
+  fi
+
 
 
   if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
@@ -47416,6 +47782,10 @@
   CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}"
   LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}"
 
+  JVM_CFLAGS="$JVM_CFLAGS $ADDED_CFLAGS"
+  JVM_LDFLAGS="$JVM_LDFLAGS $ADDED_LDFLAGS"
+  JVM_ASFLAGS="$JVM_ASFLAGS $ADDED_CFLAGS"
+
   elif test "x$COMPILE_TYPE" = xreduced; then
     if test "x$OPENJDK_TARGET_OS_TYPE" = xunix; then
       # Specify -m if running reduced on unix platforms
@@ -47436,7 +47806,16 @@
   CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}"
   LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}"
 
-    fi
+  JVM_CFLAGS="$JVM_CFLAGS $ADDED_CFLAGS"
+  JVM_LDFLAGS="$JVM_LDFLAGS $ADDED_LDFLAGS"
+  JVM_ASFLAGS="$JVM_ASFLAGS $ADDED_CFLAGS"
+
+    fi
+  fi
+  if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+    JVM_CFLAGS="$JVM_CFLAGS ${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}"
+    JVM_LDFLAGS="$JVM_LDFLAGS ${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}"
+    JVM_ASFLAGS="$JVM_ASFLAGS ${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}"
   fi
 
   # Make compilation sanity check
@@ -47562,6 +47941,10 @@
   CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}"
   LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}"
 
+  JVM_CFLAGS="$JVM_CFLAGS $ADDED_CFLAGS"
+  JVM_LDFLAGS="$JVM_LDFLAGS $ADDED_LDFLAGS"
+  JVM_ASFLAGS="$JVM_ASFLAGS $ADDED_CFLAGS"
+
 
       # We have to unset 'ac_cv_sizeof_int_p' first, otherwise AC_CHECK_SIZEOF will use the previously cached value!
       unset ac_cv_sizeof_int_p
@@ -47908,6 +48291,7 @@
         SHARED_LIBRARY_FLAGS ='-undefined dynamic_lookup'
       else
         SHARED_LIBRARY_FLAGS="-dynamiclib -compatibility_version 1.0.0 -current_version 1.0.0 $PICFLAG"
+        JVM_CFLAGS="$JVM_CFLAGS $PICFLAG"
       fi
       SET_EXECUTABLE_ORIGIN='-Wl,-rpath,@loader_path/.'
       SET_SHARED_LIBRARY_ORIGIN="$SET_EXECUTABLE_ORIGIN"
@@ -47933,6 +48317,10 @@
       SET_SHARED_LIBRARY_ORIGIN="$SET_EXECUTABLE_ORIGIN"
       SET_SHARED_LIBRARY_NAME='-Wl,-install_name,@rpath/$1'
       SET_SHARED_LIBRARY_MAPFILE='-Wl,-exported_symbols_list,$1'
+
+      if test "x$STATIC_BUILD" = xfalse; then
+        JVM_CFLAGS="$JVM_CFLAGS -fPIC"
+      fi
     else
       # Default works for linux, might work on other platforms as well.
       PICFLAG='-fPIC'
@@ -47992,11 +48380,6 @@
 
 
 
-  if test "x$OPENJDK_TARGET_OS" = xsolaris; then
-    CFLAGS_JDK="${CFLAGS_JDK} -D__solaris__"
-    CXXFLAGS_JDK="${CXXFLAGS_JDK} -D__solaris__"
-    CFLAGS_JDKLIB_EXTRA='-xstrconst'
-  fi
   # The (cross) compiler is now configured, we can now test capabilities
   # of the target platform.
 
@@ -48054,6 +48437,22 @@
 
 
 
+  # Debug symbols for JVM_CFLAGS
+  if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+    JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -xs"
+    if test "x$DEBUG_LEVEL" = xslowdebug; then
+      JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -g"
+    else
+      # -g0 does not disable inlining, which -g does.
+      JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -g0"
+    fi
+  elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+    JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -Z7 -d2Zi+"
+  else
+    JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS -g"
+  fi
+
+
   # bounds, memory and behavior checking options
   if test "x$TOOLCHAIN_TYPE" = xgcc; then
     case $DEBUG_LEVEL in
@@ -48064,7 +48463,7 @@
       # no adjustment
       ;;
     slowdebug )
-      # FIXME: By adding this to C(XX)FLAGS_DEBUG_OPTIONS it
+      # FIXME: By adding this to C(XX)FLAGS_DEBUG_OPTIONS/JVM_CFLAGS_SYMBOLS it
       # get's added conditionally on whether we produce debug symbols or not.
       # This is most likely not really correct.
 
@@ -48339,40 +48738,59 @@
 
       CFLAGS_DEBUG_OPTIONS="$STACK_PROTECTOR_CFLAG --param ssp-buffer-size=1"
       CXXFLAGS_DEBUG_OPTIONS="$STACK_PROTECTOR_CFLAG --param ssp-buffer-size=1"
+      if test "x$STACK_PROTECTOR_CFLAG" != x; then
+        JVM_CFLAGS_SYMBOLS="$JVM_CFLAGS_SYMBOLS $STACK_PROTECTOR_CFLAG --param ssp-buffer-size=1"
+      fi
       ;;
     esac
   fi
 
+  if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+    if test "x$DEBUG_LEVEL" != xrelease; then
+      if test "x$OPENJDK_TARGET_CPU" = xx86_64; then
+        JVM_CFLAGS="$JVM_CFLAGS -homeparams"
+      fi
+    fi
+  fi
+
   # Optimization levels
   if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
     CC_HIGHEST="$CC_HIGHEST -fns -fsimple -fsingle -xbuiltin=%all -xdepend -xrestrict -xlibmil"
 
     if test "x$OPENJDK_TARGET_CPU_ARCH" = "xx86"; then
       # FIXME: seems we always set -xregs=no%frameptr; put it elsewhere more global?
+      C_O_FLAG_HIGHEST_JVM="-xO4"
       C_O_FLAG_HIGHEST="-xO4 -Wu,-O4~yz $CC_HIGHEST -xalias_level=basic -xregs=no%frameptr"
       C_O_FLAG_HI="-xO4 -Wu,-O4~yz -xregs=no%frameptr"
       C_O_FLAG_NORM="-xO2 -Wu,-O2~yz -xregs=no%frameptr"
       C_O_FLAG_DEBUG="-xregs=no%frameptr"
+      C_O_FLAG_DEBUG_JVM=""
       C_O_FLAG_NONE="-xregs=no%frameptr"
+      CXX_O_FLAG_HIGHEST_JVM="-xO4"
       CXX_O_FLAG_HIGHEST="-xO4 -Qoption ube -O4~yz $CC_HIGHEST -xregs=no%frameptr"
       CXX_O_FLAG_HI="-xO4 -Qoption ube -O4~yz -xregs=no%frameptr"
       CXX_O_FLAG_NORM="-xO2 -Qoption ube -O2~yz -xregs=no%frameptr"
       CXX_O_FLAG_DEBUG="-xregs=no%frameptr"
+      CXX_O_FLAG_DEBUG_JVM=""
       CXX_O_FLAG_NONE="-xregs=no%frameptr"
       if test "x$OPENJDK_TARGET_CPU_BITS" = "x32"; then
         C_O_FLAG_HIGHEST="$C_O_FLAG_HIGHEST -xchip=pentium"
         CXX_O_FLAG_HIGHEST="$CXX_O_FLAG_HIGHEST -xchip=pentium"
       fi
     elif test "x$OPENJDK_TARGET_CPU_ARCH" = "xsparc"; then
+      C_O_FLAG_HIGHEST_JVM="-xO4"
       C_O_FLAG_HIGHEST="-xO4 -Wc,-Qrm-s -Wc,-Qiselect-T0 $CC_HIGHEST -xalias_level=basic -xprefetch=auto,explicit -xchip=ultra"
       C_O_FLAG_HI="-xO4 -Wc,-Qrm-s -Wc,-Qiselect-T0"
       C_O_FLAG_NORM="-xO2 -Wc,-Qrm-s -Wc,-Qiselect-T0"
       C_O_FLAG_DEBUG=""
+      C_O_FLAG_DEBUG_JVM=""
       C_O_FLAG_NONE=""
+      CXX_O_FLAG_HIGHEST_JVM="-xO4"
       CXX_O_FLAG_HIGHEST="-xO4 -Qoption cg -Qrm-s -Qoption cg -Qiselect-T0 $CC_HIGHEST -xprefetch=auto,explicit -xchip=ultra"
       CXX_O_FLAG_HI="-xO4 -Qoption cg -Qrm-s -Qoption cg -Qiselect-T0"
       CXX_O_FLAG_NORM="-xO2 -Qoption cg -Qrm-s -Qoption cg -Qiselect-T0"
       CXX_O_FLAG_DEBUG=""
+      CXX_O_FLAG_DEBUG_JVM=""
       CXX_O_FLAG_NONE=""
     fi
   else
@@ -48382,48 +48800,75 @@
       if test "x$OPENJDK_TARGET_OS" = xmacosx; then
         # On MacOSX we optimize for size, something
         # we should do for all platforms?
+        C_O_FLAG_HIGHEST_JVM="-Os"
         C_O_FLAG_HIGHEST="-Os"
         C_O_FLAG_HI="-Os"
         C_O_FLAG_NORM="-Os"
-      else
+        C_O_FLAG_SIZE="-Os"
+      else
+        C_O_FLAG_HIGHEST_JVM="-O3"
         C_O_FLAG_HIGHEST="-O3"
         C_O_FLAG_HI="-O3"
         C_O_FLAG_NORM="-O2"
+        C_O_FLAG_SIZE="-Os"
       fi
       C_O_FLAG_DEBUG="-O0"
+      if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+        C_O_FLAG_DEBUG_JVM=""
+      elif test "x$OPENJDK_TARGET_OS" = xlinux; then
+        C_O_FLAG_DEBUG_JVM="-O0"
+      fi
       C_O_FLAG_NONE="-O0"
     elif test "x$TOOLCHAIN_TYPE" = xclang; then
       if test "x$OPENJDK_TARGET_OS" = xmacosx; then
         # On MacOSX we optimize for size, something
         # we should do for all platforms?
+        C_O_FLAG_HIGHEST_JVM="-Os"
         C_O_FLAG_HIGHEST="-Os"
         C_O_FLAG_HI="-Os"
         C_O_FLAG_NORM="-Os"
-      else
+        C_O_FLAG_SIZE="-Os"
+      else
+        C_O_FLAG_HIGHEST_JVM="-O3"
         C_O_FLAG_HIGHEST="-O3"
         C_O_FLAG_HI="-O3"
         C_O_FLAG_NORM="-O2"
+        C_O_FLAG_SIZE="-Os"
       fi
       C_O_FLAG_DEBUG="-O0"
+      if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+        C_O_FLAG_DEBUG_JVM=""
+      elif test "x$OPENJDK_TARGET_OS" = xlinux; then
+        C_O_FLAG_DEBUG_JVM="-O0"
+      fi
       C_O_FLAG_NONE="-O0"
     elif test "x$TOOLCHAIN_TYPE" = xxlc; then
+      C_O_FLAG_HIGHEST_JVM="-O3"
       C_O_FLAG_HIGHEST="-O3"
       C_O_FLAG_HI="-O3 -qstrict"
       C_O_FLAG_NORM="-O2"
       C_O_FLAG_DEBUG="-qnoopt"
+      # FIXME: Value below not verified.
+      C_O_FLAG_DEBUG_JVM=""
       C_O_FLAG_NONE="-qnoopt"
     elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+      C_O_FLAG_HIGHEST_JVM="-O2 -Oy-"
       C_O_FLAG_HIGHEST="-O2"
       C_O_FLAG_HI="-O1"
       C_O_FLAG_NORM="-O1"
       C_O_FLAG_DEBUG="-Od"
+      C_O_FLAG_DEBUG_JVM=""
       C_O_FLAG_NONE="-Od"
-    fi
+      C_O_FLAG_SIZE="-Os"
+    fi
+    CXX_O_FLAG_HIGHEST_JVM="$C_O_FLAG_HIGHEST_JVM"
     CXX_O_FLAG_HIGHEST="$C_O_FLAG_HIGHEST"
     CXX_O_FLAG_HI="$C_O_FLAG_HI"
     CXX_O_FLAG_NORM="$C_O_FLAG_NORM"
     CXX_O_FLAG_DEBUG="$C_O_FLAG_DEBUG"
+    CXX_O_FLAG_DEBUG_JVM="$C_O_FLAG_DEBUG_JVM"
     CXX_O_FLAG_NONE="$C_O_FLAG_NONE"
+    CXX_O_FLAG_SIZE="$C_O_FLAG_SIZE"
   fi
 
   # Adjust optimization flags according to debug level.
@@ -48438,12 +48883,16 @@
       ;;
     slowdebug )
       # Disable optimization
+      C_O_FLAG_HIGHEST_JVM="$C_O_FLAG_DEBUG_JVM"
       C_O_FLAG_HIGHEST="$C_O_FLAG_DEBUG"
       C_O_FLAG_HI="$C_O_FLAG_DEBUG"
       C_O_FLAG_NORM="$C_O_FLAG_DEBUG"
+      C_O_FLAG_SIZE="$C_O_FLAG_DEBUG"
+      CXX_O_FLAG_HIGHEST_JVM="$CXX_O_FLAG_DEBUG_JVM"
       CXX_O_FLAG_HIGHEST="$CXX_O_FLAG_DEBUG"
       CXX_O_FLAG_HI="$CXX_O_FLAG_DEBUG"
       CXX_O_FLAG_NORM="$CXX_O_FLAG_DEBUG"
+      CXX_O_FLAG_SIZE="$CXX_O_FLAG_DEBUG"
       ;;
   esac
 
@@ -48459,6 +48908,12 @@
 
 
 
+
+
+
+
+
+
   # Special extras...
   if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
     if test "x$OPENJDK_TARGET_CPU_ARCH" = "xsparc"; then
@@ -48570,10 +49025,23 @@
     CXXFLAGS_JDK="${CXXFLAGS_JDK} ${CXXSTD_CXXFLAG}"
 
   fi
-
-  CFLAGS_JDK="${CFLAGS_JDK} $EXTRA_CFLAGS"
-  CXXFLAGS_JDK="${CXXFLAGS_JDK} $EXTRA_CXXFLAGS"
-  LDFLAGS_JDK="${LDFLAGS_JDK} $EXTRA_LDFLAGS"
+  if test "x$OPENJDK_TARGET_OS" = xsolaris; then
+    CFLAGS_JDK="${CFLAGS_JDK} -D__solaris__"
+    CXXFLAGS_JDK="${CXXFLAGS_JDK} -D__solaris__"
+    CFLAGS_JDKLIB_EXTRA='-xstrconst'
+    CFLAGS_JDK="${CFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
+    CXXFLAGS_JDK="${CXXFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
+  fi
+
+  if test "x$OPENJDK_TARGET_OS" = xsolaris; then
+    CFLAGS_JDK="${CFLAGS_JDK} -D__solaris__"
+    CXXFLAGS_JDK="${CXXFLAGS_JDK} -D__solaris__"
+    CFLAGS_JDKLIB_EXTRA='-xstrconst'
+  fi
+
+  CFLAGS_JDK="${CFLAGS_JDK} ${EXTRA_CFLAGS}"
+  CXXFLAGS_JDK="${CXXFLAGS_JDK} ${EXTRA_CXXFLAGS}"
+  LDFLAGS_JDK="${LDFLAGS_JDK} ${EXTRA_LDFLAGS}"
 
   ###############################################################################
   #
@@ -48586,9 +49054,13 @@
   #    CXXFLAGS_JDK  - C++ Compiler flags
   #    COMMON_CCXXFLAGS_JDK - common to C and C++
   if test "x$TOOLCHAIN_TYPE" = xgcc; then
+    JVM_CFLAGS="$JVM_CFLAGS -D_GNU_SOURCE"
+    JVM_CFLAGS="$JVM_CFLAGS -D_REENTRANT"
+    JVM_CFLAGS="$JVM_CFLAGS -fcheck-new"
     if test "x$OPENJDK_TARGET_CPU" = xx86; then
       # Force compatibility with i586 on 32 bit intel platforms.
       COMMON_CCXXFLAGS="${COMMON_CCXXFLAGS} -march=i586"
+      JVM_CFLAGS="$JVM_CFLAGS -march=i586"
     fi
     COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS $COMMON_CCXXFLAGS_JDK -Wall -Wextra -Wno-unused -Wno-unused-parameter -Wformat=2 \
         -pipe -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE"
@@ -49225,11 +49697,19 @@
 
 
   elif test "x$TOOLCHAIN_TYPE" = xclang; then
+    JVM_CFLAGS="$JVM_CFLAGS -D_GNU_SOURCE"
+
+    # Restrict the debug information created by Clang to avoid
+    # too big object files and speed the build up a little bit
+    # (see http://llvm.org/bugs/show_bug.cgi?id=7554)
+    JVM_CFLAGS="$JVM_CFLAGS -flimit-debug-info"
     if test "x$OPENJDK_TARGET_OS" = xlinux; then
       if test "x$OPENJDK_TARGET_CPU" = xx86; then
         # Force compatibility with i586 on 32 bit intel platforms.
         COMMON_CCXXFLAGS="${COMMON_CCXXFLAGS} -march=i586"
-      fi
+        JVM_CFLAGS="$JVM_CFLAGS -march=i586"
+      fi
+      JVM_CFLAGS="$JVM_CFLAGS -Wno-sometimes-uninitialized"
       COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS $COMMON_CCXXFLAGS_JDK -Wall -Wextra -Wno-unused -Wno-unused-parameter -Wformat=2 \
           -pipe -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE"
       case $OPENJDK_TARGET_CPU_ARCH in
@@ -49244,6 +49724,7 @@
       esac
     fi
   elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+    JVM_CFLAGS="$JVM_CFLAGS -DSPARC_WORKS"
     COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS $COMMON_CCXXFLAGS_JDK -DTRACING -DMACRO_MEMSYS_OPS -DBREAKPTS"
     if test "x$OPENJDK_TARGET_CPU_ARCH" = xx86; then
       COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -DcpuIntel -Di586 -D$OPENJDK_TARGET_CPU_LEGACY_LIB"
@@ -49252,6 +49733,7 @@
     CFLAGS_JDK="$CFLAGS_JDK -xc99=%none -xCC -errshort=tags -Xa -v -mt -W0,-noglobal"
     CXXFLAGS_JDK="$CXXFLAGS_JDK -errtags=yes +w -mt -features=no%except -DCC_NOEX -norunpath -xnolib"
   elif test "x$TOOLCHAIN_TYPE" = xxlc; then
+    JVM_CFLAGS="$JVM_CFLAGS -D_REENTRANT -D__STDC_FORMAT_MACROS"
     CFLAGS_JDK="$CFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC"
     CXXFLAGS_JDK="$CXXFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC"
   elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
@@ -49272,6 +49754,7 @@
     if test "x$TOOLCHAIN_VERSION" = "x2010"; then
       STATIC_CPPLIB_FLAGS="-D_STATIC_CPPLIB -D_DISABLE_DEPRECATE_STATIC_CPPLIB"
       COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK $STATIC_CPPLIB_FLAGS"
+      JVM_CFLAGS="$JVM_CFLAGS $STATIC_CPPLIB_FLAGS"
     fi
   fi
 
@@ -49321,12 +49804,9 @@
   COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D$OPENJDK_TARGET_OS_UPPERCASE"
 
   # Setup target CPU
-  OPENJDK_TARGET_CCXXFLAGS_JDK="$OPENJDK_TARGET_CCXXFLAGS_JDK \
-      $ADD_LP64 \
+  COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK \
+      $OPENJDK_TARGET_ADD_LP64 \
       -DARCH='\"$OPENJDK_TARGET_CPU_LEGACY\"' -D$OPENJDK_TARGET_CPU_LEGACY"
-  OPENJDK_BUILD_CCXXFLAGS_JDK="$OPENJDK_BUILD_CCXXFLAGS_JDK \
-      $OPENJDK_BUILD_ADD_LP64 \
-      -DARCH='\"$OPENJDK_BUILD_CPU_LEGACY\"' -D$OPENJDK_BUILD_CPU_LEGACY"
 
   # Setup debug/release defines
   if test "x$DEBUG_LEVEL" = xrelease; then
@@ -49339,10 +49819,172 @@
   fi
 
   # Set some additional per-OS defines.
-  if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+  if test "x$OPENJDK_TARGET_OS" = xlinux; then
+    JVM_CFLAGS="$JVM_CFLAGS -DLINUX"
+    JVM_CFLAGS="$JVM_CFLAGS -pipe -fPIC -fno-rtti -fno-exceptions \
+        -fvisibility=hidden -fno-strict-aliasing -fno-omit-frame-pointer"
+  elif test "x$OPENJDK_TARGET_OS" = xsolaris; then
+    JVM_CFLAGS="$JVM_CFLAGS -DSOLARIS"
+    JVM_CFLAGS="$JVM_CFLAGS -template=no%extdef -features=no%split_init \
+        -D_Crun_inline_placement -library=%none -KPIC -mt -xwe -features=no%except"
+  elif test "x$OPENJDK_TARGET_OS" = xmacosx; then
     COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT"
+    JVM_CFLAGS="$JVM_CFLAGS -D_ALLBSD_SOURCE"
+    JVM_CFLAGS="$JVM_CFLAGS -D_DARWIN_C_SOURCE -D_XOPEN_SOURCE"
+    JVM_CFLAGS="$JVM_CFLAGS -fno-rtti -fno-exceptions -fvisibility=hidden \
+        -mno-omit-leaf-frame-pointer -mstack-alignment=16 -pipe -fno-strict-aliasing \
+        -DMAC_OS_X_VERSION_MAX_ALLOWED=1070 -mmacosx-version-min=10.7.0 \
+        -fno-omit-frame-pointer"
+  elif test "x$OPENJDK_TARGET_OS" = xaix; then
+    JVM_CFLAGS="$JVM_CFLAGS -DAIX"
+    # We may need '-qminimaltoc' or '-qpic=large -bbigtoc' if the TOC overflows.
+    JVM_CFLAGS="$JVM_CFLAGS -qtune=balanced -qhot=level=1 -qinline \
+        -qinlglue -qalias=noansi -qstrict -qtls=default -qlanglvl=c99vla \
+        -qlanglvl=noredefmac -qnortti -qnoeh -qignerrno"
   elif test "x$OPENJDK_TARGET_OS" = xbsd; then
     COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE"
+  elif test "x$OPENJDK_TARGET_OS" = xwindows; then
+    JVM_CFLAGS="$JVM_CFLAGS -D_WINDOWS -DWIN32 -D_JNI_IMPLEMENTATION_"
+    JVM_CFLAGS="$JVM_CFLAGS -nologo -W3 -MD -MP"
+  fi
+
+  # Set some additional per-CPU defines.
+  if test "x$OPENJDK_TARGET_OS-$OPENJDK_TARGET_CPU" = xwindows-x86; then
+    JVM_CFLAGS="$JVM_CFLAGS -arch:IA32"
+  elif test "x$OPENJDK_TARGET_CPU" = xsparcv9; then
+    JVM_CFLAGS="$JVM_CFLAGS -xarch=sparc"
+  elif test "x$OPENJDK_TARGET_CPU" = xppc64; then
+    if test "x$OPENJDK_TARGET_OS" = xlinux; then
+      JVM_CFLAGS="$JVM_CFLAGS -minsert-sched-nops=regroup_exact -mno-multiple -mno-string"
+      # fixes `relocation truncated to fit' error for gcc 4.1.
+      JVM_CFLAGS="$JVM_CFLAGS -mminimal-toc"
+      # Use ppc64 instructions, but schedule for power5
+      JVM_CFLAGS="$JVM_CFLAGS -mcpu=powerpc64 -mtune=power5"
+    elif test "x$OPENJDK_TARGET_OS" = xaix; then
+      JVM_CFLAGS="$JVM_CFLAGS -qarch=ppc64"
+    fi
+  elif test "x$OPENJDK_TARGET_CPU" = xppc64le; then
+    if test "x$OPENJDK_TARGET_OS" = xlinux; then
+      JVM_CFLAGS="$JVM_CFLAGS -minsert-sched-nops=regroup_exact -mno-multiple -mno-string"
+      # Little endian machine uses ELFv2 ABI.
+      JVM_CFLAGS="$JVM_CFLAGS -DABI_ELFv2"
+      # Use Power8, this is the first CPU to support PPC64 LE with ELFv2 ABI.
+      JVM_CFLAGS="$JVM_CFLAGS -mcpu=power7 -mtune=power8"
+    fi
+  fi
+
+  if test "x$OPENJDK_TARGET_CPU_ENDIAN" = xlittle; then
+    JVM_CFLAGS="$JVM_CFLAGS -DVM_LITTLE_ENDIAN"
+  fi
+
+  if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+    if test "x$OPENJDK_TARGET_OS" != xsolaris && test "x$OPENJDK_TARGET_OS" != xaix; then
+      # Solaris does not have _LP64=1 in the old build.
+      # xlc on AIX defines _LP64=1 by default and issues a warning if we redefine it.
+      JVM_CFLAGS="$JVM_CFLAGS -D_LP64=1"
+    fi
+  fi
+
+  # Set JVM_CFLAGS warning handling
+  if test "x$OPENJDK_TARGET_OS" = xlinux; then
+    JVM_CFLAGS="$JVM_CFLAGS -Wpointer-arith -Wsign-compare -Wunused-function \
+        -Wunused-value -Woverloaded-virtual"
+
+    if test "x$TOOLCHAIN_TYPE" = xgcc; then
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    # Execute function body
+
+  # Need to assign to a variable since m4 is blocked from modifying parts in [].
+  REFERENCE_VERSION=4.8
+
+  if  [[ "$REFERENCE_VERSION" =~ (.*\.){3} ]] ; then
+    as_fn_error $? "Internal error: Cannot compare to 4.8, only three parts (X.Y.Z) is supported" "$LINENO" 5
+  fi
+
+  if  [[ "$REFERENCE_VERSION" =~ [0-9]{6} ]] ; then
+    as_fn_error $? "Internal error: Cannot compare to 4.8, only parts < 99999 is supported" "$LINENO" 5
+  fi
+
+  # Version comparison method inspired by http://stackoverflow.com/a/24067243
+  COMPARABLE_REFERENCE_VERSION=`$AWK -F. '{ printf("%05d%05d%05d\n", $1, $2, $3) }' <<< "$REFERENCE_VERSION"`
+
+  if test $COMPARABLE_ACTUAL_VERSION -ge $COMPARABLE_REFERENCE_VERSION ; then
+    :
+
+            # These flags either do not work or give spurious warnings prior to gcc 4.8.
+            JVM_CFLAGS="$JVM_CFLAGS -Wno-format-zero-length -Wtype-limits -Wuninitialized"
+
+
+  else
+    :
+
+  fi
+
+
+
+
+
+
+
+
+
+
+
+
+    fi
+    if !   [[ " $JVM_VARIANTS " =~ " zero " ]]   && !   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
+      # Non-zero builds have stricter warnings
+      JVM_CFLAGS="$JVM_CFLAGS -Wreturn-type -Wundef -Wformat=2"
+    else
+      if test "x$TOOLCHAIN_TYPE" = xclang; then
+        # Some versions of llvm do not like -Wundef
+        JVM_CFLAGS="$JVM_CFLAGS -Wno-undef"
+      fi
+    fi
+  elif test "x$OPENJDK_TARGET_OS" = xmacosx; then
+    JVM_CFLAGS="$JVM_CFLAGS -Wno-deprecated -Wpointer-arith \
+        -Wsign-compare -Wundef -Wunused-function -Wformat=2"
   fi
 
   # Additional macosx handling
@@ -49370,43 +50012,14 @@
       -I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS_TYPE/native/libjava"
 
   # The shared libraries are compiled using the picflag.
-  CFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
+  CFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK \
       $CFLAGS_JDK $EXTRA_CFLAGS_JDK $PICFLAG $CFLAGS_JDKLIB_EXTRA"
-  CXXFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
+  CXXFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK \
       $CXXFLAGS_JDK $EXTRA_CXXFLAGS_JDK $PICFLAG $CXXFLAGS_JDKLIB_EXTRA"
 
   # Executable flags
-  CFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
-      $CFLAGS_JDK $EXTRA_CFLAGS_JDK"
-  CXXFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_TARGET_CCXXFLAGS_JDK \
-      $CXXFLAGS_JDK $EXTRA_CXXFLAGS_JDK"
-
-  # The corresponding flags for building for the build platform. This is still an
-  # approximation, we only need something that runs on this machine when cross
-  # compiling the product.
-  OPENJDK_BUILD_CFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK \
-      $PICFLAG $CFLAGS_JDKLIB_EXTRA"
-  OPENJDK_BUILD_CXXFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK \
-      $PICFLAG $CXXFLAGS_JDKLIB_EXTRA"
-  OPENJDK_BUILD_CFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK"
-  OPENJDK_BUILD_CXXFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CCXXFLAGS_JDK"
-
-
-
-
-
-
-
-
-
-
-  # Flags for compiling test libraries
-  CFLAGS_TESTLIB="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK $PICFLAG $CFLAGS_JDKLIB_EXTRA"
-  CXXFLAGS_TESTLIB="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK $PICFLAG $CXXFLAGS_JDKLIB_EXTRA"
-
-  # Flags for compiling test executables
-  CFLAGS_TESTEXE="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK"
-  CXXFLAGS_TESTEXE="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK"
+  CFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK $EXTRA_CFLAGS_JDK"
+  CXXFLAGS_JDKEXE="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK $EXTRA_CXXFLAGS_JDK"
 
 
 
@@ -49419,9 +50032,21 @@
   if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
     LDFLAGS_MICROSOFT="-nologo -opt:ref"
     LDFLAGS_JDK="$LDFLAGS_JDK $LDFLAGS_MICROSOFT -incremental:no"
+    JVM_LDFLAGS="$JVM_LDFLAGS $LDFLAGS_MICROSOFT -opt:icf,8 -subsystem:windows -base:0x8000000"
     if test "x$OPENJDK_TARGET_CPU_BITS" = "x32"; then
       LDFLAGS_SAFESH="-safeseh"
       LDFLAGS_JDK="$LDFLAGS_JDK $LDFLAGS_SAFESH"
+      JVM_LDFLAGS="$JVM_LDFLAGS $LDFLAGS_SAFESH"
+      # NOTE: Old build added -machine. Probably not needed.
+      JVM_LDFLAGS="$JVM_LDFLAGS -machine:I386"
+    else
+      JVM_LDFLAGS="$JVM_LDFLAGS -machine:AMD64"
+    fi
+  elif test "x$TOOLCHAIN_TYPE" = xclang; then
+      JVM_LDFLAGS="$JVM_LDFLAGS -mno-omit-leaf-frame-pointer -mstack-alignment=16 -stdlib=libstdc++ -fPIC"
+      if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+        # FIXME: We should really generalize SET_SHARED_LIBRARY_ORIGIN instead.
+        JVM_LDFLAGS="$JVM_LDFLAGS -Wl,-rpath,@loader_path/. -Wl,-rpath,@loader_path/.."
     fi
   elif test "x$TOOLCHAIN_TYPE" = xgcc; then
     # If this is a --hash-style=gnu system, use --hash-style=both, why?
@@ -49429,36 +50054,57 @@
     if test -n "$HAS_GNU_HASH"; then
       LDFLAGS_HASH_STYLE="-Wl,--hash-style=both"
       LDFLAGS_JDK="${LDFLAGS_JDK} $LDFLAGS_HASH_STYLE"
+      JVM_LDFLAGS="$JVM_LDFLAGS $LDFLAGS_HASH_STYLE"
+    fi
+      if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+        JVM_LDFLAGS="$JVM_LDFLAGS -Wl,-rpath,@loader_path/. -Wl,-rpath,@loader_path/.."
     fi
     if test "x$OPENJDK_TARGET_OS" = xlinux; then
       # And since we now know that the linker is gnu, then add -z defs, to forbid
       # undefined symbols in object files.
       LDFLAGS_NO_UNDEF_SYM="-Wl,-z,defs"
       LDFLAGS_JDK="${LDFLAGS_JDK} $LDFLAGS_NO_UNDEF_SYM"
+      JVM_LDFLAGS="$JVM_LDFLAGS  $LDFLAGS_NO_UNDEF_SYM"
+      LDFLAGS_NO_EXEC_STACK="-Wl,-z,noexecstack"
+      JVM_LDFLAGS="$JVM_LDFLAGS $LDFLAGS_NO_EXEC_STACK"
+      if test "x$OPENJDK_TARGET_CPU" = xx86; then
+        JVM_LDFLAGS="$JVM_LDFLAGS -march=i586"
+      fi
       case $DEBUG_LEVEL in
         release )
           # tell linker to optimize libraries.
           # Should this be supplied to the OSS linker as well?
           LDFLAGS_DEBUGLEVEL_release="-Wl,-O1"
           LDFLAGS_JDK="${LDFLAGS_JDK} $LDFLAGS_DEBUGLEVEL_release"
+          JVM_LDFLAGS="$JVM_LDFLAGS $LDFLAGS_DEBUGLEVEL_release"
+          if test "x$HAS_LINKER_RELRO" = "xtrue"; then
+            JVM_LDFLAGS="$JVM_LDFLAGS $LINKER_RELRO_FLAG"
+          fi
           ;;
         slowdebug )
+          # Hotspot always let the linker optimize
+          JVM_LDFLAGS="$JVM_LDFLAGS -Wl,-O1"
           if test "x$HAS_LINKER_NOW" = "xtrue"; then
             # do relocations at load
             LDFLAGS_JDK="$LDFLAGS_JDK $LINKER_NOW_FLAG"
             LDFLAGS_CXX_JDK="$LDFLAGS_CXX_JDK $LINKER_NOW_FLAG"
+            JVM_LDFLAGS="$JVM_LDFLAGS $LINKER_NOW_FLAG"
           fi
           if test "x$HAS_LINKER_RELRO" = "xtrue"; then
             # mark relocations read only
             LDFLAGS_JDK="$LDFLAGS_JDK $LINKER_RELRO_FLAG"
             LDFLAGS_CXX_JDK="$LDFLAGS_CXX_JDK $LINKER_RELRO_FLAG"
+            JVM_LDFLAGS="$JVM_LDFLAGS $LINKER_RELRO_FLAG"
           fi
           ;;
         fastdebug )
+          # Hotspot always let the linker optimize
+          JVM_LDFLAGS="$JVM_LDFLAGS -Wl,-O1"
           if test "x$HAS_LINKER_RELRO" = "xtrue"; then
             # mark relocations read only
             LDFLAGS_JDK="$LDFLAGS_JDK $LINKER_RELRO_FLAG"
             LDFLAGS_CXX_JDK="$LDFLAGS_CXX_JDK $LINKER_RELRO_FLAG"
+            JVM_LDFLAGS="$JVM_LDFLAGS $LINKER_RELRO_FLAG"
           fi
           ;;
         * )
@@ -49471,9 +50117,14 @@
     LDFLAGS_JDK="$LDFLAGS_JDK $LDFLAGS_SOLSTUDIO -xildoff -ztext"
     LDFLAGS_CXX_SOLSTUDIO="-norunpath"
     LDFLAGS_CXX_JDK="$LDFLAGS_CXX_JDK $LDFLAGS_CXX_SOLSTUDIO -xnolib"
+    JVM_LDFLAGS="$JVM_LDFLAGS $LDFLAGS_SOLSTUDIO -library=%none -mt $LDFLAGS_CXX_SOLSTUDIO -z noversion"
+    if test "x$OPENJDK_TARGET_CPU_ARCH" = "xsparc"; then
+      JVM_LDFLAGS="$JVM_LDFLAGS -xarch=sparc"
+    fi
   elif test "x$TOOLCHAIN_TYPE" = xxlc; then
     LDFLAGS_XLC="-b64 -brtl -bnolibpath -bexpall -bernotok"
     LDFLAGS_JDK="${LDFLAGS_JDK} $LDFLAGS_XLC"
+    JVM_LDFLAGS="$JVM_LDFLAGS $LDFLAGS_XLC"
   fi
 
   # Customize LDFLAGS for executables
@@ -49491,7 +50142,6 @@
     LDFLAGS_JDKEXE="$LDFLAGS_JDKEXE -Wl,--allow-shlib-undefined"
   fi
 
-  OPENJDK_BUILD_LDFLAGS_JDKEXE="${LDFLAGS_JDKEXE}"
   LDFLAGS_JDKEXE="${LDFLAGS_JDKEXE} ${EXTRA_LDFLAGS_JDK}"
 
   # Customize LDFLAGS for libs
@@ -49506,18 +50156,24 @@
     LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} \
         -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)"
 
+    if test "xTARGET" = "xTARGET"; then
     # On some platforms (mac) the linker warns about non existing -L dirs.
     # Add server first if available. Linking aginst client does not always produce the same results.
-    # Only add client dir if client is being built. Add minimal (note not minimal1) if only building minimal1.
+      # Only add client/minimal dir if client/minimal is being built.
     # Default to server for other variants.
-    if test "x$JVM_VARIANT_SERVER" = xtrue; then
-      LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
-    elif test "x$JVM_VARIANT_CLIENT" = xtrue; then
-      LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/client"
-    elif test "x$JVM_VARIANT_MINIMAL1" = xtrue; then
-      LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/minimal"
-    else
-      LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
+      if   [[ " $JVM_VARIANTS " =~ " server " ]]  ; then
+        LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
+      elif   [[ " $JVM_VARIANTS " =~ " client " ]]  ; then
+        LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/client"
+      elif   [[ " $JVM_VARIANTS " =~ " minimal " ]]  ; then
+        LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/minimal"
+    else
+        LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
+    fi
+    elif test "xTARGET" = "xBUILD"; then
+      # When building a buildjdk, it's always only the server variant
+      LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} \
+          -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
     fi
 
     JDKLIB_LIBS="-ljava -ljvm"
@@ -49525,17 +50181,842 @@
       JDKLIB_LIBS="$JDKLIB_LIBS -lc"
     fi
 
-    # When building a buildjdk, it's always only the server variant
+  fi
+
+  # Set JVM_LIBS (per os)
+  if test "x$OPENJDK_TARGET_OS" = xlinux; then
+    JVM_LIBS="$JVM_LIBS -lm -ldl -lpthread"
+  elif test "x$OPENJDK_TARGET_OS" = xsolaris; then
+    # FIXME: This hard-coded path is not really proper.
+    if test "x$OPENJDK_TARGET_CPU" = xx86_64; then
+      SOLARIS_LIBM_LIBS="/usr/lib/amd64/libm.so.1"
+    elif test "x$OPENJDK_TARGET_CPU" = xsparcv9; then
+      SOLARIS_LIBM_LIBS="/usr/lib/sparcv9/libm.so.1"
+    fi
+    JVM_LIBS="$JVM_LIBS -lsocket -lsched -ldl $SOLARIS_LIBM_LIBS -lCrun \
+        -lthread -ldoor -lc -ldemangle -lnsl -lkstat -lrt"
+  elif test "x$OPENJDK_TARGET_OS" = xmacosx; then
+    JVM_LIBS="$JVM_LIBS -lm"
+  elif test "x$OPENJDK_TARGET_OS" = xaix; then
+    JVM_LIBS="$JVM_LIBS -Wl,-lC_r -lm -ldl -lpthread"
+  elif test "x$OPENJDK_TARGET_OS" = xbsd; then
+    JVM_LIBS="$JVM_LIBS -lm"
+  elif test "x$OPENJDK_TARGET_OS" = xwindows; then
+    JVM_LIBS="$JVM_LIBS kernel32.lib user32.lib gdi32.lib winspool.lib \
+        comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib \
+        wsock32.lib winmm.lib version.lib psapi.lib"
+    fi
+
+  # Set JVM_ASFLAGS
+  if test "x$OPENJDK_TARGET_OS" = xlinux; then
+    if test "x$OPENJDK_TARGET_CPU" = xx86; then
+      JVM_ASFLAGS="$JVM_ASFLAGS -march=i586"
+    fi
+  elif test "x$OPENJDK_TARGET_OS" = xmacosx; then
+    JVM_ASFLAGS="$JVM_ASFLAGS -x assembler-with-cpp -mno-omit-leaf-frame-pointer -mstack-alignment=16"
+  fi
+
+  LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} ${EXTRA_LDFLAGS_JDK}"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  # Special extras...
+  if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+    if test "x$OPENJDK_BUILD_CPU_ARCH" = "xsparc"; then
+      OPENJDK_BUILD_CFLAGS_JDKLIB_EXTRA="${OPENJDK_BUILD_CFLAGS_JDKLIB_EXTRA} -xregs=no%appl"
+      OPENJDK_BUILD_CXXFLAGS_JDKLIB_EXTRA="${OPENJDK_BUILD_CXXFLAGS_JDKLIB_EXTRA} -xregs=no%appl"
+    fi
+    OPENJDK_BUILD_CFLAGS_JDKLIB_EXTRA="${OPENJDK_BUILD_CFLAGS_JDKLIB_EXTRA} -errtags=yes -errfmt"
+    OPENJDK_BUILD_CXXFLAGS_JDKLIB_EXTRA="${OPENJDK_BUILD_CXXFLAGS_JDKLIB_EXTRA} -errtags=yes -errfmt"
+  elif test "x$TOOLCHAIN_TYPE" = xxlc; then
+    OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
+    OPENJDK_BUILD_CXXFLAGS_JDK="${OPENJDK_BUILD_CXXFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
+  elif test "x$TOOLCHAIN_TYPE" = xgcc; then
+    OPENJDK_BUILD_CXXSTD_CXXFLAG="-std=gnu++98"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    # Execute function body
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the C++ compiler supports \"$OPENJDK_BUILD_CXXSTD_CXXFLAG -Werror\"" >&5
+$as_echo_n "checking if the C++ compiler supports \"$OPENJDK_BUILD_CXXSTD_CXXFLAG -Werror\"... " >&6; }
+  supports=yes
+
+  saved_cxxflags="$CXXFLAGS"
+  CXXFLAGS="$CXXFLAG $OPENJDK_BUILD_CXXSTD_CXXFLAG -Werror"
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int i;
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+  supports=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+  CXXFLAGS="$saved_cxxflags"
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $supports" >&5
+$as_echo "$supports" >&6; }
+  if test "x$supports" = "xyes" ; then
+    :
+
+  else
+    :
+    OPENJDK_BUILD_CXXSTD_CXXFLAG=""
+  fi
+
+
+
+
+
+
+
+
+
+
+
+
+    OPENJDK_BUILD_CXXFLAGS_JDK="${OPENJDK_BUILD_CXXFLAGS_JDK} ${OPENJDK_BUILD_CXXSTD_CXXFLAG}"
+
+  fi
+  if test "x$OPENJDK_TARGET_OS" = xsolaris; then
+    OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -D__solaris__"
+    OPENJDK_BUILD_CXXFLAGS_JDK="${OPENJDK_BUILD_CXXFLAGS_JDK} -D__solaris__"
+    OPENJDK_BUILD_CFLAGS_JDKLIB_EXTRA='-xstrconst'
+    CFLAGS_JDK="${CFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
+    CXXFLAGS_JDK="${CXXFLAGS_JDK} -qchars=signed -qfullpath -qsaveopt"
+  fi
+
+  if test "x$OPENJDK_TARGET_OS" = xsolaris; then
+    OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -D__solaris__"
+    OPENJDK_BUILD_CXXFLAGS_JDK="${OPENJDK_BUILD_CXXFLAGS_JDK} -D__solaris__"
+    OPENJDK_BUILD_CFLAGS_JDKLIB_EXTRA='-xstrconst'
+  fi
+
+  OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} ${OPENJDK_BUILD_EXTRA_CFLAGS}"
+  OPENJDK_BUILD_CXXFLAGS_JDK="${OPENJDK_BUILD_CXXFLAGS_JDK} ${OPENJDK_BUILD_EXTRA_CXXFLAGS}"
+  OPENJDK_BUILD_LDFLAGS_JDK="${OPENJDK_BUILD_LDFLAGS_JDK} ${OPENJDK_BUILD_EXTRA_LDFLAGS}"
+
+  ###############################################################################
+  #
+  # Now setup the CFLAGS and LDFLAGS for the JDK build.
+  # Later we will also have CFLAGS and LDFLAGS for the hotspot subrepo build.
+  #
+
+  # Setup compiler/platform specific flags into
+  #    OPENJDK_BUILD_CFLAGS_JDK    - C Compiler flags
+  #    OPENJDK_BUILD_CXXFLAGS_JDK  - C++ Compiler flags
+  #    OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK - common to C and C++
+  if test "x$TOOLCHAIN_TYPE" = xgcc; then
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_GNU_SOURCE"
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_REENTRANT"
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -fcheck-new"
+    if test "x$OPENJDK_BUILD_CPU" = xx86; then
+      # Force compatibility with i586 on 32 bit intel platforms.
+      OPENJDK_BUILD_COMMON_CCXXFLAGS="${OPENJDK_BUILD_COMMON_CCXXFLAGS} -march=i586"
+      OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -march=i586"
+    fi
+    OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS $OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -Wall -Wextra -Wno-unused -Wno-unused-parameter -Wformat=2 \
+        -pipe -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE"
+    case $OPENJDK_BUILD_CPU_ARCH in
+      arm )
+        # on arm we don't prevent gcc to omit frame pointer but do prevent strict aliasing
+        OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -fno-strict-aliasing"
+        ;;
+      ppc )
+        # on ppc we don't prevent gcc to omit frame pointer but do prevent strict aliasing
+        OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -fno-strict-aliasing"
+        ;;
+      * )
+        OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer"
+        OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -fno-strict-aliasing"
+        ;;
+    esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    # Execute function body
+
+  # Need to assign to a variable since m4 is blocked from modifying parts in [].
+  REFERENCE_VERSION=6
+
+  if  [[ "$REFERENCE_VERSION" =~ (.*\.){3} ]] ; then
+    as_fn_error $? "Internal error: Cannot compare to 6, only three parts (X.Y.Z) is supported" "$LINENO" 5
+  fi
+
+  if  [[ "$REFERENCE_VERSION" =~ [0-9]{6} ]] ; then
+    as_fn_error $? "Internal error: Cannot compare to 6, only parts < 99999 is supported" "$LINENO" 5
+  fi
+
+  # Version comparison method inspired by http://stackoverflow.com/a/24067243
+  COMPARABLE_REFERENCE_VERSION=`$AWK -F. '{ printf("%05d%05d%05d\n", $1, $2, $3) }' <<< "$REFERENCE_VERSION"`
+
+  if test $COMPARABLE_ACTUAL_VERSION -ge $COMPARABLE_REFERENCE_VERSION ; then
+    :
+
+  else
+    :
+
+  fi
+
+
+
+
+
+
+
+
+
+
+
+
+  elif test "x$TOOLCHAIN_TYPE" = xclang; then
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_GNU_SOURCE"
+
+    # Restrict the debug information created by Clang to avoid
+    # too big object files and speed the build up a little bit
+    # (see http://llvm.org/bugs/show_bug.cgi?id=7554)
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -flimit-debug-info"
+    if test "x$OPENJDK_BUILD_OS" = xlinux; then
+      if test "x$OPENJDK_BUILD_CPU" = xx86; then
+        # Force compatibility with i586 on 32 bit intel platforms.
+        OPENJDK_BUILD_COMMON_CCXXFLAGS="${OPENJDK_BUILD_COMMON_CCXXFLAGS} -march=i586"
+        OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -march=i586"
+      fi
+      OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -Wno-sometimes-uninitialized"
+      OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS $OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -Wall -Wextra -Wno-unused -Wno-unused-parameter -Wformat=2 \
+          -pipe -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE"
+      case $OPENJDK_BUILD_CPU_ARCH in
+        ppc )
+          # on ppc we don't prevent gcc to omit frame pointer but do prevent strict aliasing
+          OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -fno-strict-aliasing"
+          ;;
+        * )
+          OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer"
+          OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -fno-strict-aliasing"
+          ;;
+      esac
+    fi
+  elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -DSPARC_WORKS"
+    OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS $OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -DTRACING -DMACRO_MEMSYS_OPS -DBREAKPTS"
+    if test "x$OPENJDK_BUILD_CPU_ARCH" = xx86; then
+      OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -DcpuIntel -Di586 -D$OPENJDK_BUILD_CPU_LEGACY_LIB"
+    fi
+
+    OPENJDK_BUILD_CFLAGS_JDK="$OPENJDK_BUILD_CFLAGS_JDK -xc99=%none -xCC -errshort=tags -Xa -v -mt -W0,-noglobal"
+    OPENJDK_BUILD_CXXFLAGS_JDK="$OPENJDK_BUILD_CXXFLAGS_JDK -errtags=yes +w -mt -features=no%except -DCC_NOEX -norunpath -xnolib"
+  elif test "x$TOOLCHAIN_TYPE" = xxlc; then
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_REENTRANT -D__STDC_FORMAT_MACROS"
+    OPENJDK_BUILD_CFLAGS_JDK="$OPENJDK_BUILD_CFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC"
+    OPENJDK_BUILD_CXXFLAGS_JDK="$OPENJDK_BUILD_CXXFLAGS_JDK -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -DSTDC"
+  elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+    OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS $OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK \
+        -MD -Zc:wchar_t- -W3 -wd4800 \
+        -DWIN32_LEAN_AND_MEAN \
+        -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE \
+        -D_WINSOCK_DEPRECATED_NO_WARNINGS \
+        -DWIN32 -DIAL"
+    if test "x$OPENJDK_BUILD_CPU" = xx86_64; then
+      OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D_AMD64_ -Damd64"
+    else
+      OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D_X86_ -Dx86"
+    fi
+    # If building with Visual Studio 2010, we can still use _STATIC_CPPLIB to
+    # avoid bundling msvcpNNN.dll. Doesn't work with newer versions of visual
+    # studio.
+    if test "x$TOOLCHAIN_VERSION" = "x2010"; then
+      STATIC_CPPLIB_FLAGS="-D_STATIC_CPPLIB -D_DISABLE_DEPRECATE_STATIC_CPPLIB"
+      OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK $STATIC_CPPLIB_FLAGS"
+      OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS $STATIC_CPPLIB_FLAGS"
+    fi
+  fi
+
+  ###############################################################################
+
+  # Adjust flags according to debug level.
+  case $DEBUG_LEVEL in
+    fastdebug | slowdebug )
+      OPENJDK_BUILD_CFLAGS_JDK="$OPENJDK_BUILD_CFLAGS_JDK $CFLAGS_DEBUG_SYMBOLS $CFLAGS_DEBUG_OPTIONS"
+      OPENJDK_BUILD_CXXFLAGS_JDK="$OPENJDK_BUILD_CXXFLAGS_JDK $CXXFLAGS_DEBUG_SYMBOLS $CXXFLAGS_DEBUG_OPTIONS"
+      JAVAC_FLAGS="$JAVAC_FLAGS -g"
+      ;;
+    release )
+      ;;
+    * )
+      as_fn_error $? "Unrecognized \$DEBUG_LEVEL: $DEBUG_LEVEL" "$LINENO" 5
+      ;;
+  esac
+
+  # Set some common defines. These works for all compilers, but assume
+  # -D is universally accepted.
+
+  # Setup endianness
+  if test "x$OPENJDK_BUILD_CPU_ENDIAN" = xlittle; then
+    # The macro _LITTLE_ENDIAN needs to be defined the same to avoid the
+    #   Sun C compiler warning message: warning: macro redefined: _LITTLE_ENDIAN
+    #   (The Solaris X86 system defines this in file /usr/include/sys/isa_defs.h).
+    #   Note: -Dmacro         is the same as    #define macro 1
+    #         -Dmacro=        is the same as    #define macro
+    if test "x$OPENJDK_BUILD_OS" = xsolaris; then
+      OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D_LITTLE_ENDIAN="
+    else
+      OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D_LITTLE_ENDIAN"
+    fi
+  else
+    # Same goes for _BIG_ENDIAN. Do we really need to set *ENDIAN on Solaris if they
+    # are defined in the system?
+    if test "x$OPENJDK_BUILD_OS" = xsolaris; then
+      OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D_BIG_ENDIAN="
+    else
+      OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D_BIG_ENDIAN"
+    fi
+  fi
+
+  # Setup target OS define. Use OS target name but in upper case.
+  OPENJDK_BUILD_OS_UPPERCASE=`$ECHO $OPENJDK_BUILD_OS | $TR 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D$OPENJDK_BUILD_OS_UPPERCASE"
+
+  # Setup target CPU
+  OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK \
+      $OPENJDK_BUILD_ADD_LP64 \
+      -DARCH='\"$OPENJDK_BUILD_CPU_LEGACY\"' -D$OPENJDK_BUILD_CPU_LEGACY"
+
+  # Setup debug/release defines
+  if test "x$DEBUG_LEVEL" = xrelease; then
+    OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -DNDEBUG"
+    if test "x$OPENJDK_BUILD_OS" = xsolaris; then
+      OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -DTRIMMED"
+    fi
+  else
+    OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -DDEBUG"
+  fi
+
+  # Set some additional per-OS defines.
+  if test "x$OPENJDK_BUILD_OS" = xlinux; then
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -DLINUX"
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -pipe -fPIC -fno-rtti -fno-exceptions \
+        -fvisibility=hidden -fno-strict-aliasing -fno-omit-frame-pointer"
+  elif test "x$OPENJDK_BUILD_OS" = xsolaris; then
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -DSOLARIS"
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -template=no%extdef -features=no%split_init \
+        -D_Crun_inline_placement -library=%none -KPIC -mt -xwe -features=no%except"
+  elif test "x$OPENJDK_BUILD_OS" = xmacosx; then
+    OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT"
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_ALLBSD_SOURCE"
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_DARWIN_C_SOURCE -D_XOPEN_SOURCE"
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -fno-rtti -fno-exceptions -fvisibility=hidden \
+        -mno-omit-leaf-frame-pointer -mstack-alignment=16 -pipe -fno-strict-aliasing \
+        -DMAC_OS_X_VERSION_MAX_ALLOWED=1070 -mmacosx-version-min=10.7.0 \
+        -fno-omit-frame-pointer"
+  elif test "x$OPENJDK_BUILD_OS" = xaix; then
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -DAIX"
+    # We may need '-qminimaltoc' or '-qpic=large -bbigtoc' if the TOC overflows.
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -qtune=balanced -qhot=level=1 -qinline \
+        -qinlglue -qalias=noansi -qstrict -qtls=default -qlanglvl=c99vla \
+        -qlanglvl=noredefmac -qnortti -qnoeh -qignerrno"
+  elif test "x$OPENJDK_BUILD_OS" = xbsd; then
+    OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE"
+  elif test "x$OPENJDK_BUILD_OS" = xwindows; then
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_WINDOWS -DWIN32 -D_JNI_IMPLEMENTATION_"
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -nologo -W3 -MD -MP"
+  fi
+
+  # Set some additional per-CPU defines.
+  if test "x$OPENJDK_BUILD_OS-$OPENJDK_BUILD_CPU" = xwindows-x86; then
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -arch:IA32"
+  elif test "x$OPENJDK_BUILD_CPU" = xsparcv9; then
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -xarch=sparc"
+  elif test "x$OPENJDK_BUILD_CPU" = xppc64; then
+    if test "x$OPENJDK_BUILD_OS" = xlinux; then
+      OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -minsert-sched-nops=regroup_exact -mno-multiple -mno-string"
+      # fixes `relocation truncated to fit' error for gcc 4.1.
+      OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -mminimal-toc"
+      # Use ppc64 instructions, but schedule for power5
+      OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -mcpu=powerpc64 -mtune=power5"
+    elif test "x$OPENJDK_BUILD_OS" = xaix; then
+      OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -qarch=ppc64"
+    fi
+  elif test "x$OPENJDK_BUILD_CPU" = xppc64le; then
+    if test "x$OPENJDK_BUILD_OS" = xlinux; then
+      OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -minsert-sched-nops=regroup_exact -mno-multiple -mno-string"
+      # Little endian machine uses ELFv2 ABI.
+      OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -DABI_ELFv2"
+      # Use Power8, this is the first CPU to support PPC64 LE with ELFv2 ABI.
+      OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -mcpu=power7 -mtune=power8"
+    fi
+  fi
+
+  if test "x$OPENJDK_BUILD_CPU_ENDIAN" = xlittle; then
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -DVM_LITTLE_ENDIAN"
+  fi
+
+  if test "x$OPENJDK_BUILD_CPU_BITS" = x64; then
+    if test "x$OPENJDK_BUILD_OS" != xsolaris && test "x$OPENJDK_BUILD_OS" != xaix; then
+      # Solaris does not have _LP64=1 in the old build.
+      # xlc on AIX defines _LP64=1 by default and issues a warning if we redefine it.
+      OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_LP64=1"
+    fi
+  fi
+
+  # Set OPENJDK_BUILD_JVM_CFLAGS warning handling
+  if test "x$OPENJDK_BUILD_OS" = xlinux; then
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -Wpointer-arith -Wsign-compare -Wunused-function \
+        -Wunused-value -Woverloaded-virtual"
+
+    if test "x$TOOLCHAIN_TYPE" = xgcc; then
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    # Execute function body
+
+  # Need to assign to a variable since m4 is blocked from modifying parts in [].
+  REFERENCE_VERSION=4.8
+
+  if  [[ "$REFERENCE_VERSION" =~ (.*\.){3} ]] ; then
+    as_fn_error $? "Internal error: Cannot compare to 4.8, only three parts (X.Y.Z) is supported" "$LINENO" 5
+  fi
+
+  if  [[ "$REFERENCE_VERSION" =~ [0-9]{6} ]] ; then
+    as_fn_error $? "Internal error: Cannot compare to 4.8, only parts < 99999 is supported" "$LINENO" 5
+  fi
+
+  # Version comparison method inspired by http://stackoverflow.com/a/24067243
+  COMPARABLE_REFERENCE_VERSION=`$AWK -F. '{ printf("%05d%05d%05d\n", $1, $2, $3) }' <<< "$REFERENCE_VERSION"`
+
+  if test $COMPARABLE_ACTUAL_VERSION -ge $COMPARABLE_REFERENCE_VERSION ; then
+    :
+
+            # These flags either do not work or give spurious warnings prior to gcc 4.8.
+            OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -Wno-format-zero-length -Wtype-limits -Wuninitialized"
+
+
+  else
+    :
+
+  fi
+
+
+
+
+
+
+
+
+
+
+
+
+    fi
+    if !   [[ " $JVM_VARIANTS " =~ " zero " ]]   && !   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
+      # Non-zero builds have stricter warnings
+      OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -Wreturn-type -Wundef -Wformat=2"
+    else
+      if test "x$TOOLCHAIN_TYPE" = xclang; then
+        # Some versions of llvm do not like -Wundef
+        OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -Wno-undef"
+      fi
+    fi
+  elif test "x$OPENJDK_BUILD_OS" = xmacosx; then
+    OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -Wno-deprecated -Wpointer-arith \
+        -Wsign-compare -Wundef -Wunused-function -Wformat=2"
+  fi
+
+  # Additional macosx handling
+  if test "x$OPENJDK_BUILD_OS" = xmacosx; then
+    # Setting these parameters makes it an error to link to macosx APIs that are
+    # newer than the given OS version and makes the linked binaries compatible
+    # even if built on a newer version of the OS.
+    # The expected format is X.Y.Z
+    MACOSX_VERSION_MIN=10.7.0
+
+
+    # The macro takes the version with no dots, ex: 1070
+    # Let the flags variables get resolved in make for easier override on make
+    # command line.
+    OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -DMAC_OS_X_VERSION_MAX_ALLOWED=\$(subst .,,\$(MACOSX_VERSION_MIN)) -mmacosx-version-min=\$(MACOSX_VERSION_MIN)"
+    OPENJDK_BUILD_LDFLAGS_JDK="$OPENJDK_BUILD_LDFLAGS_JDK -mmacosx-version-min=\$(MACOSX_VERSION_MIN)"
+  fi
+
+  # Setup some hard coded includes
+  OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK \
+      -I${JDK_TOPDIR}/src/java.base/share/native/include \
+      -I${JDK_TOPDIR}/src/java.base/$OPENJDK_BUILD_OS/native/include \
+      -I${JDK_TOPDIR}/src/java.base/$OPENJDK_BUILD_OS_TYPE/native/include \
+      -I${JDK_TOPDIR}/src/java.base/share/native/libjava \
+      -I${JDK_TOPDIR}/src/java.base/$OPENJDK_BUILD_OS_TYPE/native/libjava"
+
+  # The shared libraries are compiled using the picflag.
+  OPENJDK_BUILD_CFLAGS_JDKLIB="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK \
+      $OPENJDK_BUILD_CFLAGS_JDK $OPENJDK_BUILD_EXTRA_CFLAGS_JDK $PICFLAG $OPENJDK_BUILD_CFLAGS_JDKLIB_EXTRA"
+  OPENJDK_BUILD_CXXFLAGS_JDKLIB="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK \
+      $OPENJDK_BUILD_CXXFLAGS_JDK $OPENJDK_BUILD_EXTRA_CXXFLAGS_JDK $PICFLAG $OPENJDK_BUILD_CXXFLAGS_JDKLIB_EXTRA"
+
+  # Executable flags
+  OPENJDK_BUILD_CFLAGS_JDKEXE="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CFLAGS_JDK $OPENJDK_BUILD_EXTRA_CFLAGS_JDK"
+  OPENJDK_BUILD_CXXFLAGS_JDKEXE="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK $OPENJDK_BUILD_CXXFLAGS_JDK $OPENJDK_BUILD_EXTRA_CXXFLAGS_JDK"
+
+
+
+
+
+
+  # Setup LDFLAGS et al.
+  #
+
+  if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+    LDFLAGS_MICROSOFT="-nologo -opt:ref"
+    OPENJDK_BUILD_LDFLAGS_JDK="$OPENJDK_BUILD_LDFLAGS_JDK $LDFLAGS_MICROSOFT -incremental:no"
+    OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LDFLAGS_MICROSOFT -opt:icf,8 -subsystem:windows -base:0x8000000"
+    if test "x$OPENJDK_BUILD_CPU_BITS" = "x32"; then
+      LDFLAGS_SAFESH="-safeseh"
+      OPENJDK_BUILD_LDFLAGS_JDK="$OPENJDK_BUILD_LDFLAGS_JDK $LDFLAGS_SAFESH"
+      OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LDFLAGS_SAFESH"
+      # NOTE: Old build added -machine. Probably not needed.
+      OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -machine:I386"
+    else
+      OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -machine:AMD64"
+    fi
+  elif test "x$TOOLCHAIN_TYPE" = xclang; then
+      OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -mno-omit-leaf-frame-pointer -mstack-alignment=16 -stdlib=libstdc++ -fPIC"
+      if test "x$OPENJDK_BUILD_OS" = xmacosx; then
+        # FIXME: We should really generalize SET_SHARED_LIBRARY_ORIGIN instead.
+        OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -Wl,-rpath,@loader_path/. -Wl,-rpath,@loader_path/.."
+    fi
+  elif test "x$TOOLCHAIN_TYPE" = xgcc; then
+    # If this is a --hash-style=gnu system, use --hash-style=both, why?
+    # We have previously set HAS_GNU_HASH if this is the case
+    if test -n "$HAS_GNU_HASH"; then
+      OPENJDK_BUILD_LDFLAGS_HASH_STYLE="-Wl,--hash-style=both"
+      OPENJDK_BUILD_LDFLAGS_JDK="${OPENJDK_BUILD_LDFLAGS_JDK} $OPENJDK_BUILD_LDFLAGS_HASH_STYLE"
+      OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $OPENJDK_BUILD_LDFLAGS_HASH_STYLE"
+    fi
+      if test "x$OPENJDK_BUILD_OS" = xmacosx; then
+        OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -Wl,-rpath,@loader_path/. -Wl,-rpath,@loader_path/.."
+    fi
+    if test "x$OPENJDK_BUILD_OS" = xlinux; then
+      # And since we now know that the linker is gnu, then add -z defs, to forbid
+      # undefined symbols in object files.
+      LDFLAGS_NO_UNDEF_SYM="-Wl,-z,defs"
+      OPENJDK_BUILD_LDFLAGS_JDK="${OPENJDK_BUILD_LDFLAGS_JDK} $LDFLAGS_NO_UNDEF_SYM"
+      OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS  $LDFLAGS_NO_UNDEF_SYM"
+      LDFLAGS_NO_EXEC_STACK="-Wl,-z,noexecstack"
+      OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LDFLAGS_NO_EXEC_STACK"
+      if test "x$OPENJDK_BUILD_CPU" = xx86; then
+        OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -march=i586"
+      fi
+      case $DEBUG_LEVEL in
+        release )
+          # tell linker to optimize libraries.
+          # Should this be supplied to the OSS linker as well?
+          LDFLAGS_DEBUGLEVEL_release="-Wl,-O1"
+          OPENJDK_BUILD_LDFLAGS_JDK="${OPENJDK_BUILD_LDFLAGS_JDK} $LDFLAGS_DEBUGLEVEL_release"
+          OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LDFLAGS_DEBUGLEVEL_release"
+          if test "x$HAS_LINKER_RELRO" = "xtrue"; then
+            OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LINKER_RELRO_FLAG"
+          fi
+          ;;
+        slowdebug )
+          # Hotspot always let the linker optimize
+          OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -Wl,-O1"
+          if test "x$HAS_LINKER_NOW" = "xtrue"; then
+            # do relocations at load
+            OPENJDK_BUILD_LDFLAGS_JDK="$OPENJDK_BUILD_LDFLAGS_JDK $LINKER_NOW_FLAG"
+            OPENJDK_BUILD_LDFLAGS_CXX_JDK="$OPENJDK_BUILD_LDFLAGS_CXX_JDK $LINKER_NOW_FLAG"
+            OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LINKER_NOW_FLAG"
+          fi
+          if test "x$HAS_LINKER_RELRO" = "xtrue"; then
+            # mark relocations read only
+            OPENJDK_BUILD_LDFLAGS_JDK="$OPENJDK_BUILD_LDFLAGS_JDK $LINKER_RELRO_FLAG"
+            OPENJDK_BUILD_LDFLAGS_CXX_JDK="$OPENJDK_BUILD_LDFLAGS_CXX_JDK $LINKER_RELRO_FLAG"
+            OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LINKER_RELRO_FLAG"
+          fi
+          ;;
+        fastdebug )
+          # Hotspot always let the linker optimize
+          OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -Wl,-O1"
+          if test "x$HAS_LINKER_RELRO" = "xtrue"; then
+            # mark relocations read only
+            OPENJDK_BUILD_LDFLAGS_JDK="$OPENJDK_BUILD_LDFLAGS_JDK $LINKER_RELRO_FLAG"
+            OPENJDK_BUILD_LDFLAGS_CXX_JDK="$OPENJDK_BUILD_LDFLAGS_CXX_JDK $LINKER_RELRO_FLAG"
+            OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LINKER_RELRO_FLAG"
+          fi
+          ;;
+        * )
+          as_fn_error $? "Unrecognized \$DEBUG_LEVEL: $DEBUG_LEVEL" "$LINENO" 5
+          ;;
+        esac
+    fi
+  elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+    LDFLAGS_SOLSTUDIO="-Wl,-z,defs"
+    OPENJDK_BUILD_LDFLAGS_JDK="$OPENJDK_BUILD_LDFLAGS_JDK $LDFLAGS_SOLSTUDIO -xildoff -ztext"
+    LDFLAGS_CXX_SOLSTUDIO="-norunpath"
+    OPENJDK_BUILD_LDFLAGS_CXX_JDK="$OPENJDK_BUILD_LDFLAGS_CXX_JDK $LDFLAGS_CXX_SOLSTUDIO -xnolib"
+    OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LDFLAGS_SOLSTUDIO -library=%none -mt $LDFLAGS_CXX_SOLSTUDIO -z noversion"
+    if test "x$OPENJDK_BUILD_CPU_ARCH" = "xsparc"; then
+      OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -xarch=sparc"
+    fi
+  elif test "x$TOOLCHAIN_TYPE" = xxlc; then
+    LDFLAGS_XLC="-b64 -brtl -bnolibpath -bexpall -bernotok"
+    OPENJDK_BUILD_LDFLAGS_JDK="${OPENJDK_BUILD_LDFLAGS_JDK} $LDFLAGS_XLC"
+    OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $LDFLAGS_XLC"
+  fi
+
+  # Customize LDFLAGS for executables
+
+  OPENJDK_BUILD_LDFLAGS_JDKEXE="${OPENJDK_BUILD_LDFLAGS_JDK}"
+
+  if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+    if test "x$OPENJDK_BUILD_CPU_BITS" = "x64"; then
+      LDFLAGS_STACK_SIZE=1048576
+    else
+      LDFLAGS_STACK_SIZE=327680
+    fi
+    OPENJDK_BUILD_LDFLAGS_JDKEXE="${OPENJDK_BUILD_LDFLAGS_JDKEXE} /STACK:$LDFLAGS_STACK_SIZE"
+  elif test "x$OPENJDK_BUILD_OS" = xlinux; then
+    OPENJDK_BUILD_LDFLAGS_JDKEXE="$OPENJDK_BUILD_LDFLAGS_JDKEXE -Wl,--allow-shlib-undefined"
+  fi
+
+  OPENJDK_BUILD_LDFLAGS_JDKEXE="${OPENJDK_BUILD_LDFLAGS_JDKEXE} ${OPENJDK_BUILD_EXTRA_LDFLAGS_JDK}"
+
+  # Customize LDFLAGS for libs
+  OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDK}"
+
+  OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} ${SHARED_LIBRARY_FLAGS}"
+  if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
     OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} \
-        -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_TARGET_CPU_LIBDIR)/server"
-  fi
-
-  OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} ${LDFLAGS_JDKLIB}"
-  LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} ${EXTRA_LDFLAGS_JDK}"
-
-
-
-
+        -libpath:${OUTPUT_ROOT}/support/modules_libs/java.base"
+    OPENJDK_BUILD_JDKLIB_LIBS=""
+  else
+    OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} \
+        -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_BUILD_CPU_LIBDIR)"
+
+    if test "xBUILD" = "xTARGET"; then
+    # On some platforms (mac) the linker warns about non existing -L dirs.
+    # Add server first if available. Linking aginst client does not always produce the same results.
+      # Only add client/minimal dir if client/minimal is being built.
+    # Default to server for other variants.
+      if   [[ " $JVM_VARIANTS " =~ " server " ]]  ; then
+        OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_BUILD_CPU_LIBDIR)/server"
+      elif   [[ " $JVM_VARIANTS " =~ " client " ]]  ; then
+        OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_BUILD_CPU_LIBDIR)/client"
+      elif   [[ " $JVM_VARIANTS " =~ " minimal " ]]  ; then
+        OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_BUILD_CPU_LIBDIR)/minimal"
+    else
+        OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_BUILD_CPU_LIBDIR)/server"
+    fi
+    elif test "xBUILD" = "xBUILD"; then
+      # When building a buildjdk, it's always only the server variant
+      OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} \
+          -L\$(SUPPORT_OUTPUTDIR)/modules_libs/java.base\$(OPENJDK_BUILD_CPU_LIBDIR)/server"
+    fi
+
+    OPENJDK_BUILD_JDKLIB_LIBS="-ljava -ljvm"
+    if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+      OPENJDK_BUILD_JDKLIB_LIBS="$OPENJDK_BUILD_JDKLIB_LIBS -lc"
+    fi
+
+  fi
+
+  # Set OPENJDK_BUILD_JVM_LIBS (per os)
+  if test "x$OPENJDK_BUILD_OS" = xlinux; then
+    OPENJDK_BUILD_JVM_LIBS="$OPENJDK_BUILD_JVM_LIBS -lm -ldl -lpthread"
+  elif test "x$OPENJDK_BUILD_OS" = xsolaris; then
+    # FIXME: This hard-coded path is not really proper.
+    if test "x$OPENJDK_BUILD_CPU" = xx86_64; then
+      OPENJDK_BUILD_SOLARIS_LIBM_LIBS="/usr/lib/amd64/libm.so.1"
+    elif test "x$OPENJDK_BUILD_CPU" = xsparcv9; then
+      OPENJDK_BUILD_SOLARIS_LIBM_LIBS="/usr/lib/sparcv9/libm.so.1"
+    fi
+    OPENJDK_BUILD_JVM_LIBS="$OPENJDK_BUILD_JVM_LIBS -lsocket -lsched -ldl $SOLARIS_LIBM_LIBS -lCrun \
+        -lthread -ldoor -lc -ldemangle -lnsl -lkstat -lrt"
+  elif test "x$OPENJDK_BUILD_OS" = xmacosx; then
+    OPENJDK_BUILD_JVM_LIBS="$OPENJDK_BUILD_JVM_LIBS -lm"
+  elif test "x$OPENJDK_BUILD_OS" = xaix; then
+    OPENJDK_BUILD_JVM_LIBS="$OPENJDK_BUILD_JVM_LIBS -Wl,-lC_r -lm -ldl -lpthread"
+  elif test "x$OPENJDK_BUILD_OS" = xbsd; then
+    OPENJDK_BUILD_JVM_LIBS="$OPENJDK_BUILD_JVM_LIBS -lm"
+  elif test "x$OPENJDK_BUILD_OS" = xwindows; then
+    OPENJDK_BUILD_JVM_LIBS="$OPENJDK_BUILD_JVM_LIBS kernel32.lib user32.lib gdi32.lib winspool.lib \
+        comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib \
+        wsock32.lib winmm.lib version.lib psapi.lib"
+    fi
+
+  # Set OPENJDK_BUILD_JVM_ASFLAGS
+  if test "x$OPENJDK_BUILD_OS" = xlinux; then
+    if test "x$OPENJDK_BUILD_CPU" = xx86; then
+      OPENJDK_BUILD_JVM_ASFLAGS="$OPENJDK_BUILD_JVM_ASFLAGS -march=i586"
+    fi
+  elif test "x$OPENJDK_BUILD_OS" = xmacosx; then
+    OPENJDK_BUILD_JVM_ASFLAGS="$OPENJDK_BUILD_JVM_ASFLAGS -x assembler-with-cpp -mno-omit-leaf-frame-pointer -mstack-alignment=16"
+  fi
+
+  OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} ${OPENJDK_BUILD_EXTRA_LDFLAGS_JDK}"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  # Tests are only ever compiled for TARGET
+  # Flags for compiling test libraries
+  CFLAGS_TESTLIB="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK $PICFLAG $CFLAGS_JDKLIB_EXTRA"
+  CXXFLAGS_TESTLIB="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK $PICFLAG $CXXFLAGS_JDKLIB_EXTRA"
+
+  # Flags for compiling test executables
+  CFLAGS_TESTEXE="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK"
+  CXXFLAGS_TESTEXE="$COMMON_CCXXFLAGS_JDK $CXXFLAGS_JDK"
 
 
 
@@ -49549,6 +51030,7 @@
 
 
 
+
   # Some Zero and Shark settings.
   # ZERO_ARCHFLAG tells the compiler which mode to build for
   case "${OPENJDK_TARGET_CPU}" in
@@ -50897,6 +52379,222 @@
 
 
 
+# Need toolchain to setup dtrace
+
+  # Test for dtrace dependencies
+  # Check whether --enable-dtrace was given.
+if test "${enable_dtrace+set}" = set; then :
+  enableval=$enable_dtrace;
+fi
+
+
+  DTRACE_DEP_MISSING=false
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dtrace tool" >&5
+$as_echo_n "checking for dtrace tool... " >&6; }
+  if test "x$DTRACE" != "x" && test -x "$DTRACE"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DTRACE" >&5
+$as_echo "$DTRACE" >&6; }
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found, cannot build dtrace" >&5
+$as_echo "not found, cannot build dtrace" >&6; }
+    DTRACE_DEP_MISSING=true
+  fi
+
+  for ac_header in sys/sdt.h
+do :
+  ac_fn_cxx_check_header_mongrel "$LINENO" "sys/sdt.h" "ac_cv_header_sys_sdt_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_sdt_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_SDT_H 1
+_ACEOF
+ DTRACE_HEADERS_OK=yes
+else
+  DTRACE_HEADERS_OK=no
+fi
+
+done
+
+  if test "x$DTRACE_HEADERS_OK" != "xyes"; then
+    DTRACE_DEP_MISSING=true
+  fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if dtrace should be built" >&5
+$as_echo_n "checking if dtrace should be built... " >&6; }
+  if test "x$enable_dtrace" = "xyes"; then
+    if test "x$DTRACE_DEP_MISSING" = "xtrue"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, missing dependencies" >&5
+$as_echo "no, missing dependencies" >&6; }
+
+  # Print a helpful message on how to acquire the necessary build dependency.
+  # dtrace is the help tag: freetype, cups, alsa etc
+  MISSING_DEPENDENCY=dtrace
+
+  if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+    cygwin_help $MISSING_DEPENDENCY
+  elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+    msys_help $MISSING_DEPENDENCY
+  else
+    PKGHANDLER_COMMAND=
+
+    case $PKGHANDLER in
+      apt-get)
+        apt_help     $MISSING_DEPENDENCY ;;
+      yum)
+        yum_help     $MISSING_DEPENDENCY ;;
+      port)
+        port_help    $MISSING_DEPENDENCY ;;
+      pkgutil)
+        pkgutil_help $MISSING_DEPENDENCY ;;
+      pkgadd)
+        pkgadd_help  $MISSING_DEPENDENCY ;;
+    esac
+
+    if test "x$PKGHANDLER_COMMAND" != x; then
+      HELP_MSG="You might be able to fix this by running '$PKGHANDLER_COMMAND'."
+    fi
+  fi
+
+      as_fn_error $? "Cannot enable dtrace with missing dependencies. See above. $HELP_MSG" "$LINENO" 5
+    else
+      INCLUDE_DTRACE=true
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes, forced" >&5
+$as_echo "yes, forced" >&6; }
+    fi
+  elif test "x$enable_dtrace" = "xno"; then
+    INCLUDE_DTRACE=false
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, forced" >&5
+$as_echo "no, forced" >&6; }
+  elif test "x$enable_dtrace" = "xauto" || test "x$enable_dtrace" = "x"; then
+    if test "x$OPENJDK_TARGET_OS" = "xlinux" && test "x$OPENJDK" != "xtrue"; then
+      INCLUDE_DTRACE=false
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, non-open linux build" >&5
+$as_echo "no, non-open linux build" >&6; }
+    elif test "x$DTRACE_DEP_MISSING" = "xtrue"; then
+      INCLUDE_DTRACE=false
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, missing dependencies" >&5
+$as_echo "no, missing dependencies" >&6; }
+    else
+      INCLUDE_DTRACE=true
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes, dependencies present" >&5
+$as_echo "yes, dependencies present" >&6; }
+    fi
+  else
+    as_fn_error $? "Invalid value for --enable-dtrace: $enable_dtrace" "$LINENO" 5
+  fi
+
+
+
+  # The user can in some cases supply additional jvm features. For the custom
+  # variant, this defines the entire variant.
+
+# Check whether --with-jvm-features was given.
+if test "${with_jvm_features+set}" = set; then :
+  withval=$with_jvm_features;
+fi
+
+  if test "x$with_jvm_features" != x; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking additional JVM features" >&5
+$as_echo_n "checking additional JVM features... " >&6; }
+    JVM_FEATURES=`$ECHO $with_jvm_features | $SED -e 's/,/ /g'`
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JVM_FEATURES" >&5
+$as_echo "$JVM_FEATURES" >&6; }
+  fi
+
+  # Verify that dependencies are met for explicitly set features.
+  if   [[ " $JVM_FEATURES " =~ " jvmti " ]]   && !   [[ " $JVM_FEATURES " =~ " services " ]]  ; then
+    as_fn_error $? "Specified JVM feature 'jvmti' requires feature 'services'" "$LINENO" 5
+  fi
+
+  if   [[ " $JVM_FEATURES " =~ " management " ]]   && !   [[ " $JVM_FEATURES " =~ " nmt " ]]  ; then
+    as_fn_error $? "Specified JVM feature 'management' requires feature 'nmt'" "$LINENO" 5
+  fi
+
+  if   [[ " $JVM_FEATURES " =~ " jvmci " ]]   && !   [[ " $JVM_FEATURES " =~ " compiler2 " ]]  ; then
+    as_fn_error $? "Specified JVM feature 'jvmci' requires feature 'compiler2'" "$LINENO" 5
+  fi
+
+  if   [[ " $JVM_FEATURES " =~ " compiler2 " ]]   && !   [[ " $JVM_FEATURES " =~ " all-gcs " ]]  ; then
+    as_fn_error $? "Specified JVM feature 'compiler2' requires feature 'all-gcs'" "$LINENO" 5
+  fi
+
+  if   [[ " $JVM_FEATURES " =~ " vm-structs " ]]   && !   [[ " $JVM_FEATURES " =~ " all-gcs " ]]  ; then
+    as_fn_error $? "Specified JVM feature 'vm-structs' requires feature 'all-gcs'" "$LINENO" 5
+  fi
+
+  # Turn on additional features based on other parts of configure
+  if test "x$INCLUDE_DTRACE" = "xtrue"; then
+    JVM_FEATURES="$JVM_FEATURES dtrace"
+  else
+    if   [[ " $JVM_FEATURES " =~ " dtrace " ]]  ; then
+      as_fn_error $? "To enable dtrace, you must use --enable-dtrace" "$LINENO" 5
+    fi
+  fi
+
+  if test "x$STATIC_BUILD" = "xtrue"; then
+    JVM_FEATURES="$JVM_FEATURES static-build"
+  else
+    if   [[ " $JVM_FEATURES " =~ " static-build " ]]  ; then
+      as_fn_error $? "To enable static-build, you must use --enable-static-build" "$LINENO" 5
+    fi
+  fi
+
+  if !   [[ " $JVM_VARIANTS " =~ " zero " ]]   && !   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
+    if   [[ " $JVM_FEATURES " =~ " zero " ]]  ; then
+      as_fn_error $? "To enable zero/zeroshark, you must use --with-jvm-variants=zero/zeroshark" "$LINENO" 5
+    fi
+  fi
+
+  if !   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
+    if   [[ " $JVM_FEATURES " =~ " shark " ]]  ; then
+      as_fn_error $? "To enable shark, you must use --with-jvm-variants=zeroshark" "$LINENO" 5
+    fi
+  fi
+
+  # Only enable jvmci on x86_64, sparcv9 and aarch64, and only on server.
+  if test "x$OPENJDK_TARGET_CPU" = "xx86_64" || \
+      test "x$OPENJDK_TARGET_CPU" = "xsparcv9" || \
+      test "x$OPENJDK_TARGET_CPU" = "xaarch64" ; then
+    JVM_FEATURES_jvmci="jvmci"
+  else
+    JVM_FEATURES_jvmci=""
+  fi
+
+  # All variants but minimal (and custom) get these features
+  NON_MINIMAL_FEATURES="$NON_MINIMAL_FEATURES jvmti fprof vm-structs jni-check services management all-gcs nmt cds"
+
+  # Enable features depending on variant.
+  JVM_FEATURES_server="compiler1 compiler2 $NON_MINIMAL_FEATURES $JVM_FEATURES $JVM_FEATURES_jvmci"
+  JVM_FEATURES_client="compiler1 $NON_MINIMAL_FEATURES $JVM_FEATURES"
+  JVM_FEATURES_core="$NON_MINIMAL_FEATURES $JVM_FEATURES"
+  JVM_FEATURES_minimal="compiler1 minimal $JVM_FEATURES"
+  JVM_FEATURES_zero="zero $NON_MINIMAL_FEATURES $JVM_FEATURES"
+  JVM_FEATURES_zeroshark="zero shark $NON_MINIMAL_FEATURES $JVM_FEATURES"
+  JVM_FEATURES_custom="$JVM_FEATURES"
+
+
+
+
+
+
+
+
+
+  # Used for verification of Makefiles by check-jvm-feature
+
+
+  # We don't support --with-jvm-interpreter anymore, use zero instead.
+
+
+# Check whether --with-jvm-interpreter was given.
+if test "${with_jvm_interpreter+set}" = set; then :
+  withval=$with_jvm_interpreter; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Option --with-jvm-interpreter is deprecated and will be ignored." >&5
+$as_echo "$as_me: WARNING: Option --with-jvm-interpreter is deprecated and will be ignored." >&2;}
+fi
+
+
+
+
 ###############################################################################
 #
 # Check dependencies for external and internal libraries.
@@ -51023,7 +52721,7 @@
   fi
 
   # Check if ffi is needed
-  if test "x$JVM_VARIANT_ZERO" = xtrue || test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then
+  if   [[ " $JVM_VARIANTS " =~ " zero " ]]   ||   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
     NEEDS_LIB_FFI=true
   else
     NEEDS_LIB_FFI=false
@@ -51146,14 +52844,26 @@
     # If dynamic wasn't requested, go with static unless it isn't available.
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libstdc++" >&5
 $as_echo_n "checking how to link with libstdc++... " >&6; }
-    if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno || test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then
+    if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno ||   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
       LIBCXX="$LIBCXX -lstdc++"
+      # To help comparisons with old build, put stdc++ first in JVM_LIBS
+      JVM_LIBS="-lstdc++ $JVM_LIBS"
+      # Ideally, we should test stdc++ for the BUILD toolchain separately. For now
+      # just use the same setting as for the TARGET toolchain.
+      OPENJDK_BUILD_JVM_LIBS="-lstdc++ $OPENJDK_BUILD_JVM_LIBS"
       LDCXX="$CXX"
       STATIC_CXX_SETTING="STATIC_CXX=false"
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: dynamic" >&5
 $as_echo "dynamic" >&6; }
     else
       LIBCXX="$LIBCXX $STATIC_STDCXX_FLAGS"
+      JVM_LDFLAGS="$JVM_LDFLAGS -static-libgcc"
+      # To help comparisons with old build, put stdc++ first in JVM_LIBS
+      JVM_LIBS="-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic $JVM_LIBS"
+      # Ideally, we should test stdc++ for the BUILD toolchain separately. For now
+      # just use the same setting as for the TARGET toolchain.
+      OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -static-libgcc"
+      OPENJDK_BUILD_JVM_LIBS="-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic $OPENJDK_BUILD_JVM_LIBS"
       LDCXX="$CC"
       STATIC_CXX_SETTING="STATIC_CXX=true"
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5
@@ -61305,7 +63015,7 @@
 
 
 
-  if test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then
+  if   [[ " $JVM_VARIANTS " =~ " zeroshark " ]]  ; then
     # Extract the first word of "llvm-config", so it can be a program name with args.
 set dummy llvm-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
@@ -62031,9 +63741,143 @@
 ###############################################################################
 
 
+  # Check whether --enable-new-hotspot-build was given.
+if test "${enable_new_hotspot_build+set}" = set; then :
+  enableval=$enable_new_hotspot_build;
+fi
+
+
+   if test "x$enable_new_hotspot_build" = "x" || test "x$enable_new_hotspot_build" = "xyes"; then
+     USE_NEW_HOTSPOT_BUILD=true
+   else
+     USE_NEW_HOTSPOT_BUILD=false
+   fi
+
+
+  case $HOTSPOT_DEBUG_LEVEL in
+    product )
+      VARIANT="OPT"
+      FASTDEBUG="false"
+      DEBUG_CLASSFILES="false"
+      ;;
+    fastdebug )
+      VARIANT="DBG"
+      FASTDEBUG="true"
+      DEBUG_CLASSFILES="true"
+      ;;
+    debug )
+      VARIANT="DBG"
+      FASTDEBUG="false"
+      DEBUG_CLASSFILES="true"
+      ;;
+    optimized )
+      VARIANT="OPT"
+      FASTDEBUG="false"
+      DEBUG_CLASSFILES="false"
+      ;;
+  esac
+
+
+
+
+  if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then
+    MACOSX_UNIVERSAL="true"
+  fi
+
+
+
+  # Make sure JVM_VARIANTS_COMMA use minimal1 for backwards compatibility
+  JVM_VARIANTS_COMMA=`$ECHO ,$JVM_VARIANTS_OPT, | $SED -e 's/,minimal,/,minimal1,/'`
+
+  JVM_VARIANT_SERVER=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,server,/!s/.*/false/g' -e '/,server,/s/.*/true/g'`
+  JVM_VARIANT_CLIENT=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,client,/!s/.*/false/g' -e '/,client,/s/.*/true/g'`
+  JVM_VARIANT_MINIMAL1=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,minimal1\?,/!s/.*/false/g' -e '/,minimal1\?,/s/.*/true/g'`
+  JVM_VARIANT_CORE=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,core,/!s/.*/false/g' -e '/,core,/s/.*/true/g'`
+  JVM_VARIANT_ZERO=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,zero,/!s/.*/false/g' -e '/,zero,/s/.*/true/g'`
+  JVM_VARIANT_ZEROSHARK=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,zeroshark,/!s/.*/false/g' -e '/,zeroshark,/s/.*/true/g'`
+  JVM_VARIANT_CUSTOM=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,custom,/!s/.*/false/g' -e '/,custom,/s/.*/true/g'`
+
+  #####
+  # Generate the legacy makefile targets for hotspot.
+  HOTSPOT_TARGET=""
+
+  if test "x$JVM_VARIANT_SERVER" = xtrue; then
+    HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL} "
+  fi
+
+  if test "x$JVM_VARIANT_CLIENT" = xtrue; then
+    HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}1 "
+  fi
+
+  if test "x$JVM_VARIANT_MINIMAL1" = xtrue; then
+    HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}minimal1 "
+  fi
+
+  if test "x$JVM_VARIANT_ZERO" = xtrue; then
+    HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}zero "
+  fi
+
+  if test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then
+    HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}shark "
+  fi
+
+  if test "x$JVM_VARIANT_CORE" = xtrue; then
+    HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}core "
+  fi
+
+  HOTSPOT_TARGET="$HOTSPOT_TARGET docs export_$HOTSPOT_DEBUG_LEVEL"
+
+  # On Macosx universal binaries are produced, but they only contain
+  # 64 bit intel. This invalidates control of which jvms are built
+  # from configure, but only server is valid anyway. Fix this
+  # when hotspot makefiles are rewritten.
+  if test "x$MACOSX_UNIVERSAL" = xtrue; then
+    HOTSPOT_TARGET=universal_${HOTSPOT_DEBUG_LEVEL}
+  fi
+
   HOTSPOT_MAKE_ARGS="$HOTSPOT_TARGET"
 
 
+  # Control wether Hotspot runs Queens test after build.
+  # Check whether --enable-hotspot-test-in-build was given.
+if test "${enable_hotspot_test_in_build+set}" = set; then :
+  enableval=$enable_hotspot_test_in_build;
+else
+  enable_hotspot_test_in_build=no
+fi
+
+  if test "x$enable_hotspot_test_in_build" = "xyes"; then
+    TEST_IN_BUILD=true
+  else
+    TEST_IN_BUILD=false
+  fi
+
+
+  if test "x$USE_NEW_HOTSPOT_BUILD" = xfalse; then
+    if test "x$JVM_VARIANT_CLIENT" = xtrue; then
+      if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+        as_fn_error $? "You cannot build a client JVM for a 64-bit machine." "$LINENO" 5
+      fi
+    fi
+    if test "x$JVM_VARIANT_MINIMAL1" = xtrue; then
+      if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+        as_fn_error $? "You cannot build a minimal JVM for a 64-bit machine." "$LINENO" 5
+      fi
+    fi
+    if test "x$JVM_VARIANT_CUSTOM" = xtrue; then
+        as_fn_error $? "You cannot build a custom JVM using the old hotspot build system." "$LINENO" 5
+    fi
+  fi
+
+
+
+
+
+
+
+
+
+
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking if elliptic curve crypto implementation is present" >&5
 $as_echo_n "checking if elliptic curve crypto implementation is present... " >&6; }
@@ -62438,6 +64282,21 @@
   fi
 
 
+  $ECHO "Check if jvm arg is ok: -XX:TieredStopAtLevel=1" >&5
+  $ECHO "Command: $JAVA -XX:TieredStopAtLevel=1 -version" >&5
+  OUTPUT=`$JAVA -XX:TieredStopAtLevel=1 -version 2>&1`
+  FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+  FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
+  if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
+    boot_jdk_jvmargs_small="$boot_jdk_jvmargs_small -XX:TieredStopAtLevel=1"
+    JVM_ARG_OK=true
+  else
+    $ECHO "Arg failed:" >&5
+    $ECHO "$OUTPUT" >&5
+    JVM_ARG_OK=false
+  fi
+
+
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $boot_jdk_jvmargs_small" >&5
 $as_echo "$boot_jdk_jvmargs_small" >&6; }
 
@@ -63322,6 +65181,10 @@
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, does not work effectively with icecc" >&5
 $as_echo "no, does not work effectively with icecc" >&6; }
     USE_PRECOMPILED_HEADER=0
+  elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, does not work with Solaris Studio" >&5
+$as_echo "no, does not work with Solaris Studio" >&6; }
+    USE_PRECOMPILED_HEADER=0
   else
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
@@ -63742,6 +65605,32 @@
 # At the end, call the custom hook. (Dummy macro if no custom sources available)
 
 
+# This needs to be done after CUSTOM_LATE_HOOK since we can setup custom features.
+
+  # Keep feature lists sorted and free of duplicates
+  JVM_FEATURES_server="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_server | $SORT -u))"
+  JVM_FEATURES_client="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_client | $SORT -u))"
+  JVM_FEATURES_core="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_core | $SORT -u))"
+  JVM_FEATURES_minimal="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_minimal | $SORT -u))"
+  JVM_FEATURES_zero="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_zero | $SORT -u))"
+  JVM_FEATURES_zeroshark="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_zeroshark | $SORT -u))"
+  JVM_FEATURES_custom="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_custom | $SORT -u))"
+
+  # Validate features
+  for variant in $JVM_VARIANTS; do
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking JVM features for JVM variant '$variant'" >&5
+$as_echo_n "checking JVM features for JVM variant '$variant'... " >&6; }
+    features_var_name=JVM_FEATURES_$variant
+    JVM_FEATURES_TO_TEST=${!features_var_name}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JVM_FEATURES_TO_TEST" >&5
+$as_echo "$JVM_FEATURES_TO_TEST" >&6; }
+    INVALID_FEATURES=`$GREP -Fvx "${VALID_JVM_FEATURES// /$'\n'}" <<< "${JVM_FEATURES_TO_TEST// /$'\n'}"`
+    if test "x$INVALID_FEATURES" != x; then
+      as_fn_error $? "Invalid JVM feature(s): $INVALID_FEATURES" "$LINENO" 5
+    fi
+  done
+
+
 # We're messing a bit with internal autoconf variables to put the config.status
 # in the output directory instead of the current directory.
 CONFIG_STATUS="$CONFIGURESUPPORT_OUTPUTDIR/config.status"
@@ -64965,7 +66854,7 @@
   printf "* Debug level:    $DEBUG_LEVEL\n"
   printf "* HS debug level: $HOTSPOT_DEBUG_LEVEL\n"
   printf "* JDK variant:    $JDK_VARIANT\n"
-  printf "* JVM variants:   $with_jvm_variants\n"
+  printf "* JVM variants:   $JVM_VARIANTS\n"
   printf "* OpenJDK target: OS: $OPENJDK_TARGET_OS, CPU architecture: $OPENJDK_TARGET_CPU_ARCH, address length: $OPENJDK_TARGET_CPU_BITS\n"
   printf "* Version string: $VERSION_STRING ($VERSION_SHORT)\n"
 
@@ -64991,7 +66880,7 @@
   fi
   printf "\n"
 
-  if test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = "xyes"; then
+  if test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = "xtrue"; then
     printf "NOTE: You have requested to build more than one version of the JVM, which\n"
     printf "will result in longer build times.\n"
     printf "\n"
--- a/common/autoconf/help.m4	Fri Apr 29 04:44:08 2016 +0200
+++ b/common/autoconf/help.m4	Thu Apr 28 23:08:16 2016 -0700
@@ -119,6 +119,8 @@
       PKGHANDLER_COMMAND="sudo apt-get install libX11-dev libxext-dev libxrender-dev libxtst-dev libxt-dev" ;;
     ccache)
       PKGHANDLER_COMMAND="sudo apt-get install ccache" ;;
+    dtrace)
+      PKGHANDLER_COMMAND="sudo apt-get install systemtap-sdt-dev" ;;
   esac
 }
 
@@ -170,6 +172,13 @@
       TOOLCHAIN_DESCRIPTION=${!toolchain_var_name}
       $PRINTF "  %-10s  %s\n" $toolchain "$TOOLCHAIN_DESCRIPTION"
     done
+    $PRINTF "\n"
+
+    # Print available jvm features
+    $PRINTF "The following JVM features are available as arguments to --with-jvm-features.\n"
+    $PRINTF "Which are valid to use depends on the target platform.\n  "
+    $PRINTF "%s " $VALID_JVM_FEATURES
+    $PRINTF "\n"
 
     # And now exit directly
     exit 0
@@ -206,7 +215,7 @@
   printf "* Debug level:    $DEBUG_LEVEL\n"
   printf "* HS debug level: $HOTSPOT_DEBUG_LEVEL\n"
   printf "* JDK variant:    $JDK_VARIANT\n"
-  printf "* JVM variants:   $with_jvm_variants\n"
+  printf "* JVM variants:   $JVM_VARIANTS\n"
   printf "* OpenJDK target: OS: $OPENJDK_TARGET_OS, CPU architecture: $OPENJDK_TARGET_CPU_ARCH, address length: $OPENJDK_TARGET_CPU_BITS\n"
   printf "* Version string: $VERSION_STRING ($VERSION_SHORT)\n"
 
@@ -232,7 +241,7 @@
   fi
   printf "\n"
 
-  if test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = "xyes"; then
+  if test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = "xtrue"; then
     printf "NOTE: You have requested to build more than one version of the JVM, which\n"
     printf "will result in longer build times.\n"
     printf "\n"
--- a/common/autoconf/hotspot-spec.gmk.in	Fri Apr 29 04:44:08 2016 +0200
+++ b/common/autoconf/hotspot-spec.gmk.in	Thu Apr 28 23:08:16 2016 -0700
@@ -38,6 +38,16 @@
 # Legacy defines controlled by the SUPPORT_HEADLESS and SUPPORT_HEADFUL options.
 @BUILD_HEADLESS@
 
+JVM_VARIANTS:=@JVM_VARIANTS_COMMA@
+
+JVM_VARIANT_SERVER:=@JVM_VARIANT_SERVER@
+JVM_VARIANT_CLIENT:=@JVM_VARIANT_CLIENT@
+JVM_VARIANT_MINIMAL1:=@JVM_VARIANT_MINIMAL1@
+JVM_VARIANT_CORE:=@JVM_VARIANT_CORE@
+JVM_VARIANT_ZERO:=@JVM_VARIANT_ZERO@
+JVM_VARIANT_ZEROSHARK:=@JVM_VARIANT_ZEROSHARK@
+JVM_VARIANT_CUSTOM:=@JVM_VARIANT_HOTSPOT@
+
 # Legacy setting: OPT or DBG
 VARIANT:=@VARIANT@
 # Legacy setting: true or false
@@ -92,8 +102,7 @@
 ALT_OUTPUTDIR=$(HOTSPOT_OUTPUTDIR)
 ALT_EXPORT_PATH=$(HOTSPOT_DIST)
 
-JVM_INTERPRETER:=@JVM_INTERPRETER@
-ifeq ($(JVM_INTERPRETER), cpp)
+ifeq ($(HOTSPOT_TARGET_CPU), zero)
   CC_INTERP=true
 endif
 
--- a/common/autoconf/hotspot.m4	Fri Apr 29 04:44:08 2016 +0200
+++ b/common/autoconf/hotspot.m4	Thu Apr 28 23:08:16 2016 -0700
@@ -23,170 +23,344 @@
 # questions.
 #
 
-###############################################################################
-# Check which interpreter of the JVM we want to build.
-# Currently we have:
-#    template: Template interpreter (the default)
-#    cpp     : C++ interpreter
-AC_DEFUN_ONCE([HOTSPOT_SETUP_JVM_INTERPRETER],
-[
-  AC_ARG_WITH([jvm-interpreter], [AS_HELP_STRING([--with-jvm-interpreter],
-    [JVM interpreter to build (template, cpp) @<:@template@:>@])])
+# All valid JVM features, regardless of platform
+VALID_JVM_FEATURES="compiler1 compiler2 zero shark minimal dtrace jvmti jvmci \
+    fprof vm-structs jni-check services management all-gcs nmt cds static-build"
+
+# All valid JVM variants
+VALID_JVM_VARIANTS="server client minimal core zero zeroshark custom"
 
-  AC_MSG_CHECKING([which interpreter of the JVM to build])
-  if test "x$with_jvm_interpreter" = x; then
-    JVM_INTERPRETER="template"
-  else
-    JVM_INTERPRETER="$with_jvm_interpreter"
-  fi
-  AC_MSG_RESULT([$JVM_INTERPRETER])
+###############################################################################
+# Check if the specified JVM variant should be built. To be used in shell if
+# constructs, like this:
+# if HOTSPOT_CHECK_JVM_VARIANT(server); then
+#
+# Only valid to use after HOTSPOT_SETUP_JVM_VARIANTS has setup variants.
 
-  if test "x$JVM_INTERPRETER" != xtemplate && test "x$JVM_INTERPRETER" != xcpp; then
-    AC_MSG_ERROR([The available JVM interpreters are: template, cpp])
-  fi
-
-  AC_SUBST(JVM_INTERPRETER)
-])
+# Definition kept in one line to allow inlining in if statements.
+# Additional [] needed to keep m4 from mangling shell constructs.
+AC_DEFUN([HOTSPOT_CHECK_JVM_VARIANT],
+[ [ [[ " $JVM_VARIANTS " =~ " $1 " ]] ] ])
 
 ###############################################################################
-# Check which variants of the JVM that we want to build.
-# Currently we have:
-#    server: normal interpreter and a C2 or tiered C1/C2 compiler
-#    client: normal interpreter and C1 (no C2 compiler) (only 32-bit platforms)
-#    minimal1: reduced form of client with optional VM services and features stripped out
-#    zero: no machine code interpreter, no compiler
-#    zeroshark: zero interpreter and shark/llvm compiler backend
-#    core: interpreter only, no compiler (only works on some platforms)
+# Check if the specified JVM features are explicitly enabled. To be used in
+# shell if constructs, like this:
+# if HOTSPOT_CHECK_JVM_FEATURE(jvmti); then
+#
+# Only valid to use after HOTSPOT_SETUP_JVM_FEATURES has setup features.
+
+# Definition kept in one line to allow inlining in if statements.
+# Additional [] needed to keep m4 from mangling shell constructs.
+AC_DEFUN([HOTSPOT_CHECK_JVM_FEATURE],
+[ [ [[ " $JVM_FEATURES " =~ " $1 " ]] ] ])
+
+###############################################################################
+# Check which variants of the JVM that we want to build. Available variants are:
+#   server: normal interpreter, and a tiered C1/C2 compiler
+#   client: normal interpreter, and C1 (no C2 compiler)
+#   minimal: reduced form of client with optional features stripped out
+#   core: normal interpreter only, no compiler
+#   zero: C++ based interpreter only, no compiler
+#   zeroshark: C++ based interpreter, and a llvm-based compiler
+#   custom: baseline JVM with no default features
+#
 AC_DEFUN_ONCE([HOTSPOT_SETUP_JVM_VARIANTS],
 [
-  AC_MSG_CHECKING([which variants of the JVM to build])
   AC_ARG_WITH([jvm-variants], [AS_HELP_STRING([--with-jvm-variants],
-      [JVM variants (separated by commas) to build (server, client, minimal1, zero, zeroshark, core) @<:@server@:>@])])
+      [JVM variants (separated by commas) to build (server,client,minimal,core,zero,zeroshark,custom) @<:@server@:>@])])
 
   if test "x$with_jvm_variants" = x; then
     with_jvm_variants="server"
   fi
+  JVM_VARIANTS_OPT="$with_jvm_variants"
 
-  JVM_VARIANTS=",$with_jvm_variants,"
-  TEST_VARIANTS=`$ECHO "$JVM_VARIANTS" | $SED -e 's/server,//' -e 's/client,//'  -e 's/minimal1,//' -e 's/zero,//' -e 's/zeroshark,//' -e 's/core,//'`
+  # Has the user listed more than one variant?
+  # Additional [] needed to keep m4 from mangling shell constructs.
+  if [ [[ "$JVM_VARIANTS_OPT" =~ "," ]] ]; then
+    BUILDING_MULTIPLE_JVM_VARIANTS=true
+  else
+    BUILDING_MULTIPLE_JVM_VARIANTS=false
+  fi
+  # Replace the commas with AND for use in the build directory name.
+  JVM_VARIANTS_WITH_AND=`$ECHO "$JVM_VARIANTS_OPT" | $SED -e 's/,/AND/g'`
+
+  AC_MSG_CHECKING([which variants of the JVM to build])
+  # JVM_VARIANTS is a space-separated list.
+  # Also use minimal, not minimal1 (which is kept for backwards compatibility).
+  JVM_VARIANTS=`$ECHO $JVM_VARIANTS_OPT | $SED -e 's/,/ /g' -e 's/minimal1/minimal/'`
+  AC_MSG_RESULT([$JVM_VARIANTS])
+
+  # Check that the selected variants are valid
+
+  # grep filter function inspired by a comment to http://stackoverflow.com/a/1617326
+  INVALID_VARIANTS=`$GREP -Fvx "${VALID_JVM_VARIANTS// /$'\n'}" <<< "${JVM_VARIANTS// /$'\n'}"`
+  if test "x$INVALID_VARIANTS" != x; then
+    AC_MSG_NOTICE([Unknown variant(s) specified: $INVALID_VARIANTS])
+    AC_MSG_ERROR([The available JVM variants are: $VALID_JVM_VARIANTS])
+  fi
+
+  # All "special" variants share the same output directory ("server")
+  VALID_MULTIPLE_JVM_VARIANTS="server client minimal"
+  INVALID_MULTIPLE_VARIANTS=`$GREP -Fvx "${VALID_MULTIPLE_JVM_VARIANTS// /$'\n'}" <<< "${JVM_VARIANTS// /$'\n'}"`
+  if  test "x$INVALID_MULTIPLE_VARIANTS" != x && test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = xtrue; then
+    AC_MSG_ERROR([You cannot build multiple variants with anything else than $VALID_MULTIPLE_JVM_VARIANTS.])
+  fi
 
-  if test "x$TEST_VARIANTS" != "x,"; then
-    AC_MSG_ERROR([The available JVM variants are: server, client, minimal1, zero, zeroshark, core])
+  AC_SUBST(JVM_VARIANTS)
+  AC_SUBST(VALID_JVM_VARIANTS)
+
+  if HOTSPOT_CHECK_JVM_VARIANT(zero) || HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
+    # zero behaves as a platform and rewrites these values. This is really weird. :(
+    # We are guaranteed that we do not build any other variants when building zero.
+    HOTSPOT_TARGET_CPU=zero
+    HOTSPOT_TARGET_CPU_ARCH=zero
   fi
-  AC_MSG_RESULT([$with_jvm_variants])
+])
+
+###############################################################################
+# Check if dtrace should be enabled and has all prerequisites present.
+#
+AC_DEFUN_ONCE([HOTSPOT_SETUP_DTRACE],
+[
+  # Test for dtrace dependencies
+  AC_ARG_ENABLE([dtrace], [AS_HELP_STRING([--enable-dtrace@<:@=yes/no/auto@:>@],
+      [enable dtrace. Default is auto, where dtrace is enabled if all dependencies
+      are present.])])
+
+  DTRACE_DEP_MISSING=false
+
+  AC_MSG_CHECKING([for dtrace tool])
+  if test "x$DTRACE" != "x" && test -x "$DTRACE"; then
+    AC_MSG_RESULT([$DTRACE])
+  else
+    AC_MSG_RESULT([not found, cannot build dtrace])
+    DTRACE_DEP_MISSING=true
+  fi
+
+  AC_CHECK_HEADERS([sys/sdt.h], [DTRACE_HEADERS_OK=yes],[DTRACE_HEADERS_OK=no])
+  if test "x$DTRACE_HEADERS_OK" != "xyes"; then
+    DTRACE_DEP_MISSING=true
+  fi
 
-  JVM_VARIANT_SERVER=`$ECHO "$JVM_VARIANTS" | $SED -e '/,server,/!s/.*/false/g' -e '/,server,/s/.*/true/g'`
-  JVM_VARIANT_CLIENT=`$ECHO "$JVM_VARIANTS" | $SED -e '/,client,/!s/.*/false/g' -e '/,client,/s/.*/true/g'`
-  JVM_VARIANT_MINIMAL1=`$ECHO "$JVM_VARIANTS" | $SED -e '/,minimal1,/!s/.*/false/g' -e '/,minimal1,/s/.*/true/g'`
-  JVM_VARIANT_ZERO=`$ECHO "$JVM_VARIANTS" | $SED -e '/,zero,/!s/.*/false/g' -e '/,zero,/s/.*/true/g'`
-  JVM_VARIANT_ZEROSHARK=`$ECHO "$JVM_VARIANTS" | $SED -e '/,zeroshark,/!s/.*/false/g' -e '/,zeroshark,/s/.*/true/g'`
-  JVM_VARIANT_CORE=`$ECHO "$JVM_VARIANTS" | $SED -e '/,core,/!s/.*/false/g' -e '/,core,/s/.*/true/g'`
+  AC_MSG_CHECKING([if dtrace should be built])
+  if test "x$enable_dtrace" = "xyes"; then
+    if test "x$DTRACE_DEP_MISSING" = "xtrue"; then
+      AC_MSG_RESULT([no, missing dependencies])
+      HELP_MSG_MISSING_DEPENDENCY([dtrace])
+      AC_MSG_ERROR([Cannot enable dtrace with missing dependencies. See above. $HELP_MSG])
+    else
+      INCLUDE_DTRACE=true
+      AC_MSG_RESULT([yes, forced])
+    fi
+  elif test "x$enable_dtrace" = "xno"; then
+    INCLUDE_DTRACE=false
+    AC_MSG_RESULT([no, forced])
+  elif test "x$enable_dtrace" = "xauto" || test "x$enable_dtrace" = "x"; then
+    if test "x$OPENJDK_TARGET_OS" = "xlinux" && test "x$OPENJDK" != "xtrue"; then
+      INCLUDE_DTRACE=false
+      AC_MSG_RESULT([no, non-open linux build])
+    elif test "x$DTRACE_DEP_MISSING" = "xtrue"; then
+      INCLUDE_DTRACE=false
+      AC_MSG_RESULT([no, missing dependencies])
+    else
+      INCLUDE_DTRACE=true
+      AC_MSG_RESULT([yes, dependencies present])
+    fi
+  else
+    AC_MSG_ERROR([Invalid value for --enable-dtrace: $enable_dtrace])
+  fi
+  AC_SUBST(INCLUDE_DTRACE)
+])
 
-  if test "x$JVM_VARIANT_CLIENT" = xtrue; then
-    if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
-      AC_MSG_ERROR([You cannot build a client JVM for a 64-bit machine.])
-    fi
+###############################################################################
+# Set up all JVM features for each JVM variant.
+#
+AC_DEFUN_ONCE([HOTSPOT_SETUP_JVM_FEATURES],
+[
+  # The user can in some cases supply additional jvm features. For the custom
+  # variant, this defines the entire variant.
+  AC_ARG_WITH([jvm-features], [AS_HELP_STRING([--with-jvm-features],
+      [additional JVM features to enable (separated by comma),  use '--help' to show possible values @<:@none@:>@])])
+  if test "x$with_jvm_features" != x; then
+    AC_MSG_CHECKING([additional JVM features])
+    JVM_FEATURES=`$ECHO $with_jvm_features | $SED -e 's/,/ /g'`
+    AC_MSG_RESULT([$JVM_FEATURES])
+  fi
+
+  # Verify that dependencies are met for explicitly set features.
+  if HOTSPOT_CHECK_JVM_FEATURE(jvmti) && ! HOTSPOT_CHECK_JVM_FEATURE(services); then
+    AC_MSG_ERROR([Specified JVM feature 'jvmti' requires feature 'services'])
   fi
-  if test "x$JVM_VARIANT_MINIMAL1" = xtrue; then
-    if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
-      AC_MSG_ERROR([You cannot build a minimal JVM for a 64-bit machine.])
+
+  if HOTSPOT_CHECK_JVM_FEATURE(management) && ! HOTSPOT_CHECK_JVM_FEATURE(nmt); then
+    AC_MSG_ERROR([Specified JVM feature 'management' requires feature 'nmt'])
+  fi
+
+  if HOTSPOT_CHECK_JVM_FEATURE(jvmci) && ! HOTSPOT_CHECK_JVM_FEATURE(compiler2); then
+    AC_MSG_ERROR([Specified JVM feature 'jvmci' requires feature 'compiler2'])
+  fi
+
+  if HOTSPOT_CHECK_JVM_FEATURE(compiler2) && ! HOTSPOT_CHECK_JVM_FEATURE(all-gcs); then
+    AC_MSG_ERROR([Specified JVM feature 'compiler2' requires feature 'all-gcs'])
+  fi
+
+  if HOTSPOT_CHECK_JVM_FEATURE(vm-structs) && ! HOTSPOT_CHECK_JVM_FEATURE(all-gcs); then
+    AC_MSG_ERROR([Specified JVM feature 'vm-structs' requires feature 'all-gcs'])
+  fi
+
+  # Turn on additional features based on other parts of configure
+  if test "x$INCLUDE_DTRACE" = "xtrue"; then
+    JVM_FEATURES="$JVM_FEATURES dtrace"
+  else
+    if HOTSPOT_CHECK_JVM_FEATURE(dtrace); then
+      AC_MSG_ERROR([To enable dtrace, you must use --enable-dtrace])
     fi
   fi
 
-  # Replace the commas with AND for use in the build directory name.
-  ANDED_JVM_VARIANTS=`$ECHO "$JVM_VARIANTS" | $SED -e 's/^,//' -e 's/,$//' -e 's/,/AND/g'`
-  COUNT_VARIANTS=`$ECHO "$JVM_VARIANTS" | $SED -e 's/server,/1/' -e 's/client,/1/' -e 's/minimal1,/1/' -e 's/zero,/1/' -e 's/zeroshark,/1/' -e 's/core,/1/'`
-  if test "x$COUNT_VARIANTS" != "x,1"; then
-    BUILDING_MULTIPLE_JVM_VARIANTS=yes
+  if test "x$STATIC_BUILD" = "xtrue"; then
+    JVM_FEATURES="$JVM_FEATURES static-build"
   else
-    BUILDING_MULTIPLE_JVM_VARIANTS=no
+    if HOTSPOT_CHECK_JVM_FEATURE(static-build); then
+      AC_MSG_ERROR([To enable static-build, you must use --enable-static-build])
+    fi
+  fi
+
+  if ! HOTSPOT_CHECK_JVM_VARIANT(zero) && ! HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
+    if HOTSPOT_CHECK_JVM_FEATURE(zero); then
+      AC_MSG_ERROR([To enable zero/zeroshark, you must use --with-jvm-variants=zero/zeroshark])
+    fi
+  fi
+
+  if ! HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
+    if HOTSPOT_CHECK_JVM_FEATURE(shark); then
+      AC_MSG_ERROR([To enable shark, you must use --with-jvm-variants=zeroshark])
+    fi
+  fi
+
+  # Only enable jvmci on x86_64, sparcv9 and aarch64, and only on server.
+  if test "x$OPENJDK_TARGET_CPU" = "xx86_64" || \
+      test "x$OPENJDK_TARGET_CPU" = "xsparcv9" || \
+      test "x$OPENJDK_TARGET_CPU" = "xaarch64" ; then
+    JVM_FEATURES_jvmci="jvmci"
+  else
+    JVM_FEATURES_jvmci=""
   fi
 
-  if test "x$JVM_VARIANT_ZERO" = xtrue && test "x$BUILDING_MULTIPLE_JVM_VARIANTS" = xyes; then
-    AC_MSG_ERROR([You cannot build multiple variants with zero.])
-  fi
+  # All variants but minimal (and custom) get these features
+  NON_MINIMAL_FEATURES="$NON_MINIMAL_FEATURES jvmti fprof vm-structs jni-check services management all-gcs nmt cds"
+
+  # Enable features depending on variant.
+  JVM_FEATURES_server="compiler1 compiler2 $NON_MINIMAL_FEATURES $JVM_FEATURES $JVM_FEATURES_jvmci"
+  JVM_FEATURES_client="compiler1 $NON_MINIMAL_FEATURES $JVM_FEATURES"
+  JVM_FEATURES_core="$NON_MINIMAL_FEATURES $JVM_FEATURES"
+  JVM_FEATURES_minimal="compiler1 minimal $JVM_FEATURES"
+  JVM_FEATURES_zero="zero $NON_MINIMAL_FEATURES $JVM_FEATURES"
+  JVM_FEATURES_zeroshark="zero shark $NON_MINIMAL_FEATURES $JVM_FEATURES"
+  JVM_FEATURES_custom="$JVM_FEATURES"
+
+  AC_SUBST(JVM_FEATURES_server)
+  AC_SUBST(JVM_FEATURES_client)
+  AC_SUBST(JVM_FEATURES_core)
+  AC_SUBST(JVM_FEATURES_minimal)
+  AC_SUBST(JVM_FEATURES_zero)
+  AC_SUBST(JVM_FEATURES_zeroshark)
+  AC_SUBST(JVM_FEATURES_custom)
+
+  # Used for verification of Makefiles by check-jvm-feature
+  AC_SUBST(VALID_JVM_FEATURES)
+
+  # We don't support --with-jvm-interpreter anymore, use zero instead.
+  BASIC_DEPRECATED_ARG_WITH(jvm-interpreter)
+])
+
+###############################################################################
+# Validate JVM features once all setup is complete, including custom setup.
+#
+AC_DEFUN_ONCE([HOTSPOT_VALIDATE_JVM_FEATURES],
+[
+  # Keep feature lists sorted and free of duplicates
+  JVM_FEATURES_server="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_server | $SORT -u))"
+  JVM_FEATURES_client="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_client | $SORT -u))"
+  JVM_FEATURES_core="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_core | $SORT -u))"
+  JVM_FEATURES_minimal="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_minimal | $SORT -u))"
+  JVM_FEATURES_zero="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_zero | $SORT -u))"
+  JVM_FEATURES_zeroshark="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_zeroshark | $SORT -u))"
+  JVM_FEATURES_custom="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_custom | $SORT -u))"
 
-  AC_SUBST(JVM_VARIANTS)
-  AC_SUBST(JVM_VARIANT_SERVER)
-  AC_SUBST(JVM_VARIANT_CLIENT)
-  AC_SUBST(JVM_VARIANT_MINIMAL1)
-  AC_SUBST(JVM_VARIANT_ZERO)
-  AC_SUBST(JVM_VARIANT_ZEROSHARK)
-  AC_SUBST(JVM_VARIANT_CORE)
+  # Validate features
+  for variant in $JVM_VARIANTS; do
+    AC_MSG_CHECKING([JVM features for JVM variant '$variant'])
+    features_var_name=JVM_FEATURES_$variant
+    JVM_FEATURES_TO_TEST=${!features_var_name}
+    AC_MSG_RESULT([$JVM_FEATURES_TO_TEST])
+    INVALID_FEATURES=`$GREP -Fvx "${VALID_JVM_FEATURES// /$'\n'}" <<< "${JVM_FEATURES_TO_TEST// /$'\n'}"`
+    if test "x$INVALID_FEATURES" != x; then
+      AC_MSG_ERROR([Invalid JVM feature(s): $INVALID_FEATURES])
+    fi
+  done
+])
+
+###############################################################################
+# Support for old hotspot build. Remove once new hotspot build has proven
+# to work satisfactory.
+#
+AC_DEFUN_ONCE([HOTSPOT_SETUP_LEGACY_BUILD],
+[
+  AC_ARG_ENABLE(new-hotspot-build, [AS_HELP_STRING([--disable-new-hotspot-build],
+      [disable the new hotspot build system (use the old) @<:@enabled@:>@])])
+
+   if test "x$enable_new_hotspot_build" = "x" || test "x$enable_new_hotspot_build" = "xyes"; then
+     USE_NEW_HOTSPOT_BUILD=true
+   else
+     USE_NEW_HOTSPOT_BUILD=false
+   fi
+  AC_SUBST(USE_NEW_HOTSPOT_BUILD)
+
+  case $HOTSPOT_DEBUG_LEVEL in
+    product )
+      VARIANT="OPT"
+      FASTDEBUG="false"
+      DEBUG_CLASSFILES="false"
+      ;;
+    fastdebug )
+      VARIANT="DBG"
+      FASTDEBUG="true"
+      DEBUG_CLASSFILES="true"
+      ;;
+    debug )
+      VARIANT="DBG"
+      FASTDEBUG="false"
+      DEBUG_CLASSFILES="true"
+      ;;
+    optimized )
+      VARIANT="OPT"
+      FASTDEBUG="false"
+      DEBUG_CLASSFILES="false"
+      ;;
+  esac
+  AC_SUBST(VARIANT)
+  AC_SUBST(FASTDEBUG)
+  AC_SUBST(DEBUG_CLASSFILES)
 
   if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then
     MACOSX_UNIVERSAL="true"
   fi
 
   AC_SUBST(MACOSX_UNIVERSAL)
-])
 
+  # Make sure JVM_VARIANTS_COMMA use minimal1 for backwards compatibility
+  JVM_VARIANTS_COMMA=`$ECHO ,$JVM_VARIANTS_OPT, | $SED -e 's/,minimal,/,minimal1,/'`
 
-###############################################################################
-# Setup legacy vars/targets and new vars to deal with different debug levels.
-#
-#    release: no debug information, all optimizations, no asserts.
-#    optimized: no debug information, all optimizations, no asserts, HotSpot target is 'optimized'.
-#    fastdebug: debug information (-g), all optimizations, all asserts
-#    slowdebug: debug information (-g), no optimizations, all asserts
-#
-AC_DEFUN_ONCE([HOTSPOT_SETUP_DEBUG_LEVEL],
-[
-  case $DEBUG_LEVEL in
-    release )
-      VARIANT="OPT"
-      FASTDEBUG="false"
-      DEBUG_CLASSFILES="false"
-      BUILD_VARIANT_RELEASE=""
-      HOTSPOT_DEBUG_LEVEL="product"
-      HOTSPOT_EXPORT="product"
-      ;;
-    fastdebug )
-      VARIANT="DBG"
-      FASTDEBUG="true"
-      DEBUG_CLASSFILES="true"
-      BUILD_VARIANT_RELEASE="-fastdebug"
-      HOTSPOT_DEBUG_LEVEL="fastdebug"
-      HOTSPOT_EXPORT="fastdebug"
-      ;;
-    slowdebug )
-      VARIANT="DBG"
-      FASTDEBUG="false"
-      DEBUG_CLASSFILES="true"
-      BUILD_VARIANT_RELEASE="-debug"
-      HOTSPOT_DEBUG_LEVEL="debug"
-      HOTSPOT_EXPORT="debug"
-      ;;
-    optimized )
-      VARIANT="OPT"
-      FASTDEBUG="false"
-      DEBUG_CLASSFILES="false"
-      BUILD_VARIANT_RELEASE="-optimized"
-      HOTSPOT_DEBUG_LEVEL="optimized"
-      HOTSPOT_EXPORT="optimized"
-      ;;
-  esac
-
-  # The debug level 'optimized' is a little special because it is currently only
-  # applicable to the HotSpot build where it means to build a completely
-  # optimized version of the VM without any debugging code (like for the
-  # 'release' debug level which is called 'product' in the HotSpot build) but
-  # with the exception that it can contain additional code which is otherwise
-  # protected by '#ifndef PRODUCT' macros. These 'optimized' builds are used to
-  # test new and/or experimental features which are not intended for customer
-  # shipment. Because these new features need to be tested and benchmarked in
-  # real world scenarios, we want to build the containing JDK at the 'release'
-  # debug level.
-  if test "x$DEBUG_LEVEL" = xoptimized; then
-    DEBUG_LEVEL="release"
-  fi
+  JVM_VARIANT_SERVER=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,server,/!s/.*/false/g' -e '/,server,/s/.*/true/g'`
+  JVM_VARIANT_CLIENT=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,client,/!s/.*/false/g' -e '/,client,/s/.*/true/g'`
+  JVM_VARIANT_MINIMAL1=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,minimal1\?,/!s/.*/false/g' -e '/,minimal1\?,/s/.*/true/g'`
+  JVM_VARIANT_CORE=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,core,/!s/.*/false/g' -e '/,core,/s/.*/true/g'`
+  JVM_VARIANT_ZERO=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,zero,/!s/.*/false/g' -e '/,zero,/s/.*/true/g'`
+  JVM_VARIANT_ZEROSHARK=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,zeroshark,/!s/.*/false/g' -e '/,zeroshark,/s/.*/true/g'`
+  JVM_VARIANT_CUSTOM=`$ECHO "$JVM_VARIANTS_COMMA" | $SED -e '/,custom,/!s/.*/false/g' -e '/,custom,/s/.*/true/g'`
 
   #####
   # Generate the legacy makefile targets for hotspot.
-  # The hotspot api for selecting the build artifacts, really, needs to be improved.
-  # JDK-7195896 will fix this on the hotspot side by using the JVM_VARIANT_* variables to
-  # determine what needs to be built. All we will need to set here is all_product, all_fastdebug etc
-  # But until then ...
   HOTSPOT_TARGET=""
 
   if test "x$JVM_VARIANT_SERVER" = xtrue; then
@@ -213,27 +387,19 @@
     HOTSPOT_TARGET="$HOTSPOT_TARGET${HOTSPOT_DEBUG_LEVEL}core "
   fi
 
-  HOTSPOT_TARGET="$HOTSPOT_TARGET docs export_$HOTSPOT_EXPORT"
+  HOTSPOT_TARGET="$HOTSPOT_TARGET docs export_$HOTSPOT_DEBUG_LEVEL"
 
   # On Macosx universal binaries are produced, but they only contain
   # 64 bit intel. This invalidates control of which jvms are built
   # from configure, but only server is valid anyway. Fix this
   # when hotspot makefiles are rewritten.
   if test "x$MACOSX_UNIVERSAL" = xtrue; then
-    HOTSPOT_TARGET=universal_${HOTSPOT_EXPORT}
+    HOTSPOT_TARGET=universal_${HOTSPOT_DEBUG_LEVEL}
   fi
 
-  #####
+  HOTSPOT_MAKE_ARGS="$HOTSPOT_TARGET"
+  AC_SUBST(HOTSPOT_MAKE_ARGS)
 
-  AC_SUBST(DEBUG_LEVEL)
-  AC_SUBST(VARIANT)
-  AC_SUBST(FASTDEBUG)
-  AC_SUBST(DEBUG_CLASSFILES)
-  AC_SUBST(BUILD_VARIANT_RELEASE)
-])
-
-AC_DEFUN_ONCE([HOTSPOT_SETUP_HOTSPOT_OPTIONS],
-[
   # Control wether Hotspot runs Queens test after build.
   AC_ARG_ENABLE([hotspot-test-in-build], [AS_HELP_STRING([--enable-hotspot-test-in-build],
       [run the Queens test after Hotspot build @<:@disabled@:>@])],,
@@ -244,10 +410,29 @@
     TEST_IN_BUILD=false
   fi
   AC_SUBST(TEST_IN_BUILD)
-])
 
-AC_DEFUN_ONCE([HOTSPOT_SETUP_BUILD_TWEAKS],
-[
-  HOTSPOT_MAKE_ARGS="$HOTSPOT_TARGET"
-  AC_SUBST(HOTSPOT_MAKE_ARGS)
+  if test "x$USE_NEW_HOTSPOT_BUILD" = xfalse; then
+    if test "x$JVM_VARIANT_CLIENT" = xtrue; then
+      if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+        AC_MSG_ERROR([You cannot build a client JVM for a 64-bit machine.])
+      fi
+    fi
+    if test "x$JVM_VARIANT_MINIMAL1" = xtrue; then
+      if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+        AC_MSG_ERROR([You cannot build a minimal JVM for a 64-bit machine.])
+      fi
+    fi
+    if test "x$JVM_VARIANT_CUSTOM" = xtrue; then
+        AC_MSG_ERROR([You cannot build a custom JVM using the old hotspot build system.])
+    fi
+  fi
+
+  AC_SUBST(JVM_VARIANTS_COMMA)
+  AC_SUBST(JVM_VARIANT_SERVER)
+  AC_SUBST(JVM_VARIANT_CLIENT)
+  AC_SUBST(JVM_VARIANT_MINIMAL1)
+  AC_SUBST(JVM_VARIANT_HOTSPOT)
+  AC_SUBST(JVM_VARIANT_ZERO)
+  AC_SUBST(JVM_VARIANT_ZEROSHARK)
+  AC_SUBST(JVM_VARIANT_CORE)
 ])
--- a/common/autoconf/jdk-options.m4	Fri Apr 29 04:44:08 2016 +0200
+++ b/common/autoconf/jdk-options.m4	Thu Apr 28 23:08:16 2016 -0700
@@ -81,6 +81,31 @@
       test "x$DEBUG_LEVEL" != xslowdebug; then
     AC_MSG_ERROR([Allowed debug levels are: release, fastdebug, slowdebug and optimized])
   fi
+
+  # Translate DEBUG_LEVEL to debug level used by Hotspot
+  HOTSPOT_DEBUG_LEVEL="$DEBUG_LEVEL"
+  if test "x$DEBUG_LEVEL" = xrelease; then
+    HOTSPOT_DEBUG_LEVEL="product"
+  elif test "x$DEBUG_LEVEL" = xslowdebug; then
+    HOTSPOT_DEBUG_LEVEL="debug"
+  fi
+
+  if test "x$DEBUG_LEVEL" = xoptimized; then
+    # The debug level 'optimized' is a little special because it is currently only
+    # applicable to the HotSpot build where it means to build a completely
+    # optimized version of the VM without any debugging code (like for the
+    # 'release' debug level which is called 'product' in the HotSpot build) but
+    # with the exception that it can contain additional code which is otherwise
+    # protected by '#ifndef PRODUCT' macros. These 'optimized' builds are used to
+    # test new and/or experimental features which are not intended for customer
+    # shipment. Because these new features need to be tested and benchmarked in
+    # real world scenarios, we want to build the containing JDK at the 'release'
+    # debug level.
+    DEBUG_LEVEL="release"
+  fi
+
+  AC_SUBST(HOTSPOT_DEBUG_LEVEL)
+  AC_SUBST(DEBUG_LEVEL)
 ])
 
 ###############################################################################
@@ -178,10 +203,7 @@
 
   # Should we build the serviceability agent (SA)?
   INCLUDE_SA=true
-  if test "x$JVM_VARIANT_ZERO" = xtrue ; then
-    INCLUDE_SA=false
-  fi
-  if test "x$JVM_VARIANT_ZEROSHARK" = xtrue ; then
+  if HOTSPOT_CHECK_JVM_VARIANT(zero) || HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
     INCLUDE_SA=false
   fi
   if test "x$OPENJDK_TARGET_OS" = xaix ; then
--- a/common/autoconf/jdk-version.m4	Fri Apr 29 04:44:08 2016 +0200
+++ b/common/autoconf/jdk-version.m4	Thu Apr 28 23:08:16 2016 -0700
@@ -72,6 +72,7 @@
   AC_SUBST(PRODUCT_SUFFIX)
   AC_SUBST(JDK_RC_PLATFORM_NAME)
   AC_SUBST(COMPANY_NAME)
+  AC_SUBST(HOTSPOT_VM_DISTRO)
   AC_SUBST(MACOSX_BUNDLE_NAME_BASE)
   AC_SUBST(MACOSX_BUNDLE_ID_BASE)
 
--- a/common/autoconf/lib-std.m4	Fri Apr 29 04:44:08 2016 +0200
+++ b/common/autoconf/lib-std.m4	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, 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
@@ -88,13 +88,25 @@
     # If dynamic was requested, it's available since it would fail above otherwise.
     # If dynamic wasn't requested, go with static unless it isn't available.
     AC_MSG_CHECKING([how to link with libstdc++])
-    if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno || test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then
+    if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno || HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
       LIBCXX="$LIBCXX -lstdc++"
+      # To help comparisons with old build, put stdc++ first in JVM_LIBS
+      JVM_LIBS="-lstdc++ $JVM_LIBS"
+      # Ideally, we should test stdc++ for the BUILD toolchain separately. For now
+      # just use the same setting as for the TARGET toolchain.
+      OPENJDK_BUILD_JVM_LIBS="-lstdc++ $OPENJDK_BUILD_JVM_LIBS"
       LDCXX="$CXX"
       STATIC_CXX_SETTING="STATIC_CXX=false"
       AC_MSG_RESULT([dynamic])
     else
       LIBCXX="$LIBCXX $STATIC_STDCXX_FLAGS"
+      JVM_LDFLAGS="$JVM_LDFLAGS -static-libgcc"
+      # To help comparisons with old build, put stdc++ first in JVM_LIBS
+      JVM_LIBS="-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic $JVM_LIBS"
+      # Ideally, we should test stdc++ for the BUILD toolchain separately. For now
+      # just use the same setting as for the TARGET toolchain.
+      OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -static-libgcc"
+      OPENJDK_BUILD_JVM_LIBS="-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic $OPENJDK_BUILD_JVM_LIBS"
       LDCXX="$CC"
       STATIC_CXX_SETTING="STATIC_CXX=true"
       AC_MSG_RESULT([static])
--- a/common/autoconf/libraries.m4	Fri Apr 29 04:44:08 2016 +0200
+++ b/common/autoconf/libraries.m4	Thu Apr 28 23:08:16 2016 -0700
@@ -74,7 +74,7 @@
   fi
 
   # Check if ffi is needed
-  if test "x$JVM_VARIANT_ZERO" = xtrue || test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then
+  if HOTSPOT_CHECK_JVM_VARIANT(zero) || HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
     NEEDS_LIB_FFI=true
   else
     NEEDS_LIB_FFI=false
@@ -102,7 +102,7 @@
 ################################################################################
 AC_DEFUN_ONCE([LIB_SETUP_LLVM],
 [
-  if test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then
+  if HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
     AC_CHECK_PROG([LLVM_CONFIG], [llvm-config], [llvm-config])
 
     if test "x$LLVM_CONFIG" != xllvm-config; then
--- a/common/autoconf/platform.m4	Fri Apr 29 04:44:08 2016 +0200
+++ b/common/autoconf/platform.m4	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, 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
@@ -274,168 +274,172 @@
 #
 AC_DEFUN([PLATFORM_SETUP_LEGACY_VARS],
 [
+  PLATFORM_SETUP_LEGACY_VARS_HELPER([TARGET])
+  PLATFORM_SETUP_LEGACY_VARS_HELPER([BUILD])
+
+  # ZERO_ARCHDEF is used to enable architecture-specific code.
+  # This is used in legacy hotspot build.
+  ZERO_ARCHDEF="$HOTSPOT_TARGET_CPU_DEFINE"
+  AC_SUBST(ZERO_ARCHDEF)
+
+])
+
+# $1 - Either TARGET or BUILD to setup the variables for.
+AC_DEFUN([PLATFORM_SETUP_LEGACY_VARS_HELPER],
+[
   # Also store the legacy naming of the cpu.
   # Ie i586 and amd64 instead of x86 and x86_64
-  OPENJDK_TARGET_CPU_LEGACY="$OPENJDK_TARGET_CPU"
-  if test "x$OPENJDK_TARGET_CPU" = xx86; then
-    OPENJDK_TARGET_CPU_LEGACY="i586"
-  elif test "x$OPENJDK_TARGET_OS" != xmacosx && test "x$OPENJDK_TARGET_CPU" = xx86_64; then
+  OPENJDK_$1_CPU_LEGACY="$OPENJDK_$1_CPU"
+  if test "x$OPENJDK_$1_CPU" = xx86; then
+    OPENJDK_$1_CPU_LEGACY="i586"
+  elif test "x$OPENJDK_$1_OS" != xmacosx && test "x$OPENJDK_$1_CPU" = xx86_64; then
     # On all platforms except MacOSX replace x86_64 with amd64.
-    OPENJDK_TARGET_CPU_LEGACY="amd64"
+    OPENJDK_$1_CPU_LEGACY="amd64"
   fi
-  AC_SUBST(OPENJDK_TARGET_CPU_LEGACY)
+  AC_SUBST(OPENJDK_$1_CPU_LEGACY)
 
   # And the second legacy naming of the cpu.
   # Ie i386 and amd64 instead of x86 and x86_64.
-  OPENJDK_TARGET_CPU_LEGACY_LIB="$OPENJDK_TARGET_CPU"
-  if test "x$OPENJDK_TARGET_CPU" = xx86; then
-    OPENJDK_TARGET_CPU_LEGACY_LIB="i386"
-  elif test "x$OPENJDK_TARGET_CPU" = xx86_64; then
-    OPENJDK_TARGET_CPU_LEGACY_LIB="amd64"
-  fi
-  AC_SUBST(OPENJDK_TARGET_CPU_LEGACY_LIB)
-
-  # This is the name of the cpu (but using i386 and amd64 instead of
-  # x86 and x86_64, respectively), preceeded by a /, to be used when
-  # locating libraries. On macosx, it's empty, though.
-  OPENJDK_TARGET_CPU_LIBDIR="/$OPENJDK_TARGET_CPU_LEGACY_LIB"
-  if test "x$OPENJDK_TARGET_OS" = xmacosx; then
-    OPENJDK_TARGET_CPU_LIBDIR=""
+  OPENJDK_$1_CPU_LEGACY_LIB="$OPENJDK_$1_CPU"
+  if test "x$OPENJDK_$1_CPU" = xx86; then
+    OPENJDK_$1_CPU_LEGACY_LIB="i386"
+  elif test "x$OPENJDK_$1_CPU" = xx86_64; then
+    OPENJDK_$1_CPU_LEGACY_LIB="amd64"
   fi
-  AC_SUBST(OPENJDK_TARGET_CPU_LIBDIR)
-
-  # Now do the same for OPENJDK_BUILD_CPU...
-  # Also store the legacy naming of the cpu.
-  # Ie i586 and amd64 instead of x86 and x86_64
-  OPENJDK_BUILD_CPU_LEGACY="$OPENJDK_BUILD_CPU"
-  if test "x$OPENJDK_BUILD_CPU" = xx86; then
-    OPENJDK_BUILD_CPU_LEGACY="i586"
-  elif test "x$OPENJDK_BUILD_OS" != xmacosx && test "x$OPENJDK_BUILD_CPU" = xx86_64; then
-    # On all platforms except MacOSX replace x86_64 with amd64.
-    OPENJDK_BUILD_CPU_LEGACY="amd64"
-  fi
-  AC_SUBST(OPENJDK_BUILD_CPU_LEGACY)
-
-  # And the second legacy naming of the cpu.
-  # Ie i386 and amd64 instead of x86 and x86_64.
-  OPENJDK_BUILD_CPU_LEGACY_LIB="$OPENJDK_BUILD_CPU"
-  if test "x$OPENJDK_BUILD_CPU" = xx86; then
-    OPENJDK_BUILD_CPU_LEGACY_LIB="i386"
-  elif test "x$OPENJDK_BUILD_CPU" = xx86_64; then
-    OPENJDK_BUILD_CPU_LEGACY_LIB="amd64"
-  fi
-  AC_SUBST(OPENJDK_BUILD_CPU_LEGACY_LIB)
+  AC_SUBST(OPENJDK_$1_CPU_LEGACY_LIB)
 
   # This is the name of the cpu (but using i386 and amd64 instead of
   # x86 and x86_64, respectively), preceeded by a /, to be used when
   # locating libraries. On macosx, it's empty, though.
-  OPENJDK_BUILD_CPU_LIBDIR="/$OPENJDK_BUILD_CPU_LEGACY_LIB"
-  if test "x$OPENJDK_BUILD_OS" = xmacosx; then
-    OPENJDK_BUILD_CPU_LIBDIR=""
+  OPENJDK_$1_CPU_LIBDIR="/$OPENJDK_$1_CPU_LEGACY_LIB"
+  if test "x$OPENJDK_$1_OS" = xmacosx; then
+    OPENJDK_$1_CPU_LIBDIR=""
   fi
-  AC_SUBST(OPENJDK_BUILD_CPU_LIBDIR)
+  AC_SUBST(OPENJDK_$1_CPU_LIBDIR)
 
-  # OPENJDK_TARGET_CPU_ISADIR is normally empty. On 64-bit Solaris systems, it is set to
+  # OPENJDK_$1_CPU_ISADIR is normally empty. On 64-bit Solaris systems, it is set to
   # /amd64 or /sparcv9. This string is appended to some library paths, like this:
-  # /usr/lib${OPENJDK_TARGET_CPU_ISADIR}/libexample.so
-  OPENJDK_TARGET_CPU_ISADIR=""
-  if test "x$OPENJDK_TARGET_OS" = xsolaris; then
-    if test "x$OPENJDK_TARGET_CPU" = xx86_64; then
-      OPENJDK_TARGET_CPU_ISADIR="/amd64"
-    elif test "x$OPENJDK_TARGET_CPU" = xsparcv9; then
-      OPENJDK_TARGET_CPU_ISADIR="/sparcv9"
+  # /usr/lib${OPENJDK_$1_CPU_ISADIR}/libexample.so
+  OPENJDK_$1_CPU_ISADIR=""
+  if test "x$OPENJDK_$1_OS" = xsolaris; then
+    if test "x$OPENJDK_$1_CPU" = xx86_64; then
+      OPENJDK_$1_CPU_ISADIR="/amd64"
+    elif test "x$OPENJDK_$1_CPU" = xsparcv9; then
+      OPENJDK_$1_CPU_ISADIR="/sparcv9"
     fi
   fi
-  AC_SUBST(OPENJDK_TARGET_CPU_ISADIR)
+  AC_SUBST(OPENJDK_$1_CPU_ISADIR)
 
-  # Setup OPENJDK_TARGET_CPU_OSARCH, which is used to set the os.arch Java system property
-  OPENJDK_TARGET_CPU_OSARCH="$OPENJDK_TARGET_CPU"
-  if test "x$OPENJDK_TARGET_OS" = xlinux && test "x$OPENJDK_TARGET_CPU" = xx86; then
+  # Setup OPENJDK_$1_CPU_OSARCH, which is used to set the os.arch Java system property
+  OPENJDK_$1_CPU_OSARCH="$OPENJDK_$1_CPU"
+  if test "x$OPENJDK_$1_OS" = xlinux && test "x$OPENJDK_$1_CPU" = xx86; then
     # On linux only, we replace x86 with i386.
-    OPENJDK_TARGET_CPU_OSARCH="i386"
-  elif test "x$OPENJDK_TARGET_OS" != xmacosx && test "x$OPENJDK_TARGET_CPU" = xx86_64; then
+    OPENJDK_$1_CPU_OSARCH="i386"
+  elif test "x$OPENJDK_$1_OS" != xmacosx && test "x$OPENJDK_$1_CPU" = xx86_64; then
     # On all platforms except macosx, we replace x86_64 with amd64.
-    OPENJDK_TARGET_CPU_OSARCH="amd64"
+    OPENJDK_$1_CPU_OSARCH="amd64"
   fi
-  AC_SUBST(OPENJDK_TARGET_CPU_OSARCH)
+  AC_SUBST(OPENJDK_$1_CPU_OSARCH)
 
-  OPENJDK_TARGET_CPU_JLI="$OPENJDK_TARGET_CPU"
-  if test "x$OPENJDK_TARGET_CPU" = xx86; then
-    OPENJDK_TARGET_CPU_JLI="i386"
-  elif test "x$OPENJDK_TARGET_OS" != xmacosx && test "x$OPENJDK_TARGET_CPU" = xx86_64; then
+  OPENJDK_$1_CPU_JLI="$OPENJDK_$1_CPU"
+  if test "x$OPENJDK_$1_CPU" = xx86; then
+    OPENJDK_$1_CPU_JLI="i386"
+  elif test "x$OPENJDK_$1_OS" != xmacosx && test "x$OPENJDK_$1_CPU" = xx86_64; then
     # On all platforms except macosx, we replace x86_64 with amd64.
-    OPENJDK_TARGET_CPU_JLI="amd64"
+    OPENJDK_$1_CPU_JLI="amd64"
   fi
   # Now setup the -D flags for building libjli.
-  OPENJDK_TARGET_CPU_JLI_CFLAGS="-DLIBARCHNAME='\"$OPENJDK_TARGET_CPU_JLI\"'"
-  if test "x$OPENJDK_TARGET_OS" = xsolaris; then
-    if test "x$OPENJDK_TARGET_CPU_ARCH" = xsparc; then
-      OPENJDK_TARGET_CPU_JLI_CFLAGS="$OPENJDK_TARGET_CPU_JLI_CFLAGS -DLIBARCH32NAME='\"sparc\"' -DLIBARCH64NAME='\"sparcv9\"'"
-    elif test "x$OPENJDK_TARGET_CPU_ARCH" = xx86; then
-      OPENJDK_TARGET_CPU_JLI_CFLAGS="$OPENJDK_TARGET_CPU_JLI_CFLAGS -DLIBARCH32NAME='\"i386\"' -DLIBARCH64NAME='\"amd64\"'"
+  OPENJDK_$1_CPU_JLI_CFLAGS="-DLIBARCHNAME='\"$OPENJDK_$1_CPU_JLI\"'"
+  if test "x$OPENJDK_$1_OS" = xsolaris; then
+    if test "x$OPENJDK_$1_CPU_ARCH" = xsparc; then
+      OPENJDK_$1_CPU_JLI_CFLAGS="$OPENJDK_$1_CPU_JLI_CFLAGS -DLIBARCH32NAME='\"sparc\"' -DLIBARCH64NAME='\"sparcv9\"'"
+    elif test "x$OPENJDK_$1_CPU_ARCH" = xx86; then
+      OPENJDK_$1_CPU_JLI_CFLAGS="$OPENJDK_$1_CPU_JLI_CFLAGS -DLIBARCH32NAME='\"i386\"' -DLIBARCH64NAME='\"amd64\"'"
     fi
   fi
-  AC_SUBST(OPENJDK_TARGET_CPU_JLI_CFLAGS)
+  AC_SUBST(OPENJDK_$1_CPU_JLI_CFLAGS)
 
-  OPENJDK_BUILD_CPU_JLI="$OPENJDK_BUILD_CPU"
-  if test "x$OPENJDK_BUILD_CPU" = xx86; then
-    OPENJDK_BUILD_CPU_JLI="i386"
-  elif test "x$OPENJDK_BUILD_OS" != xmacosx && test "x$OPENJDK_BUILD_CPU" = xx86_64; then
-    # On all platforms except macosx, we replace x86_64 with amd64.
-    OPENJDK_BUILD_CPU_JLI="amd64"
+  if test "x$OPENJDK_$1_OS" = xmacosx; then
+      OPENJDK_$1_OS_EXPORT_DIR=macosx
+  else
+      OPENJDK_$1_OS_EXPORT_DIR=${OPENJDK_$1_OS_TYPE}
   fi
-  # Now setup the -D flags for building libjli.
-  OPENJDK_BUILD_CPU_JLI_CFLAGS="-DLIBARCHNAME='\"$OPENJDK_BUILD_CPU_JLI\"'"
-  if test "x$OPENJDK_BUILD_OS" = xsolaris; then
-    if test "x$OPENJDK_BUILD_CPU_ARCH" = xsparc; then
-      OPENJDK_BUILD_CPU_JLI_CFLAGS="$OPENJDK_BUILD_CPU_JLI_CFLAGS -DLIBARCH32NAME='\"sparc\"' -DLIBARCH64NAME='\"sparcv9\"'"
-    elif test "x$OPENJDK_BUILD_CPU_ARCH" = xx86; then
-      OPENJDK_BUILD_CPU_JLI_CFLAGS="$OPENJDK_BUILD_CPU_JLI_CFLAGS -DLIBARCH32NAME='\"i386\"' -DLIBARCH64NAME='\"amd64\"'"
-    fi
-  fi
-  AC_SUBST(OPENJDK_BUILD_CPU_JLI_CFLAGS)
+  AC_SUBST(OPENJDK_$1_OS_EXPORT_DIR)
 
-  if test "x$OPENJDK_TARGET_OS" = xmacosx; then
-      OPENJDK_TARGET_OS_EXPORT_DIR=macosx
-  else
-      OPENJDK_TARGET_OS_EXPORT_DIR=${OPENJDK_TARGET_OS_TYPE}
-  fi
-  AC_SUBST(OPENJDK_TARGET_OS_EXPORT_DIR)
-
-  if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
+  if test "x$OPENJDK_$1_CPU_BITS" = x64; then
     A_LP64="LP64:="
     # -D_LP64=1 is only set on linux and mac. Setting on windows causes diff in
     # unpack200.exe
-    if test "x$OPENJDK_TARGET_OS" = xlinux || test "x$OPENJDK_TARGET_OS" = xmacosx; then
-      ADD_LP64="-D_LP64=1"
+    if test "x$OPENJDK_$1_OS" = xlinux || test "x$OPENJDK_$1_OS" = xmacosx; then
+      OPENJDK_$1_ADD_LP64="-D_LP64=1"
     fi
   fi
   AC_SUBST(LP64,$A_LP64)
-  if test "x$OPENJDK_BUILD_CPU_BITS" = x64; then
-    if test "x$OPENJDK_BUILD_OS" = xlinux || test "x$OPENJDK_BUILD_OS" = xmacosx; then
-      OPENJDK_BUILD_ADD_LP64="-D_LP64=1"
-    fi
-  fi
 
   if test "x$COMPILE_TYPE" = "xcross"; then
     # FIXME: ... or should this include reduced builds..?
-    DEFINE_CROSS_COMPILE_ARCH="CROSS_COMPILE_ARCH:=$OPENJDK_TARGET_CPU_LEGACY"
+    DEFINE_CROSS_COMPILE_ARCH="CROSS_COMPILE_ARCH:=$OPENJDK_$1_CPU_LEGACY"
   else
     DEFINE_CROSS_COMPILE_ARCH=""
   fi
   AC_SUBST(DEFINE_CROSS_COMPILE_ARCH)
 
-  # ZERO_ARCHDEF is used to enable architecture-specific code
-  case "${OPENJDK_TARGET_CPU}" in
-    ppc)     ZERO_ARCHDEF=PPC32 ;;
-    ppc64)   ZERO_ARCHDEF=PPC64 ;;
-    s390*)   ZERO_ARCHDEF=S390  ;;
-    sparc*)  ZERO_ARCHDEF=SPARC ;;
-    x86_64*) ZERO_ARCHDEF=AMD64 ;;
-    x86)     ZERO_ARCHDEF=IA32  ;;
-    *)      ZERO_ARCHDEF=$(echo "${OPENJDK_TARGET_CPU_LEGACY_LIB}" | tr a-z A-Z)
-  esac
-  AC_SUBST(ZERO_ARCHDEF)
+  # Convert openjdk platform names to hotspot names
+
+  HOTSPOT_$1_OS=${OPENJDK_$1_OS}
+  if test "x$OPENJDK_$1_OS" = xmacosx; then
+    HOTSPOT_$1_OS=bsd
+  fi
+  AC_SUBST(HOTSPOT_$1_OS)
+
+  HOTSPOT_$1_OS_TYPE=${OPENJDK_$1_OS_TYPE}
+  if test "x$OPENJDK_$1_OS_TYPE" = xunix; then
+    HOTSPOT_$1_OS_TYPE=posix
+  fi
+  AC_SUBST(HOTSPOT_$1_OS_TYPE)
+
+  HOTSPOT_$1_CPU=${OPENJDK_$1_CPU}
+  if test "x$OPENJDK_$1_CPU" = xx86; then
+    HOTSPOT_$1_CPU=x86_32
+  elif test "x$OPENJDK_$1_CPU" = xsparcv9; then
+    HOTSPOT_$1_CPU=sparc
+  elif test "x$OPENJDK_$1_CPU" = xppc64; then
+    HOTSPOT_$1_CPU=ppc_64
+  elif test "x$OPENJDK_$1_CPU" = xppc64le; then
+    HOTSPOT_$1_CPU=ppc_64
+  fi
+  AC_SUBST(HOTSPOT_$1_CPU)
+
+  # This is identical with OPENJDK_*, but define anyway for consistency.
+  HOTSPOT_$1_CPU_ARCH=${OPENJDK_$1_CPU_ARCH}
+  AC_SUBST(HOTSPOT_$1_CPU_ARCH)
+
+  # Setup HOTSPOT_$1_CPU_DEFINE
+  if test "x$OPENJDK_$1_CPU" = xx86; then
+    HOTSPOT_$1_CPU_DEFINE=IA32
+  elif test "x$OPENJDK_$1_CPU" = xx86_64; then
+    HOTSPOT_$1_CPU_DEFINE=AMD64
+  elif test "x$OPENJDK_$1_CPU" = xsparcv9; then
+    HOTSPOT_$1_CPU_DEFINE=SPARC
+  elif test "x$OPENJDK_$1_CPU" = xaarch64; then
+    HOTSPOT_$1_CPU_DEFINE=AARCH64
+  elif test "x$OPENJDK_$1_CPU" = xppc64; then
+    HOTSPOT_$1_CPU_DEFINE=PPC64
+  elif test "x$OPENJDK_$1_CPU" = xppc64le; then
+    HOTSPOT_$1_CPU_DEFINE=PPC64
+
+  # The cpu defines below are for zero, we don't support them directly.
+  elif test "x$OPENJDK_$1_CPU" = xsparc; then
+    HOTSPOT_$1_CPU_DEFINE=SPARC
+  elif test "x$OPENJDK_$1_CPU" = xppc; then
+    HOTSPOT_$1_CPU_DEFINE=PPC32
+  elif test "x$OPENJDK_$1_CPU" = xs390; then
+    HOTSPOT_$1_CPU_DEFINE=S390
+  elif test "x$OPENJDK_$1_CPU" = xs390x; then
+    HOTSPOT_$1_CPU_DEFINE=S390
+  fi
+  AC_SUBST(HOTSPOT_$1_CPU_DEFINE)
+
 ])
 
 AC_DEFUN([PLATFORM_SET_RELEASE_FILE_OS_VALUES],
@@ -521,6 +525,10 @@
   CFLAGS_JDK="${CFLAGS_JDK}${ADDED_CFLAGS}"
   CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}"
   LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}"
+
+  JVM_CFLAGS="$JVM_CFLAGS $ADDED_CFLAGS"
+  JVM_LDFLAGS="$JVM_LDFLAGS $ADDED_LDFLAGS"
+  JVM_ASFLAGS="$JVM_ASFLAGS $ADDED_CFLAGS"
 ])
 
 AC_DEFUN_ONCE([PLATFORM_SETUP_OPENJDK_TARGET_BITS],
@@ -542,6 +550,11 @@
       PLATFORM_SET_COMPILER_TARGET_BITS_FLAGS
     fi
   fi
+  if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+    JVM_CFLAGS="$JVM_CFLAGS ${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}"
+    JVM_LDFLAGS="$JVM_LDFLAGS ${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}"
+    JVM_ASFLAGS="$JVM_ASFLAGS ${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}"
+  fi
 
   # Make compilation sanity check
   AC_CHECK_HEADERS([stdio.h], , [
--- a/common/autoconf/spec.gmk.in	Fri Apr 29 04:44:08 2016 +0200
+++ b/common/autoconf/spec.gmk.in	Thu Apr 28 23:08:16 2016 -0700
@@ -82,6 +82,13 @@
 OPENJDK_TARGET_CPU_JLI_CFLAGS:=@OPENJDK_TARGET_CPU_JLI_CFLAGS@
 OPENJDK_TARGET_OS_EXPORT_DIR:=@OPENJDK_TARGET_OS_EXPORT_DIR@
 
+HOTSPOT_TARGET_OS := @HOTSPOT_TARGET_OS@
+HOTSPOT_TARGET_OS_TYPE := @HOTSPOT_TARGET_OS_TYPE@
+
+HOTSPOT_TARGET_CPU := @HOTSPOT_TARGET_CPU@
+HOTSPOT_TARGET_CPU_ARCH := @HOTSPOT_TARGET_CPU_ARCH@
+HOTSPOT_TARGET_CPU_DEFINE := @HOTSPOT_TARGET_CPU_DEFINE@
+
 # We are building on this build system.
 # When not cross-compiling, it is the same as the target.
 OPENJDK_BUILD_OS:=@OPENJDK_BUILD_OS@
@@ -192,6 +199,7 @@
 PRODUCT_SUFFIX:=@PRODUCT_SUFFIX@
 JDK_RC_PLATFORM_NAME:=@JDK_RC_PLATFORM_NAME@
 COMPANY_NAME:=@COMPANY_NAME@
+HOTSPOT_VM_DISTRO:=@HOTSPOT_VM_DISTRO@
 MACOSX_BUNDLE_NAME_BASE=@MACOSX_BUNDLE_NAME_BASE@
 MACOSX_BUNDLE_ID_BASE=@MACOSX_BUNDLE_ID_BASE@
 USERNAME:=@USERNAME@
@@ -201,11 +209,32 @@
 
 # How to compile the code: release, fastdebug or slowdebug
 DEBUG_LEVEL:=@DEBUG_LEVEL@
+HOTSPOT_DEBUG_LEVEL:=@HOTSPOT_DEBUG_LEVEL@
 
 # This is the JDK variant to build.
 # The JDK variant is a name for a specific set of modules to be compiled for the JDK.
 JDK_VARIANT:=@JDK_VARIANT@
 
+# Which JVM variants to build (space-separated list)
+JVM_VARIANTS := @JVM_VARIANTS@
+
+# Lists of features per variant. Only relevant for the variants listed in
+# JVM_VARIANTS.
+JVM_FEATURES_server := @JVM_FEATURES_server@
+JVM_FEATURES_client := @JVM_FEATURES_client@
+JVM_FEATURES_core := @JVM_FEATURES_core@
+JVM_FEATURES_minimal := @JVM_FEATURES_minimal@
+JVM_FEATURES_zero := @JVM_FEATURES_zero@
+JVM_FEATURES_zeroshark := @JVM_FEATURES_zeroshark@
+JVM_FEATURES_custom := @JVM_FEATURES_custom@
+
+# Used for make-time verifications
+VALID_JVM_FEATURES := @VALID_JVM_FEATURES@
+VALID_JVM_VARIANTS := @VALID_JVM_VARIANTS@
+
+# Control use of precompiled header in hotspot libjvm build
+USE_PRECOMPILED_HEADER := @USE_PRECOMPILED_HEADER@
+
 # Should we compile support for running with a graphical UI? (ie headful)
 # Should we compile support for running without? (ie headless)
 SUPPORT_HEADFUL:=@SUPPORT_HEADFUL@
@@ -213,25 +242,11 @@
 # Legacy defines controlled by the SUPPORT_HEADLESS and SUPPORT_HEADFUL options.
 @BUILD_HEADLESS@
 
-# These are the libjvms that we want to build.
-# The java launcher uses the default.
-# The others can be selected by specifying -client -server -minimal1 -zero or -zeroshark
-# on the java launcher command line.
-JVM_VARIANTS:=@JVM_VARIANTS@
-JVM_VARIANT_SERVER:=@JVM_VARIANT_SERVER@
-JVM_VARIANT_CLIENT:=@JVM_VARIANT_CLIENT@
-JVM_VARIANT_MINIMAL1:=@JVM_VARIANT_MINIMAL1@
-JVM_VARIANT_ZERO:=@JVM_VARIANT_ZERO@
-JVM_VARIANT_ZEROSHARK:=@JVM_VARIANT_ZEROSHARK@
-JVM_VARIANT_CORE:=@JVM_VARIANT_CORE@
+# Legacy support
+USE_NEW_HOTSPOT_BUILD:=@USE_NEW_HOTSPOT_BUILD@
 
-# Universal binaries on macosx
 MACOSX_UNIVERSAL=@MACOSX_UNIVERSAL@
 
-# Legacy setting: -debug or -fastdebug
-# Still used in version string...
-BUILD_VARIANT_RELEASE:=@BUILD_VARIANT_RELEASE@
-
 # JDK_OUTPUTDIR specifies where a working jvm is built.
 # You can run $(JDK_OUTPUTDIR)/bin/java
 # Though the layout of the contents of $(JDK_OUTPUTDIR) is not
@@ -320,6 +335,11 @@
 # Toolchain type: gcc, clang, solstudio, lxc, microsoft...
 TOOLCHAIN_TYPE:=@TOOLCHAIN_TYPE@
 TOOLCHAIN_VERSION := @TOOLCHAIN_VERSION@
+CC_VERSION_NUMBER := @CC_VERSION_NUMBER@
+CXX_VERSION_NUMBER := @CXX_VERSION_NUMBER@
+
+# Legacy support
+HOTSPOT_TOOLCHAIN_TYPE := @HOTSPOT_TOOLCHAIN_TYPE@
 
 # Option used to tell the compiler whether to create 32- or 64-bit executables
 COMPILER_TARGET_BITS_FLAG:=@COMPILER_TARGET_BITS_FLAG@
@@ -338,14 +358,18 @@
 AR_OUT_OPTION:=@AR_OUT_OPTION@
 
 # Flags used for overriding the default opt setting for a C/C++ source file.
+C_O_FLAG_HIGHEST_JVM:=@C_O_FLAG_HIGHEST_JVM@
 C_O_FLAG_HIGHEST:=@C_O_FLAG_HIGHEST@
 C_O_FLAG_HI:=@C_O_FLAG_HI@
 C_O_FLAG_NORM:=@C_O_FLAG_NORM@
 C_O_FLAG_NONE:=@C_O_FLAG_NONE@
+C_O_FLAG_SIZE:=@C_O_FLAG_SIZE@
+CXX_O_FLAG_HIGHEST_JVM:=@CXX_O_FLAG_HIGHEST_JVM@
 CXX_O_FLAG_HIGHEST:=@CXX_O_FLAG_HIGHEST@
 CXX_O_FLAG_HI:=@CXX_O_FLAG_HI@
 CXX_O_FLAG_NORM:=@CXX_O_FLAG_NORM@
 CXX_O_FLAG_NONE:=@CXX_O_FLAG_NONE@
+CXX_O_FLAG_SIZE:=@CXX_O_FLAG_SIZE@
 
 C_FLAG_DEPS:=@C_FLAG_DEPS@
 CXX_FLAG_DEPS:=@CXX_FLAG_DEPS@
@@ -374,6 +398,23 @@
 
 LDFLAGS_HASH_STYLE := @LDFLAGS_HASH_STYLE@
 
+JVM_CFLAGS := @JVM_CFLAGS@
+JVM_CFLAGS_SYMBOLS := @JVM_CFLAGS_SYMBOLS@
+JVM_LDFLAGS := @JVM_LDFLAGS@
+JVM_ASFLAGS := @JVM_ASFLAGS@
+JVM_LIBS := @JVM_LIBS@
+JVM_RCFLAGS := @JVM_RCFLAGS@
+
+# Flags for zeroshark
+LLVM_CFLAGS := @LLVM_CFLAGS@
+LLVM_LIBS := @LLVM_LIBS@
+LLVM_LDFLAGS := @LLVM_LDFLAGS@
+
+# These flags might contain variables set by a custom extension that is included later.
+EXTRA_CFLAGS = @EXTRA_CFLAGS@
+EXTRA_CXXFLAGS = @EXTRA_CXXFLAGS@
+EXTRA_LDFLAGS = @EXTRA_LDFLAGS@
+
 CXX:=@FIXPATH@ @CCACHE@ @ICECC@ @CXX@
 
 CPP:=@FIXPATH@ @CPP@
@@ -630,6 +671,7 @@
 JT_HOME:=@JT_HOME@
 JTREGEXE:=@JTREGEXE@
 XCODEBUILD=@XCODEBUILD@
+DTRACE := @DTRACE@
 FIXPATH:=@FIXPATH@
 
 # Build setup
--- a/common/autoconf/toolchain.m4	Fri Apr 29 04:44:08 2016 +0200
+++ b/common/autoconf/toolchain.m4	Thu Apr 28 23:08:16 2016 -0700
@@ -930,6 +930,17 @@
     rm -rf version-script.map main.c a.out
   fi
   AC_SUBST(USING_BROKEN_SUSE_LD)
+
+  # Setup hotspot lecagy names for toolchains
+  HOTSPOT_TOOLCHAIN_TYPE=$TOOLCHAIN_TYPE
+  if test "x$TOOLCHAIN_TYPE" = xclang; then
+    HOTSPOT_TOOLCHAIN_TYPE=gcc
+  elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+    HOTSPOT_TOOLCHAIN_TYPE=sparcWorks
+  elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+    HOTSPOT_TOOLCHAIN_TYPE=visCPP
+  fi
+  AC_SUBST(HOTSPOT_TOOLCHAIN_TYPE)
 ])
 
 # Setup the JTReg Regression Test Harness.
--- a/common/autoconf/version-numbers	Fri Apr 29 04:44:08 2016 +0200
+++ b/common/autoconf/version-numbers	Thu Apr 28 23:08:16 2016 -0700
@@ -32,6 +32,7 @@
 PRODUCT_SUFFIX="Runtime Environment"
 JDK_RC_PLATFORM_NAME=Platform
 COMPANY_NAME=N/A
+HOTSPOT_VM_DISTRO="OpenJDK"
 
 # Might need better names for these
 MACOSX_BUNDLE_NAME_BASE="OpenJDK"
--- a/common/conf/jib-profiles.js	Fri Apr 29 04:44:08 2016 +0200
+++ b/common/conf/jib-profiles.js	Thu Apr 28 23:08:16 2016 -0700
@@ -212,14 +212,17 @@
  * @returns Common values
  */
 var getJibProfilesCommon = function (input) {
-    var common = {
-        dependencies: ["boot_jdk", "gnumake", "jtreg"],
-        configure_args: ["--with-default-make-target=all", "--enable-jtreg-failure-handler"],
-        configure_args_32bit: ["--with-target-bits=32", "--with-jvm-variants=client,server"],
-        configure_args_debug: ["--enable-debug"],
-        configure_args_slowdebug: ["--with-debug-level=slowdebug"],
-        organization: "jpg.infra.builddeps"
-    };
+    var common = {};
+
+    common.dependencies = ["boot_jdk", "gnumake", "jtreg"],
+    common.default_make_targets = ["product-images", "test-image"],
+    common.default_make_targets_debug = common.default_make_targets;
+    common.default_make_targets_slowdebug = common.default_make_targets;
+    common.configure_args = ["--enable-jtreg-failure-handler"],
+    common.configure_args_32bit = ["--with-target-bits=32", "--with-jvm-variants=client,server"],
+    common.configure_args_debug = ["--enable-debug"],
+    common.configure_args_slowdebug = ["--with-debug-level=slowdebug"],
+    common.organization = "jpg.infra.builddeps"
 
     return common;
 };
@@ -242,7 +245,7 @@
             target_cpu: "x64",
             dependencies: concat(common.dependencies, "devkit"),
             configure_args: concat(common.configure_args, "--with-zlib=system"),
-            make_args: common.make_args
+            default_make_targets: concat(common.default_make_targets, "docs-image")
         },
 
         "linux-x86": {
@@ -252,7 +255,7 @@
             dependencies: concat(common.dependencies, "devkit"),
             configure_args: concat(common.configure_args, common.configure_args_32bit,
                 "--with-zlib=system"),
-            make_args: common.make_args
+            default_make_targets: common.default_make_targets
         },
 
         "macosx-x64": {
@@ -260,7 +263,7 @@
             target_cpu: "x64",
             dependencies: concat(common.dependencies, "devkit"),
             configure_args: concat(common.configure_args, "--with-zlib=system"),
-            make_args: common.make_args
+            default_make_targets: common.default_make_targets
         },
 
         "solaris-x64": {
@@ -268,7 +271,7 @@
             target_cpu: "x64",
             dependencies: concat(common.dependencies, "devkit", "cups"),
             configure_args: concat(common.configure_args, "--with-zlib=system"),
-            make_args: common.make_args
+            default_make_targets: common.default_make_targets
         },
 
         "solaris-sparcv9": {
@@ -276,15 +279,15 @@
             target_cpu: "sparcv9",
             dependencies: concat(common.dependencies, "devkit", "cups"),
             configure_args: concat(common.configure_args, "--with-zlib=system"),
-            make_args: common.make_args
+            default_make_targets: common.default_make_targets
         },
 
         "windows-x64": {
             target_os: "windows",
             target_cpu: "x64",
             dependencies: concat(common.dependencies, "devkit", "freetype"),
-            configure_args: common.configure_args,
-            make_args: common.make_args
+            configure_args: concat(common.configure_args),
+            default_make_targets: common.default_make_targets
         },
 
         "windows-x86": {
@@ -293,7 +296,7 @@
             build_cpu: "x64",
             dependencies: concat(common.dependencies, "devkit", "freetype"),
             configure_args: concat(common.configure_args, common.configure_args_32bit),
-            make_args: common.make_args
+            default_make_targets: common.default_make_targets
         }
     };
     profiles = concatObjects(profiles, mainProfiles);
@@ -306,14 +309,15 @@
     // implementation builds.
     var openOnlyProfiles = generateOpenOnlyProfiles(common, mainProfiles);
     // The open only profiles on linux are used for reference builds and should
-    // produce the compact profile images by default.
+    // produce the compact profile images by default. This adds "profiles" as an
+    // extra default target.
     var openOnlyProfilesExtra = {
         "linux-x64-open": {
-            configure_args: ["--with-default-make-target=all profiles"],
+            default_make_targets: "profiles"
         },
 
         "linux-x86-open": {
-            configure_args: ["--with-default-make-target=all profiles"],
+            default_make_targets: "profiles"
         }
     };
     var openOnlyProfiles = concatObjects(openOnlyProfiles, openOnlyProfilesExtra);
@@ -336,6 +340,7 @@
 
     // Generate the missing platform attributes
     profiles = generatePlatformAttributes(profiles);
+    profiles = generateDefaultMakeTargetsConfigureArg(common, profiles);
     return profiles;
 };
 
@@ -469,6 +474,8 @@
         var debugProfile = profile + "-debug";
         newProfiles[debugProfile] = clone(profiles[profile]);
         newProfiles[debugProfile].debug_level = "fastdebug";
+        newProfiles[debugProfile].default_make_targets
+            = common.default_make_targets_debug;
         newProfiles[debugProfile].labels
             = concat(newProfiles[debugProfile].labels || [], "debug"),
             newProfiles[debugProfile].configure_args
@@ -492,6 +499,8 @@
         var debugProfile = profile + "-slowdebug";
         newProfiles[debugProfile] = clone(profiles[profile]);
         newProfiles[debugProfile].debug_level = "slowdebug";
+        newProfiles[debugProfile].default_make_targets
+            = common.default_make_targets_slowdebug;
         newProfiles[debugProfile].labels
             = concat(newProfiles[debugProfile].labels || [], "slowdebug"),
             newProfiles[debugProfile].configure_args
@@ -524,6 +533,39 @@
 };
 
 /**
+ * The default_make_targets attribute on a profile is not a real Jib attribute.
+ * This function rewrites that attribute into the corresponding configure arg.
+ * Calling this function multiple times on the same profiles object is safe.
+ *
+ * @param common Common values
+ * @param profiles Profiles map to rewrite profiles for
+ * @returns {{}} New map of profiles with the make targets converted
+ */
+var generateDefaultMakeTargetsConfigureArg = function (common, profiles) {
+    var ret = concatObjects(profiles, {});
+    for (var profile in ret) {
+        if (ret[profile]["default_make_targets"] != null) {
+            var targetsString = concat(ret[profile].default_make_targets).join(" ");
+            // Iterate over all configure args and see if --with-default-make-target
+            // is already there and change it, otherwise add it.
+            var found = false;
+            for (var arg in ret[profile].configure_args) {
+                if (arg.startsWith("--with-default-make-target")) {
+                    found = true;
+                    arg.replace(/=.*/, "=" + targetsString);
+                }
+            }
+            if (!found) {
+                ret[profile].configure_args = concat(
+                    ret[profile].configure_args,
+                    "--with-default-make-target=" + targetsString);
+            }
+        }
+    }
+    return ret;
+}
+
+/**
  * Deep clones an object tree.
  *
  * @param o Object to clone
--- a/corba/.hgtags	Fri Apr 29 04:44:08 2016 +0200
+++ b/corba/.hgtags	Thu Apr 28 23:08:16 2016 -0700
@@ -357,3 +357,5 @@
 780d0620add32bf545471cf65038c9ac6d9c036d jdk-9+112
 cc30faa2da498c478e89ab062ff160653ca1b170 jdk-9+113
 10d175b0368c30f54350fc648adc41b94ce357ee jdk-9+114
+7bab1b1b36824924b1c657a8419369ba93d198d3 jdk-9+115
+7dfa7377a5e601b8f740741a9a80e04c72dd04d6 jdk-9+116
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/corba/RequestImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/corba/RequestImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -255,7 +255,7 @@
     public synchronized void send_deferred()
     {
         AsynchInvoke invokeObject = new AsynchInvoke(_orb, this, false);
-        new sun.misc.ManagedLocalsThread(invokeObject).start();
+        new Thread(null, invokeObject, "Async-Request-Invoker-Thread", 0, false).start();
     }
 
     public synchronized boolean poll_response()
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/javax/rmi/CORBA/Util.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/javax/rmi/CORBA/Util.java	Thu Apr 28 23:08:16 2016 -0700
@@ -751,12 +751,13 @@
     }
 }
 
-class KeepAlive extends sun.misc.ManagedLocalsThread
+class KeepAlive extends Thread
 {
     boolean quit = false;
 
     public KeepAlive ()
     {
+        super(null, null, "Servant-KeepAlive-Thread", 0, false);
         setDaemon(false);
     }
 
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/oa/poa/POAImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/oa/poa/POAImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -516,7 +516,7 @@
 
     // Converted from anonymous class to local class
     // so that we can call performDestroy() directly.
-    static class DestroyThread extends sun.misc.ManagedLocalsThread {
+    static class DestroyThread extends Thread {
         private boolean wait ;
         private boolean etherealize ;
         private boolean debug ;
@@ -524,6 +524,7 @@
 
         public DestroyThread( boolean etherealize, boolean debug )
         {
+            super(null, null, "POA-Destroy-Thread", 0, false);
             this.etherealize = etherealize ;
             this.debug = debug ;
         }
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/oa/poa/POAManagerImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/oa/poa/POAManagerImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -357,7 +357,7 @@
             if (wait_for_completion)
                 deactivator.run() ;
             else {
-                Thread thr = new sun.misc.ManagedLocalsThread(deactivator) ;
+                Thread thr = new Thread(null, deactivator, "POA-Deactivator-Thread", 0, false) ;
                 thr.start() ;
             }
         } finally {
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/oa/poa/POAPolicyMediatorImpl_R_USM.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/oa/poa/POAPolicyMediatorImpl_R_USM.java	Thu Apr 28 23:08:16 2016 -0700
@@ -302,7 +302,7 @@
         throw new WrongPolicy();
     }
 
-    class Etherealizer extends sun.misc.ManagedLocalsThread {
+    class Etherealizer extends Thread {
         private POAPolicyMediatorImpl_R_USM mediator ;
         private ActiveObjectMap.Key key ;
         private AOMEntry entry ;
@@ -314,6 +314,7 @@
             ActiveObjectMap.Key key, AOMEntry entry, Servant servant,
             boolean debug )
         {
+            super(null, null, "PAO-Etherealizer-Thread", 0, false);
             this.mediator = mediator ;
             this.key = key ;
             this.entry = entry;
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -691,7 +691,7 @@
         for (int i = 0; i < req.length; i++) {
             AsynchInvoke invokeObject = new AsynchInvoke( this,
                 (com.sun.corba.se.impl.corba.RequestImpl)req[i], true);
-            new sun.misc.ManagedLocalsThread(invokeObject).start();
+            new Thread(null, invokeObject, "ORB-Request-Thread", 0, false).start();
         }
     }
 
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/orbutil/threadpool/ThreadPoolImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/orbutil/threadpool/ThreadPoolImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -459,7 +459,7 @@
     }
 
 
-    private class WorkerThread extends sun.misc.ManagedLocalsThread implements Closeable
+    private class WorkerThread extends Thread implements Closeable
     {
         private Work currentWork;
         private int threadId = 0; // unique id for the thread
@@ -469,7 +469,7 @@
         private StringBuffer workerThreadName = new StringBuffer();
 
         WorkerThread(ThreadGroup tg, String threadPoolName) {
-            super(tg, "Idle");
+            super(tg, null, "Idle", 0, false);
             this.threadId = ThreadPoolImpl.getUniqueThreadId();
             this.threadPoolName = threadPoolName;
             setName(composeWorkerThreadName(threadPoolName, "Idle"));
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/transport/SelectorImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/transport/SelectorImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -61,7 +61,7 @@
  */
 class SelectorImpl
     extends
-        sun.misc.ManagedLocalsThread
+        Thread
     implements
         com.sun.corba.se.pept.transport.Selector
 {
@@ -79,6 +79,7 @@
 
     public SelectorImpl(ORB orb)
     {
+        super(null, null, "ORB-Selector-Thread", 0, false);
         this.orb = orb;
         selector = null;
         selectorStarted = false;
@@ -277,7 +278,6 @@
 
     public void run()
     {
-        setName("SelectorThread");
         while (!closed) {
             try {
                 int n = 0;
--- a/corba/src/java.corba/share/classes/module-info.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/corba/src/java.corba/share/classes/module-info.java	Thu Apr 28 23:08:16 2016 -0700
@@ -29,8 +29,6 @@
     requires java.logging;
     requires java.naming;
     requires java.transaction;
-    // 8148863
-    requires jdk.unsupported;
 
     exports javax.activity;
     exports javax.rmi;
--- a/hotspot/.hgtags	Fri Apr 29 04:44:08 2016 +0200
+++ b/hotspot/.hgtags	Thu Apr 28 23:08:16 2016 -0700
@@ -518,3 +518,4 @@
 c569f8d89269fb6205b90f727581eb8cc04132f9 jdk-9+113
 b64432bae5271735fd53300b2005b713e98ef411 jdk-9+114
 88dd08d7be0fe7fb9f1914b1628f0aae9bf56e25 jdk-9+115
+61a214186dae6811dd989e9165e42f7dbf02acde jdk-9+116
--- a/hotspot/src/cpu/ppc/vm/c1_LIRGenerator_ppc.cpp	Fri Apr 29 04:44:08 2016 +0200
+++ b/hotspot/src/cpu/ppc/vm/c1_LIRGenerator_ppc.cpp	Thu Apr 28 23:08:16 2016 -0700
@@ -360,7 +360,7 @@
     length.set_instruction(x->length());
     length.load_item();
   }
-  if (needs_store_check) {
+  if (needs_store_check || x->check_boolean()) {
     value.load_item();
   } else {
     value.load_for_store(x->elt_type());
@@ -407,7 +407,8 @@
     pre_barrier(LIR_OprFact::address(array_addr), LIR_OprFact::illegalOpr /* pre_val */,
                 true /* do_load */, false /* patch */, NULL);
   }
-  __ move(value.result(), array_addr, null_check_info);
+  LIR_Opr result = maybe_mask_boolean(x, array.result(), value.result(), null_check_info);
+  __ move(result, array_addr, null_check_info);
   if (obj_store) {
     // Precise card mark.
     post_barrier(LIR_OprFact::address(array_addr), value.result());
--- a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp	Fri Apr 29 04:44:08 2016 +0200
+++ b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp	Thu Apr 28 23:08:16 2016 -0700
@@ -169,6 +169,7 @@
     case ltos: ld(R17_tos, in_bytes(JvmtiThreadState::earlyret_value_offset()), RjvmtiState);
                break;
     case btos: // fall through
+    case ztos: // fall through
     case ctos: // fall through
     case stos: // fall through
     case itos: lwz(R17_tos, in_bytes(JvmtiThreadState::earlyret_value_offset()), RjvmtiState);
@@ -294,6 +295,7 @@
   switch (state) {
     case atos: push_ptr();                break;
     case btos:
+    case ztos:
     case ctos:
     case stos:
     case itos: push_i();                  break;
@@ -309,6 +311,7 @@
   switch (state) {
     case atos: pop_ptr();            break;
     case btos:
+    case ztos:
     case ctos:
     case stos:
     case itos: pop_i();              break;
@@ -749,6 +752,43 @@
   stdux(Rscratch2, R1_SP, Rscratch1); // atomically set *(SP = top_frame_sp) = **SP
 }
 
+void InterpreterMacroAssembler::narrow(Register result) {
+  Register ret_type = R11_scratch1;
+  ld(R11_scratch1, in_bytes(Method::const_offset()), R19_method);
+  lbz(ret_type, in_bytes(ConstMethod::result_type_offset()), R11_scratch1);
+
+  Label notBool, notByte, notChar, done;
+
+  // common case first
+  cmpwi(CCR0, ret_type, T_INT);
+  beq(CCR0, done);
+
+  cmpwi(CCR0, ret_type, T_BOOLEAN);
+  bne(CCR0, notBool);
+  andi(result, result, 0x1);
+  b(done);
+
+  bind(notBool);
+  cmpwi(CCR0, ret_type, T_BYTE);
+  bne(CCR0, notByte);
+  extsb(result, result);
+  b(done);
+
+  bind(notByte);
+  cmpwi(CCR0, ret_type, T_CHAR);
+  bne(CCR0, notChar);
+  andi(result, result, 0xffff);
+  b(done);
+
+  bind(notChar);
+  // cmpwi(CCR0, ret_type, T_SHORT);  // all that's left
+  // bne(CCR0, done);
+  extsh(result, result);
+
+  // Nothing to do for T_INT
+  bind(done);
+}
+
 // Remove activation.
 //
 // Unlock the receiver if this is a synchronized method.
--- a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.hpp	Fri Apr 29 04:44:08 2016 +0200
+++ b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.hpp	Thu Apr 28 23:08:16 2016 -0700
@@ -140,6 +140,8 @@
   void get_cpool_and_tags(Register Rcpool, Register Rtags);
   void is_a(Label& L);
 
+  void narrow(Register result);
+
   // Java Call Helpers
   void call_from_interpreter(Register Rtarget_method, Register Rret_addr, Register Rscratch1, Register Rscratch2);
 
--- a/hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp	Fri Apr 29 04:44:08 2016 +0200
+++ b/hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp	Thu Apr 28 23:08:16 2016 -0700
@@ -655,6 +655,7 @@
   switch (state) {
     case ltos:
     case btos:
+    case ztos:
     case ctos:
     case stos:
     case atos:
@@ -701,6 +702,7 @@
   switch (state) {
     case ltos:
     case btos:
+    case ztos:
     case ctos:
     case stos:
     case atos:
@@ -2082,12 +2084,14 @@
   // Copied from TemplateTable::_return.
   // Restoration of lr done by remove_activation.
   switch (state) {
+    // Narrow result if state is itos but result type is smaller.
+    case itos: __ narrow(R17_tos); /* fall through */
     case ltos:
     case btos:
+    case ztos:
     case ctos:
     case stos:
-    case atos:
-    case itos: __ mr(R3_RET, R17_tos); break;
+    case atos: __ mr(R3_RET, R17_tos); break;
     case ftos:
     case dtos: __ fmr(F1_RET, F15_ftos); break;
     case vtos: // This might be a constructor. Final fields (and volatile fields on PPC64) need
@@ -2147,6 +2151,10 @@
     bname = "trace_code_btos {";
     tsize = 2;
     break;
+  case ztos:
+    bname = "trace_code_ztos {";
+    tsize = 2;
+    break;
   case ctos:
     bname = "trace_code_ctos {";
     tsize = 2;
--- a/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp	Fri Apr 29 04:44:08 2016 +0200
+++ b/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp	Thu Apr 28 23:08:16 2016 -0700
@@ -170,6 +170,7 @@
   switch (new_bc) {
     case Bytecodes::_fast_aputfield:
     case Bytecodes::_fast_bputfield:
+    case Bytecodes::_fast_zputfield:
     case Bytecodes::_fast_cputfield:
     case Bytecodes::_fast_dputfield:
     case Bytecodes::_fast_fputfield:
@@ -981,9 +982,21 @@
                  Rarray   = R12_scratch2,
                  Rscratch = R3_ARG1;
   __ pop_i(Rindex);
+  __ pop_ptr(Rarray);
   // tos: val
-  // Rarray: array ptr (popped by index_check)
-  __ index_check(Rarray, Rindex, 0, Rscratch, Rarray);
+
+  // Need to check whether array is boolean or byte
+  // since both types share the bastore bytecode.
+  __ load_klass(Rscratch, Rarray);
+  __ lwz(Rscratch, in_bytes(Klass::layout_helper_offset()), Rscratch);
+  int diffbit = exact_log2(Klass::layout_helper_boolean_diffbit());
+  __ testbitdi(CCR0, R0, Rscratch, diffbit);
+  Label L_skip;
+  __ bfalse(CCR0, L_skip);
+  __ andi(R17_tos, R17_tos, 1);  // if it is a T_BOOLEAN array, mask the stored value to 0/1
+  __ bind(L_skip);
+
+  __ index_check_without_pop(Rarray, Rindex, 0, Rscratch, Rarray);
   __ stb(R17_tos, arrayOopDesc::base_offset_in_bytes(T_BYTE), Rarray);
 }
 
@@ -2108,12 +2121,16 @@
   __ remove_activation(state, /* throw_monitor_exception */ true);
   // Restoration of lr done by remove_activation.
   switch (state) {
+    // Narrow result if state is itos but result type is smaller.
+    // Need to narrow in the return bytecode rather than in generate_return_entry
+    // since compiled code callers expect the result to already be narrowed.
+    case itos: __ narrow(R17_tos); /* fall through */
     case ltos:
     case btos:
+    case ztos:
     case ctos:
     case stos:
-    case atos:
-    case itos: __ mr(R3_RET, R17_tos); break;
+    case atos: __ mr(R3_RET, R17_tos); break;
     case ftos:
     case dtos: __ fmr(F1_RET, F15_ftos); break;
     case vtos: // This might be a constructor. Final fields (and volatile fields on PPC64) need
@@ -2519,6 +2536,21 @@
   __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
 
   __ align(32, 28, 28); // Align load.
+  // __ bind(Lztos); (same code as btos)
+  __ fence(); // Volatile entry point (one instruction before non-volatile_entry point).
+  assert(branch_table[ztos] == 0, "can't compute twice");
+  branch_table[ztos] = __ pc(); // non-volatile_entry point
+  __ lbzx(R17_tos, Rclass_or_obj, Roffset);
+  __ extsb(R17_tos, R17_tos);
+  __ push(ztos);
+  if (!is_static) {
+    // use btos rewriting, no truncating to t/f bit is needed for getfield.
+    patch_bytecode(Bytecodes::_fast_bgetfield, Rbc, Rscratch);
+  }
+  __ beq(CCR6, Lacquire); // Volatile?
+  __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
+
+  __ align(32, 28, 28); // Align load.
   // __ bind(Lctos);
   __ fence(); // Volatile entry point (one instruction before non-volatile_entry point).
   assert(branch_table[ctos] == 0, "can't compute twice");
@@ -2618,6 +2650,7 @@
         case Bytecodes::_fast_aputfield: __ push_ptr(); offs+= Interpreter::stackElementSize; break;
         case Bytecodes::_fast_iputfield: // Fall through
         case Bytecodes::_fast_bputfield: // Fall through
+        case Bytecodes::_fast_zputfield: // Fall through
         case Bytecodes::_fast_cputfield: // Fall through
         case Bytecodes::_fast_sputfield: __ push_i(); offs+=  Interpreter::stackElementSize; break;
         case Bytecodes::_fast_lputfield: __ push_l(); offs+=2*Interpreter::stackElementSize; break;
@@ -2658,6 +2691,7 @@
       case Bytecodes::_fast_aputfield: __ pop_ptr(); break;
       case Bytecodes::_fast_iputfield: // Fall through
       case Bytecodes::_fast_bputfield: // Fall through
+      case Bytecodes::_fast_zputfield: // Fall through
       case Bytecodes::_fast_cputfield: // Fall through
       case Bytecodes::_fast_sputfield: __ pop_i(); break;
       case Bytecodes::_fast_lputfield: __ pop_l(); break;
@@ -2825,6 +2859,21 @@
   __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
 
   __ align(32, 28, 28); // Align pop.
+  // __ bind(Lztos);
+  __ release(); // Volatile entry point (one instruction before non-volatile_entry point).
+  assert(branch_table[ztos] == 0, "can't compute twice");
+  branch_table[ztos] = __ pc(); // non-volatile_entry point
+  __ pop(ztos);
+  if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1.
+  __ andi(R17_tos, R17_tos, 0x1);
+  __ stbx(R17_tos, Rclass_or_obj, Roffset);
+  if (!is_static) { patch_bytecode(Bytecodes::_fast_zputfield, Rbc, Rscratch, true, byte_no); }
+  if (!support_IRIW_for_not_multiple_copy_atomic_cpu) {
+    __ beq(CR_is_vol, Lvolatile); // Volatile?
+  }
+  __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
+
+  __ align(32, 28, 28); // Align pop.
   // __ bind(Lctos);
   __ release(); // Volatile entry point (one instruction before non-volatile_entry point).
   assert(branch_table[ctos] == 0, "can't compute twice");
@@ -2949,6 +2998,9 @@
       __ stdx(R17_tos, Rclass_or_obj, Roffset);
       break;
 
+    case Bytecodes::_fast_zputfield:
+      __ andi(R17_tos, R17_tos, 0x1);  // boolean is true if LSB is 1
+      // fall through to bputfield
     case Bytecodes::_fast_bputfield:
       __ stbx(R17_tos, Rclass_or_obj, Roffset);
       break;
--- a/hotspot/src/share/vm/classfile/classLoader.cpp	Fri Apr 29 04:44:08 2016 +0200
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp	Thu Apr 28 23:08:16 2016 -0700
@@ -98,12 +98,13 @@
 
 // Entry points for jimage.dll for loading jimage file entries
 
-static JImageOpen_t                    JImageOpen                    = NULL;
-static JImageClose_t                   JImageClose                   = NULL;
-static JImagePackageToModule_t         JImagePackageToModule         = NULL;
-static JImageFindResource_t            JImageFindResource            = NULL;
-static JImageGetResource_t             JImageGetResource             = NULL;
-static JImageResourceIterator_t        JImageResourceIterator        = NULL;
+static JImageOpen_t                    JImageOpen             = NULL;
+static JImageClose_t                   JImageClose            = NULL;
+static JImagePackageToModule_t         JImagePackageToModule  = NULL;
+static JImageFindResource_t            JImageFindResource     = NULL;
+static JImageGetResource_t             JImageGetResource      = NULL;
+static JImageResourceIterator_t        JImageResourceIterator = NULL;
+static JImage_ResourcePath_t           JImageResourcePath     = NULL;
 
 // Globals
 
@@ -925,6 +926,8 @@
   guarantee(JImageGetResource != NULL, "function JIMAGE_GetResource not found");
   JImageResourceIterator = CAST_TO_FN_PTR(JImageResourceIterator_t, os::dll_lookup(handle, "JIMAGE_ResourceIterator"));
   guarantee(JImageResourceIterator != NULL, "function JIMAGE_ResourceIterator not found");
+  JImageResourcePath = CAST_TO_FN_PTR(JImage_ResourcePath_t, os::dll_lookup(handle, "JIMAGE_ResourcePath"));
+  guarantee(JImageResourcePath != NULL, "function JIMAGE_ResourcePath not found");
 }
 
 jboolean ClassLoader::decompress(void *in, u8 inSize, void *out, u8 outSize, char **pmsg) {
--- a/hotspot/src/share/vm/classfile/jimage.hpp	Fri Apr 29 04:44:08 2016 +0200
+++ b/hotspot/src/share/vm/classfile/jimage.hpp	Thu Apr 28 23:08:16 2016 -0700
@@ -30,7 +30,7 @@
 typedef jlong JImageLocationRef;
 
 // Max path length limit independent of platform.  Windows max path is 1024,
-// other platforms use 4096.  The JCK fails several tests when 1024 is used.
+// other platforms use 4096.
 #define JIMAGE_MAX_PATH 4096
 
 // JImage Error Codes
@@ -113,7 +113,8 @@
  *
  *  Ex.
  *   jlong size;
- *   JImageLocationRef location = (*JImageFindResource)(image, "java.base", "9.0", "java/lang/String.class", &size);
+ *   JImageLocationRef location = (*JImageFindResource)(image,
+ *                                "java.base", "9.0", "java/lang/String.class", &size);
  */
 extern "C" JImageLocationRef JIMAGE_FindResource(JImageFile* jimage,
         const char* module_name, const char* version, const char* name,
@@ -134,7 +135,8 @@
  *
  * Ex.
  *  jlong size;
- *  JImageLocationRef location = (*JImageFindResource)(image, "java.base", "9.0", "java/lang/String.class", &size);
+ *  JImageLocationRef location = (*JImageFindResource)(image,
+ *                               "java.base", "9.0", "java/lang/String.class", &size);
  *  char* buffer = new char[size];
  *  (*JImageGetResource)(image, location, buffer, size);
  */
@@ -154,7 +156,8 @@
  * required. All strings are utf-8, zero byte terminated.file.
  *
  * Ex.
- *   bool ctw_visitor(JImageFile* jimage, const char* module_name, const char* version, const char* package, const char* name, const char* extension, void* arg) {
+ *   bool ctw_visitor(JImageFile* jimage, const char* module_name, const char* version,
+ *                  const char* package, const char* name, const char* extension, void* arg) {
  *     if (strcmp(extension, “class”) == 0) {
  *       char path[JIMAGE_MAX_PATH];
  *       Thread* THREAD = Thread::current();
@@ -176,3 +179,20 @@
 
 typedef void (*JImageResourceIterator_t)(JImageFile* jimage,
         JImageResourceVisitor_t visitor, void* arg);
+
+/*
+ * JIMAGE_ResourcePath- Given an open image file, a location reference, a buffer
+ * and a maximum buffer size, copy the path of the resource into the buffer.
+ * Returns false if not a valid location reference.
+ *
+ * Ex.
+ *   JImageLocationRef location = ...
+ *   char path[JIMAGE_MAX_PATH];
+ *    (*JImageResourcePath)(image, location, path, JIMAGE_MAX_PATH);
+ */
+extern "C" bool JIMAGE_ResourcePath(JImageFile* image, JImageLocationRef locationRef,
+                                    char* path, size_t max);
+
+typedef bool (*JImage_ResourcePath_t)(JImageFile* jimage, JImageLocationRef location,
+        char* buffer, jlong size);
+
--- a/jaxp/.hgtags	Fri Apr 29 04:44:08 2016 +0200
+++ b/jaxp/.hgtags	Thu Apr 28 23:08:16 2016 -0700
@@ -357,3 +357,5 @@
 36326537f929d20cc5885b93939f90c0efcc4681 jdk-9+112
 28626780e245fccbfb9bad8e3b05f62357958038 jdk-9+113
 147114dd0641cd7c9fe6e81642eb993a7b9c6f0b jdk-9+114
+1902a5bda18e794b31fc5f520f5e7d827714b50d jdk-9+115
+9d71d20e614777cd23c1a43b38b5c08a9094d27a jdk-9+116
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,15 +1,16 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
- * Copyright 2005 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -24,7 +25,6 @@
 import com.sun.org.apache.xerces.internal.util.XML11Char;
 import com.sun.org.apache.xerces.internal.util.XMLChar;
 import com.sun.org.apache.xerces.internal.util.XMLStringBuffer;
-import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
 import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager.Limit;
 import com.sun.org.apache.xerces.internal.xni.QName;
 import com.sun.org.apache.xerces.internal.xni.XMLString;
@@ -815,7 +815,7 @@
             load(0, true, true);
         }
         else if (fCurrentEntity.position == fCurrentEntity.count - 1) {
-            invokeListeners(0);
+            invokeListeners(1);
             fCurrentEntity.ch[0] = fCurrentEntity.ch[fCurrentEntity.count - 1];
             load(1, false, false);
             fCurrentEntity.position = 0;
@@ -960,7 +960,7 @@
             load(0, true, true);
         }
         else if (fCurrentEntity.position == fCurrentEntity.count - 1) {
-            invokeListeners(0);
+            invokeListeners(1);
             fCurrentEntity.ch[0] = fCurrentEntity.ch[fCurrentEntity.count - 1];
             load(1, false, false);
             fCurrentEntity.startPosition = 0;
@@ -1397,7 +1397,7 @@
                         fCurrentEntity.lineNumber++;
                         fCurrentEntity.columnNumber = 1;
                         if (fCurrentEntity.position == fCurrentEntity.count - 1) {
-                            invokeListeners(0);
+                            invokeListeners(1);
                             fCurrentEntity.ch[0] = (char)c;
                             entityChanged = load(1, true, false);
                             if (!entityChanged) {
@@ -1446,8 +1446,9 @@
                     fCurrentEntity.lineNumber++;
                     fCurrentEntity.columnNumber = 1;
                     if (fCurrentEntity.position == fCurrentEntity.count - 1) {
+                        invokeListeners(1);
                         fCurrentEntity.ch[0] = (char)c;
-                        entityChanged = load(1, true, true);
+                        entityChanged = load(1, true, false);
                         if (!entityChanged) {
                             // the load change the position to be 1,
                             // need to restore it when entity not changed
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDTDScannerImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDTDScannerImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -3,13 +3,14 @@
  */
 
 /*
- * Copyright 2005 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -19,17 +20,17 @@
  */
 
 package com.sun.org.apache.xerces.internal.impl;
-import com.sun.xml.internal.stream.dtd.nonvalidating.DTDGrammar;
-import java.io.EOFException;
-import java.io.IOException;
 
+import com.sun.org.apache.xerces.internal.impl.Constants;
 import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
-
+import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
+import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler;
 import com.sun.org.apache.xerces.internal.util.SymbolTable;
 import com.sun.org.apache.xerces.internal.util.XMLAttributesImpl;
 import com.sun.org.apache.xerces.internal.util.XMLChar;
 import com.sun.org.apache.xerces.internal.util.XMLStringBuffer;
-
+import com.sun.org.apache.xerces.internal.utils.XMLLimitAnalyzer;
+import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
 import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler;
 import com.sun.org.apache.xerces.internal.xni.XMLDTDHandler;
 import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
@@ -41,11 +42,9 @@
 import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDScanner;
 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
 import com.sun.org.apache.xerces.internal.xni.Augmentations;
-import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
-import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler;
-import com.sun.org.apache.xerces.internal.impl.Constants;
-import com.sun.org.apache.xerces.internal.utils.XMLLimitAnalyzer;
-import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
+import com.sun.xml.internal.stream.dtd.nonvalidating.DTDGrammar;
+import java.io.EOFException;
+import java.io.IOException;
 
 /**
  * This class is responsible for scanning the declarations found
@@ -387,15 +386,25 @@
      */
     @Override
     public boolean skipDTD(boolean supportDTD) throws IOException {
-        if (!supportDTD) {
-            fStringBuffer.clear();
-            if (!fEntityScanner.scanData("]", fStringBuffer)) {
-                fEntityScanner.fCurrentEntity.position--;
+        if (supportDTD)
+            return false;
+
+        fStringBuffer.clear();
+        while (fEntityScanner.scanData("]", fStringBuffer)) {
+            int c = fEntityScanner.peekChar();
+            if (c != -1) {
+                if (XMLChar.isHighSurrogate(c)) {
+                    scanSurrogates(fStringBuffer);
+                }
+                if (isInvalidLiteral(c)) {
+                    reportFatalError("InvalidCharInDTD",
+                        new Object[] { Integer.toHexString(c) });
+                    fEntityScanner.scanChar();
+                }
             }
-
-            return true;
         }
-        return false;
+        fEntityScanner.fCurrentEntity.position--;
+        return true;
     }
 
     //
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -3,13 +3,14 @@
  */
 
 /*
- * Copyright 2005 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -18,7 +19,6 @@
  * limitations under the License.
  */
 
-
 package com.sun.org.apache.xerces.internal.impl;
 
 import com.sun.xml.internal.stream.XMLBufferListener;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -3,13 +3,14 @@
  */
 
 /*
- * Copyright 2005 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -20,7 +21,6 @@
 
 package com.sun.org.apache.xerces.internal.impl;
 
-
 import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDDescription;
 import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager;
 import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
@@ -1106,8 +1106,7 @@
                             if (!moreToScan) {
                                 // end doctype declaration
                                 if (!fEntityScanner.skipChar(']')) {
-                                    reportFatalError("EXPECTED_SQUARE_BRACKET_TO_CLOSE_INTERNAL_SUBSET",
-                                            null);
+                                    reportFatalError("DoctypedeclNotClosed", new Object[]{fDoctypeName});
                                 }
                                 fEntityScanner.skipSpaces();
                                 if (!fEntityScanner.skipChar('>')) {
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,15 +1,16 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
- * Copyright 2005 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -20,8 +21,6 @@
 
 package com.sun.org.apache.xerces.internal.impl;
 
-
-
 import com.sun.org.apache.xerces.internal.impl.io.ASCIIReader;
 import com.sun.org.apache.xerces.internal.impl.io.UCSReader;
 import com.sun.org.apache.xerces.internal.impl.io.UTF8Reader;
@@ -44,8 +43,8 @@
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
+import java.util.ArrayList;
 import java.util.Locale;
-import java.util.Vector;
 
 /**
  * Implements the entity scanner methods.
@@ -58,11 +57,10 @@
  */
 public class XMLEntityScanner implements XMLLocator  {
 
-
-    protected Entity.ScannedEntity fCurrentEntity = null ;
+    protected Entity.ScannedEntity fCurrentEntity = null;
     protected int fBufferSize = XMLEntityManager.DEFAULT_BUFFER_SIZE;
 
-    protected XMLEntityManager fEntityManager ;
+    protected XMLEntityManager fEntityManager;
 
     /** Security manager. */
     protected XMLSecurityManager fSecurityManager = null;
@@ -72,8 +70,9 @@
 
     /** Debug switching readers for encodings. */
     private static final boolean DEBUG_ENCODINGS = false;
+
     /** Listeners which should know when load is being called */
-    private Vector listeners = new Vector();
+    private ArrayList<XMLBufferListener> listeners = new ArrayList<>();
 
     private static final boolean [] VALID_NAMES = new boolean[127];
 
@@ -140,9 +139,11 @@
         VALID_NAMES[58]=true;
         VALID_NAMES[95]=true;
     }
-    // SAPJVM: Remember, that the XML version has explicitly been set,
+
+    // Remember, that the XML version has explicitly been set,
     // so that XMLStreamReader.getVersion() can find that out.
-    boolean xmlVersionSetExplicitly = false;
+    protected boolean xmlVersionSetExplicitly = false;
+
     //
     // Constructors
     //
@@ -257,7 +258,7 @@
      * @param xmlVersion the XML version of the current entity
      */
     public final void setXMLVersion(String xmlVersion) {
-        xmlVersionSetExplicitly = true; // SAPJVM
+        xmlVersionSetExplicitly = true;
         fCurrentEntity.xmlVersion = xmlVersion;
     } // setXMLVersion(String)
 
@@ -546,8 +547,7 @@
 
         // scan character
         int c = fCurrentEntity.ch[fCurrentEntity.position++];
-        if (c == '\n' ||
-                (c == '\r' && isExternal)) {
+        if (c == '\n' || (c == '\r' && isExternal)) {
             fCurrentEntity.lineNumber++;
             fCurrentEntity.columnNumber = 1;
             if (fCurrentEntity.position == fCurrentEntity.count) {
@@ -953,7 +953,7 @@
         if (fCurrentEntity.position == fCurrentEntity.count) {
             load(0, true, true);
         } else if (fCurrentEntity.position == fCurrentEntity.count - 1) {
-            invokeListeners(0);
+            invokeListeners(1);
             fCurrentEntity.ch[0] = fCurrentEntity.ch[fCurrentEntity.count - 1];
             load(1, false, false);
             fCurrentEntity.position = 0;
@@ -1105,7 +1105,7 @@
         if (fCurrentEntity.position == fCurrentEntity.count) {
             load(0, true, true);
         } else if (fCurrentEntity.position == fCurrentEntity.count - 1) {
-            invokeListeners(0);
+            invokeListeners(1);
             fCurrentEntity.ch[0] = fCurrentEntity.ch[fCurrentEntity.count - 1];
             load(1, false, false);
             fCurrentEntity.position = 0;
@@ -1256,8 +1256,8 @@
      * <p>
      * <strong>Note:</strong> The characters are consumed.
      * <p>
-     * <strong>Note:</strong> This assumes that the length of the delimiter
-     * and that the delimiter contains at least one character.
+     * <strong>Note:</strong> This assumes that the delimiter contains at
+     * least one character.
      * <p>
      * <strong>Note:</strong> This method does not guarantee to return
      * the longest run of character data. This method may return before
@@ -1436,7 +1436,7 @@
         } while (!done);
         return !done;
 
-    } // scanData(String,XMLString)
+    } // scanData(String, XMLStringBuffer)
 
     /**
      * Skips a character appearing immediately on the input.
@@ -1558,7 +1558,7 @@
                     fCurrentEntity.lineNumber++;
                     fCurrentEntity.columnNumber = 1;
                     if (fCurrentEntity.position == fCurrentEntity.count - 1) {
-                        invokeListeners(0);
+                        invokeListeners(1);
                         fCurrentEntity.ch[0] = (char)c;
                         entityChanged = load(1, true, false);
                         if (!entityChanged){
@@ -1727,8 +1727,7 @@
         final int length = s.length;
         //first make sure that required capacity is avaible
         if(arrangeCapacity(length, false)){
-            int beforeSkip = fCurrentEntity.position ;
-            int afterSkip = fCurrentEntity.position + length  ;
+            int beforeSkip = fCurrentEntity.position;
 
             if(DEBUG_SKIP_STRING){
                 System.out.println("skipString,length = " + new String(s) + "," + length);
@@ -2107,8 +2106,9 @@
      * is being changed.
      */
     public void registerListener(XMLBufferListener listener) {
-        if(!listeners.contains(listener))
+        if (!listeners.contains(listener)) {
             listeners.add(listener);
+        }
     }
 
     /**
@@ -2116,9 +2116,8 @@
      * @param loadPos Starting position from which new data is being loaded into scanner buffer.
      */
     public void invokeListeners(int loadPos){
-        for(int i=0;i<listeners.size();i++){
-            XMLBufferListener listener =(XMLBufferListener) listeners.get(i);
-            listener.refresh(loadPos);
+        for (int i=0; i<listeners.size(); i++) {
+            listeners.get(i).refresh(loadPos);
         }
     }
 
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java	Thu Apr 28 23:08:16 2016 -0700
@@ -3,13 +3,14 @@
  */
 
 /*
- * Copyright 2005 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -20,7 +21,6 @@
 
 package com.sun.org.apache.xerces.internal.impl;
 
-
 import com.sun.org.apache.xerces.internal.util.Status;
 import com.sun.xml.internal.stream.XMLEntityStorage;
 import java.io.IOException;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties	Fri Apr 29 04:44:08 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties	Thu Apr 28 23:08:16 2016 -0700
@@ -145,6 +145,7 @@
         MSG_SPACE_REQUIRED_BEFORE_ROOT_ELEMENT_TYPE_IN_DOCTYPEDECL = White space is required after \"<!DOCTYPE\" in the document type declaration.
         MSG_ROOT_ELEMENT_TYPE_REQUIRED = The root element type must appear after \"<!DOCTYPE\" in the document type declaration.
         DoctypedeclUnterminated = The document type declaration for root element type \"{0}\" must end with ''>''.
+        DoctypedeclNotClosed = The document type declaration for root element type \"{0}\" must be closed with '']''.
         PEReferenceWithinMarkup = The parameter entity reference \"%{0};\" cannot occur within markup in the internal subset of the DTD.
         MSG_MARKUP_NOT_RECOGNIZED_IN_DTD = The markup declarations contained or pointed to by the document type declaration must be well-formed.
 # 2.10 White Space Handling
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_de.properties	Fri Apr 29 04:44:08 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_de.properties	Thu Apr 28 23:08:16 2016 -0700
@@ -145,6 +145,7 @@
         MSG_SPACE_REQUIRED_BEFORE_ROOT_ELEMENT_TYPE_IN_DOCTYPEDECL = Leerstelle nach "<!DOCTYPE" in der Dokumenttypdeklaration erforderlich.
         MSG_ROOT_ELEMENT_TYPE_REQUIRED = Root-Elementtyp muss nach "<!DOCTYPE" in der Dokumenttypdeklaration enthalten sein.
         DoctypedeclUnterminated = Dokumenttypdeklaration f\u00FCr Root-Elementtyp "{0}" muss mit ">" enden.
+        DoctypedeclNotClosed = Dokumenttypdeklaration f\u00FCr Root-Elementtyp "{0}" muss mit "]" abgeschlossen werden.
         PEReferenceWithinMarkup = Parameterentit\u00E4tsreferenz "%{0};" darf nicht in Markup in der internen Teilmenge der DTD vorkommen.
         MSG_MARKUP_NOT_RECOGNIZED_IN_DTD = Die Markup-Deklarationen, die in der Dokumenttypdeklaration enthalten sind bzw. auf die von der Dokumenttypdeklaration verwiesen wird, m\u00FCssen ordnungsgem\u00E4\u00DF formatiert sein.
 # 2.10 White Space Handling
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_es.properties	Fri Apr 29 04:44:08 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_es.properties	Thu Apr 28 23:08:16 2016 -0700
@@ -145,6 +145,7 @@
         MSG_SPACE_REQUIRED_BEFORE_ROOT_ELEMENT_TYPE_IN_DOCTYPEDECL = Es necesario un espacio en blanco despu\u00E9s de "<!DOCTYPE" en la declaraci\u00F3n de tipo de documento.
         MSG_ROOT_ELEMENT_TYPE_REQUIRED = El tipo de elemento ra\u00EDz debe aparecer despu\u00E9s de "<!DOCTYPE" en la declaraci\u00F3n de tipo de documento.
         DoctypedeclUnterminated = La declaraci\u00F3n de tipo de documento para el tipo de elemento ra\u00EDz "{0}" debe finalizar en ''>''.
+        DoctypedeclNotClosed = La declaraci\u00F3n de tipo de documento para el tipo de elemento ra\u00EDz "{0}" debe cerrar en '']''.
         PEReferenceWithinMarkup = La referencia de entidad del par\u00E1metro "%{0};" no puede producirse en el marcador en el subconjunto interno del DTD.
         MSG_MARKUP_NOT_RECOGNIZED_IN_DTD = Las declaraciones de marcador que se incluyen o a las que apunta la declaraci\u00F3n de tipo de documento deben tener el formato correcto.
 # 2.10 White Space Handling
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_fr.properties	Fri Apr 29 04:44:08 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_fr.properties	Thu Apr 28 23:08:16 2016 -0700
@@ -145,6 +145,7 @@
         MSG_SPACE_REQUIRED_BEFORE_ROOT_ELEMENT_TYPE_IN_DOCTYPEDECL = Un espace est obligatoire apr\u00E8s "<!DOCTYPE" dans la d\u00E9claration de type de document.
         MSG_ROOT_ELEMENT_TYPE_REQUIRED = Le type d'\u00E9l\u00E9ment racine doit figurer apr\u00E8s "<!DOCTYPE" dans la d\u00E9claration de type de document.
         DoctypedeclUnterminated = La d\u00E9claration de type de document pour le type d''\u00E9l\u00E9ment racine "{0}" doit se terminer par ''>''.
+        DoctypedeclNotClosed = La d\u00E9claration de type de document pour le type d''\u00E9l\u00E9ment racine "{0}" doit se conclure par '']''.
         PEReferenceWithinMarkup = La r\u00E9f\u00E9rence d''entit\u00E9 de param\u00E8tre "%{0};" ne peut pas survenir dans le balisage du sous-ensemble interne de la DTD.
         MSG_MARKUP_NOT_RECOGNIZED_IN_DTD = Les d\u00E9clarations de balisage contenues dans la d\u00E9claration de type de document ou sur lesquelles pointe cette derni\u00E8re doivent avoir un format correct.
 # 2.10 White Space Handling
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_it.properties	Fri Apr 29 04:44:08 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_it.properties	Thu Apr 28 23:08:16 2016 -0700
@@ -145,6 +145,7 @@
         MSG_SPACE_REQUIRED_BEFORE_ROOT_ELEMENT_TYPE_IN_DOCTYPEDECL = \u00C8 richiesto uno spazio dopo "<!DOCTYPE" nella dichiarazione del tipo di documento.
         MSG_ROOT_ELEMENT_TYPE_REQUIRED = Il tipo di elemento radice deve comparire dopo "<!DOCTYPE" nella dichiarazione del tipo di documento.
         DoctypedeclUnterminated = La dichiarazione del tipo di documento per il tipo di elemento radice "{0}" deve terminare con ''>''.
+        DoctypedeclNotClosed = La dichiarazione del tipo di documento per il tipo di elemento radice "{0}" deve chiudere con '']''.
         PEReferenceWithinMarkup = Il riferimento di entit\u00E0 di parametro "%{0};" non pu\u00F2 essere presente nel markup del set secondario interno del DTD.
         MSG_MARKUP_NOT_RECOGNIZED_IN_DTD = Le dichiarazioni di markup contenute o indicate dalla dichiarazione del tipo di documento devono avere un formato corretto.
 # 2.10 White Space Handling
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/HTTPInputSource.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/HTTPInputSource.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,15 +1,16 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
  */
+
 /*
- * Copyright 2004,2005 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,18 +18,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package com.sun.org.apache.xerces.internal.util;
 
+import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
+import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
 import java.io.InputStream;
 import java.io.Reader;
-
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 
-import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
-import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
-
 /**
  * This class represents an input source for an XML resource
  * retrievable over HTTP. In addition to the properties
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogFeatures.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogFeatures.java	Thu Apr 28 23:08:16 2016 -0700
@@ -444,13 +444,15 @@
                 }
             } else if (index == Feature.FILES.ordinal()) {
                 try {
-                    if (Util.verifyAndGetURI(value, null) == null) {
-                        CatalogMessages.reportIAE(new Object[]{value, Feature.FILES.name()}, null);
+                    String[] catalogFile = value.split(";[ ]*");
+                    for (String temp : catalogFile) {
+                        if (Util.verifyAndGetURI(temp, null) == null) {
+                            CatalogMessages.reportIAE(new Object[]{value, Feature.FILES.name()}, null);
+                        }
                     }
                 }catch (MalformedURLException | URISyntaxException | IllegalArgumentException ex) {
                     CatalogMessages.reportIAE(new Object[]{value, Feature.FILES.name()}, ex);
                 }
-
             }
             if (states[index] == null || state.compareTo(states[index]) >= 0) {
                 values[index] = value;
--- a/jaxp/test/javax/xml/jaxp/libs/jaxp/library/TestPolicy.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/TestPolicy.java	Thu Apr 28 23:08:16 2016 -0700
@@ -91,6 +91,7 @@
         permissions.add(new PropertyPermission("line.separator", "read"));
         permissions.add(new PropertyPermission("fileStringBuffer", "read"));
         permissions.add(new PropertyPermission("dataproviderthreadcount", "read"));
+        permissions.add(new RuntimePermission("charsetProvider"));
     }
 
     /*
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jdk/testlibrary/Asserts.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,566 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 jdk.testlibrary;
+
+import java.util.Objects;
+
+/**
+ * Asserts that can be used for verifying assumptions in tests.
+ *
+ * An assertion will throw a {@link RuntimeException} if the assertion isn't true.
+ * All the asserts can be imported into a test by using a static import:
+ *
+ * <pre>
+ * {@code
+ * import static jdk.testlibrary.Asserts.*;
+ * }
+ *
+ * Always provide a message describing the assumption if the line number of the
+ * failing assertion isn't enough to understand why the assumption failed. For
+ * example, if the assertion is in a loop or in a method that is called
+ * multiple times, then the line number won't provide enough context to
+ * understand the failure.
+ * </pre>
+ *
+ * @deprecated This class is deprecated. Use the one from
+ *             {@code <root>/test/lib/share/classes/jdk/test/lib}
+ */
+@Deprecated
+public class Asserts {
+
+    /**
+     * Shorthand for {@link #assertLessThan(Comparable, Comparable)}.
+     *
+     * @param <T> a type
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @see #assertLessThan(Comparable, Comparable)
+     */
+    public static <T extends Comparable<T>> void assertLT(T lhs, T rhs) {
+        assertLessThan(lhs, rhs);
+    }
+
+    /**
+     * Shorthand for {@link #assertLessThan(Comparable, Comparable, String)}.
+     *
+     * @param <T> a type
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @param msg A description of the assumption; {@code null} for a default message.
+     * @see #assertLessThan(Comparable, Comparable, String)
+     */
+    public static <T extends Comparable<T>> void assertLT(T lhs, T rhs, String msg) {
+        assertLessThan(lhs, rhs, msg);
+    }
+
+    /**
+     * Calls {@link #assertLessThan(Comparable, Comparable, String)} with a default message.
+     *
+     * @param <T> a type
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @see #assertLessThan(Comparable, Comparable, String)
+     */
+    public static <T extends Comparable<T>> void assertLessThan(T lhs, T rhs) {
+        assertLessThan(lhs, rhs, null);
+    }
+
+    /**
+     * Asserts that {@code lhs} is less than {@code rhs}.
+     *
+     * @param <T> a type
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @param msg A description of the assumption; {@code null} for a default message.
+     * @throws RuntimeException if the assertion is not true.
+     */
+    public static <T extends Comparable<T>>void assertLessThan(T lhs, T rhs, String msg) {
+        if (!(compare(lhs, rhs, msg) < 0)) {
+            msg = Objects.toString(msg, "assertLessThan")
+                    + ": expected that " + Objects.toString(lhs)
+                    + " < " + Objects.toString(rhs);
+            fail(msg);
+        }
+    }
+
+    /**
+     * Shorthand for {@link #assertLessThanOrEqual(Comparable, Comparable)}.
+     *
+     * @param <T> a type
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @see #assertLessThanOrEqual(Comparable, Comparable)
+     */
+    public static <T extends Comparable<T>> void assertLTE(T lhs, T rhs) {
+        assertLessThanOrEqual(lhs, rhs);
+    }
+
+    /**
+     * Shorthand for {@link #assertLessThanOrEqual(Comparable, Comparable, String)}.
+     *
+     * @param <T> a type
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @param msg A description of the assumption; {@code null} for a default message.
+     * @see #assertLessThanOrEqual(Comparable, Comparable, String)
+     */
+    public static <T extends Comparable<T>> void assertLTE(T lhs, T rhs, String msg) {
+        assertLessThanOrEqual(lhs, rhs, msg);
+    }
+
+    /**
+     * Calls {@link #assertLessThanOrEqual(Comparable, Comparable, String)} with a default message.
+     *
+     * @param <T> a type
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @see #assertLessThanOrEqual(Comparable, Comparable, String)
+     */
+    public static <T extends Comparable<T>> void assertLessThanOrEqual(T lhs, T rhs) {
+        assertLessThanOrEqual(lhs, rhs, null);
+    }
+
+    /**
+     * Asserts that {@code lhs} is less than or equal to {@code rhs}.
+     *
+     * @param <T> a type
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @param msg A description of the assumption; {@code null} for a default message.
+     * @throws RuntimeException if the assertion is not true.
+     */
+    public static <T extends Comparable<T>> void assertLessThanOrEqual(T lhs, T rhs, String msg) {
+        if (!(compare(lhs, rhs, msg) <= 0)) {
+            msg = Objects.toString(msg, "assertLessThanOrEqual")
+                    + ": expected that " + Objects.toString(lhs)
+                    + " <= " + Objects.toString(rhs);
+            fail(msg);
+        }
+    }
+
+    /**
+     * Shorthand for {@link #assertEquals(Object, Object)}.
+     *
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @see #assertEquals(Object, Object)
+     */
+    public static void assertEQ(Object lhs, Object rhs) {
+        assertEquals(lhs, rhs);
+    }
+
+    /**
+     * Shorthand for {@link #assertEquals(Object, Object, String)}.
+     *
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @param msg A description of the assumption; {@code null} for a default message.
+     * @see #assertEquals(Object, Object, String)
+     */
+    public static void assertEQ(Object lhs, Object rhs, String msg) {
+        assertEquals(lhs, rhs, msg);
+    }
+
+    /**
+     * Calls {@link #assertEquals(java.lang.Object, java.lang.Object, java.lang.String)} with a default message.
+     *
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @see #assertEquals(Object, Object, String)
+     */
+    public static void assertEquals(Object lhs, Object rhs) {
+        assertEquals(lhs, rhs, null);
+    }
+
+    /**
+     * Asserts that {@code lhs} is equal to {@code rhs}.
+     *
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @param msg A description of the assumption; {@code null} for a default message.
+     * @throws RuntimeException if the assertion is not true.
+     */
+    public static void assertEquals(Object lhs, Object rhs, String msg) {
+        if ((lhs != rhs) && ((lhs == null) || !(lhs.equals(rhs)))) {
+            msg = Objects.toString(msg, "assertEquals")
+                    + ": expected " + Objects.toString(lhs)
+                    + " to equal " + Objects.toString(rhs);
+            fail(msg);
+        }
+    }
+
+    /**
+     * Calls {@link #assertSame(java.lang.Object, java.lang.Object, java.lang.String)} with a default message.
+     *
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @see #assertSame(Object, Object, String)
+     */
+    public static void assertSame(Object lhs, Object rhs) {
+        assertSame(lhs, rhs, null);
+    }
+
+    /**
+     * Asserts that {@code lhs} is the same as {@code rhs}.
+     *
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @param msg A description of the assumption; {@code null} for a default message.
+     * @throws RuntimeException if the assertion is not true.
+     */
+    public static void assertSame(Object lhs, Object rhs, String msg) {
+        if (lhs != rhs) {
+            msg = Objects.toString(msg, "assertSame")
+                    + ": expected " + Objects.toString(lhs)
+                    + " to equal " + Objects.toString(rhs);
+            fail(msg);
+        }
+    }
+
+    /**
+     * Shorthand for {@link #assertGreaterThanOrEqual(Comparable, Comparable)}.
+     *
+     * @param <T> a type
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @see #assertGreaterThanOrEqual(Comparable, Comparable)
+     */
+    public static <T extends Comparable<T>> void assertGTE(T lhs, T rhs) {
+        assertGreaterThanOrEqual(lhs, rhs);
+    }
+
+    /**
+     * Shorthand for {@link #assertGreaterThanOrEqual(Comparable, Comparable, String)}.
+     *
+     * @param <T> a type
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @param msg A description of the assumption; {@code null} for a default message.
+     * @see #assertGreaterThanOrEqual(Comparable, Comparable, String)
+     */
+    public static <T extends Comparable<T>> void assertGTE(T lhs, T rhs, String msg) {
+        assertGreaterThanOrEqual(lhs, rhs, msg);
+    }
+
+    /**
+     * Calls {@link #assertGreaterThanOrEqual(Comparable, Comparable, String)} with a default message.
+     *
+     * @param <T> a type
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @see #assertGreaterThanOrEqual(Comparable, Comparable, String)
+     */
+    public static <T extends Comparable<T>> void assertGreaterThanOrEqual(T lhs, T rhs) {
+        assertGreaterThanOrEqual(lhs, rhs, null);
+    }
+
+    /**
+     * Asserts that {@code lhs} is greater than or equal to {@code rhs}.
+     *
+     * @param <T> a type
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @param msg A description of the assumption; {@code null} for a default message.
+     * @throws RuntimeException if the assertion is not true.
+     */
+    public static <T extends Comparable<T>> void assertGreaterThanOrEqual(T lhs, T rhs, String msg) {
+        if (!(compare(lhs, rhs, msg) >= 0)) {
+            msg = Objects.toString(msg, "assertGreaterThanOrEqual")
+                    + ": expected " + Objects.toString(lhs)
+                    + " >= " + Objects.toString(rhs);
+            fail(msg);
+        }
+    }
+
+    /**
+     * Shorthand for {@link #assertGreaterThan(Comparable, Comparable)}.
+     *
+     * @param <T> a type
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @see #assertGreaterThan(Comparable, Comparable)
+     */
+    public static <T extends Comparable<T>> void assertGT(T lhs, T rhs) {
+        assertGreaterThan(lhs, rhs);
+    }
+
+    /**
+     * Shorthand for {@link #assertGreaterThan(Comparable, Comparable, String)}.
+     *
+     * @param <T> a type
+     * @param lhs the left hand value
+     * @param rhs the right hand value
+     * @param msg A description of the assumption; {@code null} for a default message.
+     * @see #assertGreaterThan(Comparable, Comparable, String)
+     */
+    public static <T extends Comparable<T>> void assertGT(T lhs, T rhs, String msg) {
+        assertGreaterThan(lhs, rhs, msg);
+    }
+
+    /**
+     * Calls {@link #assertGreaterThan(Comparable, Comparable, String)} with a default message.
+     *
+     * @param <T> a type
+     * @param lhs the left hand value
+     * @param rhs the right hand value
+     * @see #assertGreaterThan(Comparable, Comparable, String)
+     */
+    public static <T extends Comparable<T>> void assertGreaterThan(T lhs, T rhs) {
+        assertGreaterThan(lhs, rhs, null);
+    }
+
+    /**
+     * Asserts that {@code lhs} is greater than {@code rhs}.
+     *
+     * @param <T> a type
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @param msg A description of the assumption; {@code null} for a default message.
+     * @throws RuntimeException if the assertion is not true.
+     */
+    public static <T extends Comparable<T>> void assertGreaterThan(T lhs, T rhs, String msg) {
+        if (!(compare(lhs, rhs, msg) > 0)) {
+            msg = Objects.toString(msg, "assertGreaterThan")
+                    + ": expected " + Objects.toString(lhs)
+                    + " > " + Objects.toString(rhs);
+            fail(msg);
+        }
+    }
+
+    /**
+     * Shorthand for {@link #assertNotEquals(Object, Object)}.
+     *
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @see #assertNotEquals(Object, Object)
+     */
+    public static void assertNE(Object lhs, Object rhs) {
+        assertNotEquals(lhs, rhs);
+    }
+
+    /**
+     * Shorthand for {@link #assertNotEquals(Object, Object, String)}.
+     *
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @param msg A description of the assumption; {@code null} for a default message.
+     * @see #assertNotEquals(Object, Object, String)
+     */
+    public static void assertNE(Object lhs, Object rhs, String msg) {
+        assertNotEquals(lhs, rhs, msg);
+    }
+
+    /**
+     * Calls {@link #assertNotEquals(Object, Object, String)} with a default message.
+     *
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @see #assertNotEquals(Object, Object, String)
+     */
+    public static void assertNotEquals(Object lhs, Object rhs) {
+        assertNotEquals(lhs, rhs, null);
+    }
+
+    /**
+     * Asserts that {@code lhs} is not equal to {@code rhs}.
+     *
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @param msg A description of the assumption; {@code null} for a default message.
+     * @throws RuntimeException if the assertion is not true.
+     */
+    public static void assertNotEquals(Object lhs, Object rhs, String msg) {
+        if ((lhs == rhs) || (lhs != null && lhs.equals(rhs))) {
+            msg = Objects.toString(msg, "assertNotEquals")
+                    + ": expected " + Objects.toString(lhs)
+                    + " to not equal " + Objects.toString(rhs);
+            fail(msg);
+        }
+    }
+
+    /**
+     * Calls {@link #assertNull(Object, String)} with a default message.
+     *
+     * @param o The reference assumed to be null.
+     * @see #assertNull(Object, String)
+     */
+    public static void assertNull(Object o) {
+        assertNull(o, null);
+    }
+
+    /**
+     * Asserts that {@code o} is null.
+     *
+     * @param o The reference assumed to be null.
+     * @param msg A description of the assumption; {@code null} for a default message.
+     * @throws RuntimeException if the assertion is not true.
+     */
+    public static void assertNull(Object o, String msg) {
+        assertEquals(o, null, msg);
+    }
+
+    /**
+     * Calls {@link #assertNotNull(Object, String)} with a default message.
+     *
+     * @param o The reference assumed <i>not</i> to be null,
+     * @see #assertNotNull(Object, String)
+     */
+    public static void assertNotNull(Object o) {
+        assertNotNull(o, null);
+    }
+
+    /**
+     * Asserts that {@code o} is <i>not</i> null.
+     *
+     * @param o The reference assumed <i>not</i> to be null,
+     * @param msg A description of the assumption; {@code null} for a default message.
+     * @throws RuntimeException if the assertion is not true.
+     */
+    public static void assertNotNull(Object o, String msg) {
+        assertNotEquals(o, null, msg);
+    }
+
+    /**
+     * Calls {@link #assertFalse(boolean, String)} with a default message.
+     *
+     * @param value The value assumed to be false.
+     * @see #assertFalse(boolean, String)
+     */
+    public static void assertFalse(boolean value) {
+        assertFalse(value, null);
+    }
+
+    /**
+     * Asserts that {@code value} is {@code false}.
+     *
+     * @param value The value assumed to be false.
+     * @param msg A description of the assumption; {@code null} for a default message.
+     * @throws RuntimeException if the assertion is not true.
+     */
+    public static void assertFalse(boolean value, String msg) {
+        if (value) {
+            msg = Objects.toString(msg, "assertFalse")
+                    + ": expected false, was true";
+            fail(msg);
+        }
+    }
+
+    /**
+     * Calls {@link #assertTrue(boolean, String)} with a default message.
+     *
+     * @param value The value assumed to be true.
+     * @see #assertTrue(boolean, String)
+     */
+    public static void assertTrue(boolean value) {
+        assertTrue(value, null);
+    }
+
+    /**
+     * Asserts that {@code value} is {@code true}.
+     *
+     * @param value The value assumed to be true.
+     * @param msg A description of the assumption; {@code null} for a default message.
+     * @throws RuntimeException if the assertion is not true.
+     */
+    public static void assertTrue(boolean value, String msg) {
+        if (!value) {
+            msg = Objects.toString(msg, "assertTrue")
+                    + ": expected true, was false";
+            fail(msg);
+        }
+    }
+
+    private static <T extends Comparable<T>> int compare(T lhs, T rhs, String msg) {
+        if (lhs == null || rhs == null) {
+            fail(lhs, rhs, msg + ": values must be non-null:", ",");
+        }
+        return lhs.compareTo(rhs);
+    }
+
+    /**
+     * Returns a string formatted with a message and expected and actual values.
+     * @param lhs the actual value
+     * @param rhs  the expected value
+     * @param message the actual value
+     * @param relation the asserted relationship between lhs and rhs
+     * @return a formatted string
+     */
+    public static String format(Object lhs, Object rhs, String message, String relation) {
+        StringBuilder sb = new StringBuilder(80);
+        if (message != null) {
+            sb.append(message);
+            sb.append(' ');
+        }
+        sb.append("<");
+        sb.append(Objects.toString(lhs));
+        sb.append("> ");
+        sb.append(Objects.toString(relation, ","));
+        sb.append(" <");
+        sb.append(Objects.toString(rhs));
+        sb.append(">");
+        return sb.toString();
+    }
+
+    /**
+     * Fail reports a failure with message fail.
+     *
+     * @throws RuntimeException always
+     */
+    public static void fail() {
+        fail("fail");
+    }
+
+    /**
+     * Fail reports a failure with a message.
+     * @param message for the failure
+     * @throws RuntimeException always
+     */
+    public static void fail(String message) {
+        throw new RuntimeException(message);
+    }
+
+    /**
+     * Fail reports a failure with a formatted message.
+     *
+     * @param lhs the actual value
+     * @param rhs the expected value
+     * @param message to be format before the expected and actual values
+     * @param relation the asserted relationship between lhs and rhs
+     * @throws RuntimeException always
+     */
+    public static void fail(Object lhs, Object rhs, String message, String relation) {
+        throw new RuntimeException(format(lhs, rhs, message, relation));
+    }
+
+    /**
+     * Fail reports a failure with a message and a cause.
+     * @param message to be format before the expected and actual values
+     * @param cause the exception that caused this failure
+     * @throws RuntimeException always
+     */
+    public static void fail(String message, Throwable cause) {
+        throw new RuntimeException(message, cause);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jdk/testlibrary/CompilerUtils.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2015, 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 jdk.testlibrary;
+
+import javax.tools.JavaCompiler;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * This class consists exclusively of static utility methods for invoking the
+ * java compiler.
+ */
+
+public final class CompilerUtils {
+    private CompilerUtils() { }
+
+    /**
+     * Compile all the java sources in {@code <source>/**} to
+     * {@code <destination>/**}. The destination directory will be created if
+     * it doesn't exist.
+     *
+     * All warnings/errors emitted by the compiler are output to System.out/err.
+     *
+     * @return true if the compilation is successful
+     *
+     * @throws IOException if there is an I/O error scanning the source tree or
+     *                     creating the destination directory
+     */
+    public static boolean compile(Path source, Path destination, String ... options)
+        throws IOException
+    {
+        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+        StandardJavaFileManager jfm = compiler.getStandardFileManager(null, null, null);
+
+        List<Path> sources
+            = Files.find(source, Integer.MAX_VALUE,
+                (file, attrs) -> (file.toString().endsWith(".java")))
+                .collect(Collectors.toList());
+
+        Files.createDirectories(destination);
+        jfm.setLocation(StandardLocation.CLASS_PATH, Collections.EMPTY_LIST);
+        jfm.setLocationFromPaths(StandardLocation.CLASS_OUTPUT,
+                                 Arrays.asList(destination));
+
+        List<String> opts = Arrays.asList(options);
+        JavaCompiler.CompilationTask task
+            = compiler.getTask(null, jfm, null, opts, null,
+                jfm.getJavaFileObjectsFromPaths(sources));
+
+        return task.call();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jdk/testlibrary/JDKToolFinder.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 jdk.testlibrary;
+
+import java.io.FileNotFoundException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+/**
+ * @deprecated This class is deprecated. Use the one from
+ *             {@code <root>/test/lib/share/classes/jdk/test/lib}
+ */
+@Deprecated
+public final class JDKToolFinder {
+
+    private JDKToolFinder() {
+    }
+
+    /**
+     * Returns the full path to an executable in jdk/bin based on System
+     * property {@code test.jdk} or {@code compile.jdk} (both are set by the jtreg test suite)
+     *
+     * @return Full path to an executable in jdk/bin
+     */
+    public static String getJDKTool(String tool) {
+
+        // First try to find the executable in test.jdk
+        try {
+            return getTool(tool, "test.jdk");
+        } catch (FileNotFoundException e) {
+
+        }
+
+        // Now see if it's available in compile.jdk
+        try {
+            return getTool(tool, "compile.jdk");
+        } catch (FileNotFoundException e) {
+            throw new RuntimeException("Failed to find " + tool +
+                    ", looked in test.jdk (" + System.getProperty("test.jdk") +
+                    ") and compile.jdk (" + System.getProperty("compile.jdk") + ")");
+        }
+    }
+
+    /**
+     * Returns the full path to an executable in jdk/bin based on System
+     * property {@code compile.jdk}
+     *
+     * @return Full path to an executable in jdk/bin
+     */
+    public static String getCompileJDKTool(String tool) {
+        try {
+            return getTool(tool, "compile.jdk");
+        } catch (FileNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Returns the full path to an executable in jdk/bin based on System
+     * property {@code test.jdk}
+     *
+     * @return Full path to an executable in jdk/bin
+     */
+    public static String getTestJDKTool(String tool) {
+        try {
+            return getTool(tool, "test.jdk");
+        } catch (FileNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static String getTool(String tool, String property) throws FileNotFoundException {
+        String jdkPath = System.getProperty(property);
+
+        if (jdkPath == null) {
+            throw new RuntimeException(
+                    "System property '" + property + "' not set. This property is normally set by jtreg. "
+                    + "When running test separately, set this property using '-D" + property + "=/path/to/jdk'.");
+        }
+
+        Path toolName = Paths.get("bin", tool + (Platform.isWindows() ? ".exe" : ""));
+
+        Path jdkTool = Paths.get(jdkPath, toolName.toString());
+        if (!jdkTool.toFile().exists()) {
+            throw new FileNotFoundException("Could not find file " + jdkTool.toAbsolutePath());
+        }
+
+        return jdkTool.toAbsolutePath().toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jdk/testlibrary/JDKToolLauncher.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 jdk.testlibrary;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A utility for constructing command lines for starting JDK tool processes.
+ *
+ * The JDKToolLauncher can in particular be combined with a
+ * java.lang.ProcessBuilder to easily run a JDK tool. For example, the following
+ * code run {@code jmap -heap} against a process with GC logging turned on for
+ * the {@code jmap} process:
+ *
+ * <pre>
+ * {@code
+ * JDKToolLauncher jmap = JDKToolLauncher.create("jmap")
+ *                                       .addVMArg("-Xlog:gc*=debug")
+ *                                       .addToolArg("-heap")
+ *                                       .addToolArg(pid);
+ * ProcessBuilder pb = new ProcessBuilder(jmap.getCommand());
+ * Process p = pb.start();
+ * }
+ * </pre>
+ * @deprecated This class is deprecated. Use the one from
+ *             {@code <root>/test/lib/share/classes/jdk/test/lib}
+ */
+@Deprecated
+public class JDKToolLauncher {
+    private final String executable;
+    private final List<String> vmArgs = new ArrayList<String>();
+    private final List<String> toolArgs = new ArrayList<String>();
+
+    private JDKToolLauncher(String tool, boolean useCompilerJDK) {
+        if (useCompilerJDK) {
+            executable = JDKToolFinder.getJDKTool(tool);
+        } else {
+            executable = JDKToolFinder.getTestJDKTool(tool);
+        }
+        vmArgs.addAll(Arrays.asList(ProcessTools.getPlatformSpecificVMArgs()));
+    }
+
+    /**
+     * Creates a new JDKToolLauncher for the specified tool. Using tools path
+     * from the compiler JDK.
+     *
+     * @param tool
+     *            The name of the tool
+     * @return A new JDKToolLauncher
+     */
+    public static JDKToolLauncher create(String tool) {
+        return new JDKToolLauncher(tool, true);
+    }
+
+    /**
+     * Creates a new JDKToolLauncher for the specified tool in the Tested JDK.
+     *
+     * @param tool
+     *            The name of the tool
+     *
+     * @return A new JDKToolLauncher
+     */
+    public static JDKToolLauncher createUsingTestJDK(String tool) {
+        return new JDKToolLauncher(tool, false);
+    }
+
+    /**
+     * Adds an argument to the JVM running the tool.
+     *
+     * The JVM arguments are passed to the underlying JVM running the tool.
+     * Arguments will automatically be prepended with "-J".
+     *
+     * Any platform specific arguments required for running the tool are
+     * automatically added.
+     *
+     *
+     * @param arg
+     *            The argument to VM running the tool
+     * @return The JDKToolLauncher instance
+     */
+    public JDKToolLauncher addVMArg(String arg) {
+        vmArgs.add(arg);
+        return this;
+    }
+
+    /**
+     * Adds an argument to the tool.
+     *
+     * @param arg
+     *            The argument to the tool
+     * @return The JDKToolLauncher instance
+     */
+    public JDKToolLauncher addToolArg(String arg) {
+        toolArgs.add(arg);
+        return this;
+    }
+
+    /**
+     * Returns the command that can be used for running the tool.
+     *
+     * @return An array whose elements are the arguments of the command.
+     */
+    public String[] getCommand() {
+        List<String> command = new ArrayList<String>();
+        command.add(executable);
+        // Add -J in front of all vmArgs
+        for (String arg : vmArgs) {
+            command.add("-J" + arg);
+        }
+        command.addAll(toolArgs);
+        return command.toArray(new String[command.size()]);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jdk/testlibrary/OutputAnalyzer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,576 @@
+/*
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.testlibrary;
+
+import static jdk.testlibrary.Asserts.*;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Utility class for verifying output and exit value from a {@code Process}.
+ *
+ * @deprecated  This class is deprecated. Use the one from
+ *              {@code <root>/test/lib/share/classes/jdk/test/lib/process}
+ *
+ */
+@Deprecated
+public final class OutputAnalyzer {
+    private final OutputBuffer output;
+    private final String stdout;
+    private final String stderr;
+    private final int exitValue;    // useless now. output contains exit value.
+
+    /**
+     * Create an OutputAnalyzer, a utility class for verifying output and exit
+     * value from a Process.
+     * <p>
+     * OutputAnalyzer should never be instantiated directly -
+     * use {@linkplain ProcessTools#executeProcess(ProcessBuilder)} instead
+     *
+     * @param process
+     *            Process to analyze
+     * @throws IOException
+     *             If an I/O error occurs.
+     */
+    OutputAnalyzer(Process process) throws IOException {
+        output = new OutputBuffer(process);
+        exitValue = -1;
+        this.stdout = null;
+        this.stderr = null;
+    }
+
+    /**
+     * Create an OutputAnalyzer, a utility class for verifying output.
+     *
+     * @param buf
+     *            String buffer to analyze
+     */
+    OutputAnalyzer(String buf) {
+        this(buf, buf);
+    }
+
+    /**
+     * Create an OutputAnalyzer, a utility class for verifying output
+     *
+     * @param stdout
+     *            stdout buffer to analyze
+     * @param stderr
+     *            stderr buffer to analyze
+     */
+    OutputAnalyzer(String stdout, String stderr) {
+        this.output = null;
+        this.stdout = stdout;
+        this.stderr = stderr;
+        exitValue = -1;
+    }
+
+    /**
+     * Verify that the stdout and stderr contents of output buffer contains the
+     * string
+     *
+     * @param expectedString
+     *            String that buffer should contain
+     * @throws RuntimeException
+     *             If the string was not found
+     */
+    public OutputAnalyzer shouldContain(String expectedString) {
+        if (!getStdout().contains(expectedString)
+                && !getStderr().contains(expectedString)) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + expectedString
+                    + "' missing from stdout/stderr \n");
+        }
+        return this;
+    }
+
+    /**
+     * Verify that the stdout contents of output buffer contains the string
+     *
+     * @param expectedString
+     *            String that buffer should contain
+     * @throws RuntimeException
+     *             If the string was not found
+     */
+    public OutputAnalyzer stdoutShouldContain(String expectedString) {
+        if (!getStdout().contains(expectedString)) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + expectedString
+                    + "' missing from stdout \n");
+        }
+        return this;
+    }
+
+    /**
+     * Verify that the stderr contents of output buffer contains the string
+     *
+     * @param expectedString
+     *            String that buffer should contain
+     * @throws RuntimeException
+     *             If the string was not found
+     */
+    public OutputAnalyzer stderrShouldContain(String expectedString) {
+        if (!getStderr().contains(expectedString)) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + expectedString
+                    + "' missing from stderr \n");
+        }
+        return this;
+    }
+
+    /**
+     * Verify that the stdout and stderr contents of output buffer does not
+     * contain the string
+     *
+     * @param notExpectedString
+     *            String that the buffer should not contain
+     * @throws RuntimeException
+     *             If the string was found
+     */
+    public OutputAnalyzer shouldNotContain(String notExpectedString) {
+        if (getStdout().contains(notExpectedString)) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + notExpectedString
+                    + "' found in stdout \n");
+        }
+        if (getStderr().contains(notExpectedString)) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + notExpectedString
+                    + "' found in stderr \n");
+        }
+        return this;
+    }
+
+    /**
+     * Verify that the stdout contents of output buffer does not contain the
+     * string
+     *
+     * @param notExpectedString
+     *            String that the buffer should not contain
+     * @throws RuntimeException
+     *             If the string was found
+     */
+    public OutputAnalyzer stdoutShouldNotContain(String notExpectedString) {
+        if (getStdout().contains(notExpectedString)) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + notExpectedString
+                    + "' found in stdout \n");
+        }
+        return this;
+    }
+
+    /**
+     * Verify that the stderr contents of output buffer does not contain the
+     * string
+     *
+     * @param notExpectedString
+     *            String that the buffer should not contain
+     * @throws RuntimeException
+     *             If the string was found
+     */
+    public OutputAnalyzer stderrShouldNotContain(String notExpectedString) {
+        if (getStderr().contains(notExpectedString)) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + notExpectedString
+                    + "' found in stderr \n");
+        }
+        return this;
+    }
+
+    /**
+     * Verify that the stdout and stderr contents of output buffer matches the
+     * pattern
+     *
+     * @param pattern
+     * @throws RuntimeException
+     *             If the pattern was not found
+     */
+    public OutputAnalyzer shouldMatch(String pattern) {
+        Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE)
+                .matcher(getStdout());
+        Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE)
+                .matcher(getStderr());
+        if (!stdoutMatcher.find() && !stderrMatcher.find()) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + pattern
+                    + "' missing from stdout/stderr \n");
+        }
+        return this;
+    }
+
+    /**
+     * Verify that the stdout contents of output buffer matches the pattern
+     *
+     * @param pattern
+     * @throws RuntimeException
+     *             If the pattern was not found
+     */
+    public OutputAnalyzer stdoutShouldMatch(String pattern) {
+        Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(
+                getStdout());
+        if (!matcher.find()) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + pattern
+                    + "' missing from stdout \n");
+        }
+        return this;
+    }
+
+    /**
+     * Verify that the stderr contents of output buffer matches the pattern
+     *
+     * @param pattern
+     * @throws RuntimeException
+     *             If the pattern was not found
+     */
+    public OutputAnalyzer stderrShouldMatch(String pattern) {
+        Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(
+                getStderr());
+        if (!matcher.find()) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + pattern
+                    + "' missing from stderr \n");
+        }
+        return this;
+    }
+
+    /**
+     * Verify that the stdout and stderr contents of output buffer does not
+     * match the pattern
+     *
+     * @param pattern
+     * @throws RuntimeException
+     *             If the pattern was found
+     */
+    public OutputAnalyzer shouldNotMatch(String pattern) {
+        Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(
+                getStdout());
+        if (matcher.find()) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + pattern + "' found in stdout: '"
+                    + matcher.group() + "' \n");
+        }
+        matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(getStderr());
+        if (matcher.find()) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + pattern + "' found in stderr: '"
+                    + matcher.group() + "' \n");
+        }
+        return this;
+    }
+
+    /**
+     * Verify that the stdout contents of output buffer does not match the
+     * pattern
+     *
+     * @param pattern
+     * @throws RuntimeException
+     *             If the pattern was found
+     */
+    public OutputAnalyzer stdoutShouldNotMatch(String pattern) {
+        Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(
+                getStdout());
+        if (matcher.find()) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + pattern + "' found in stdout \n");
+        }
+        return this;
+    }
+
+    /**
+     * Verify that the stderr contents of output buffer does not match the
+     * pattern
+     *
+     * @param pattern
+     * @throws RuntimeException
+     *             If the pattern was found
+     */
+    public OutputAnalyzer stderrShouldNotMatch(String pattern) {
+        Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(
+                getStderr());
+        if (matcher.find()) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("'" + pattern + "' found in stderr \n");
+        }
+        return this;
+    }
+
+    /**
+     * Get the captured group of the first string matching the pattern. stderr
+     * is searched before stdout.
+     *
+     * @param pattern
+     *            The multi-line pattern to match
+     * @param group
+     *            The group to capture
+     * @return The matched string or null if no match was found
+     */
+    public String firstMatch(String pattern, int group) {
+        Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE)
+                .matcher(getStderr());
+        Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE)
+                .matcher(getStdout());
+        if (stderrMatcher.find()) {
+            return stderrMatcher.group(group);
+        }
+        if (stdoutMatcher.find()) {
+            return stdoutMatcher.group(group);
+        }
+        return null;
+    }
+
+    /**
+     * Get the first string matching the pattern. stderr is searched before
+     * stdout.
+     *
+     * @param pattern
+     *            The multi-line pattern to match
+     * @return The matched string or null if no match was found
+     */
+    public String firstMatch(String pattern) {
+        return firstMatch(pattern, 0);
+    }
+
+    /**
+     * Verify the exit value of the process
+     *
+     * @param expectedExitValue
+     *            Expected exit value from process
+     * @throws RuntimeException
+     *             If the exit value from the process did not match the expected
+     *             value
+     */
+    public OutputAnalyzer shouldHaveExitValue(int expectedExitValue) {
+        if (getExitValue() != expectedExitValue) {
+            reportDiagnosticSummary();
+            throw new RuntimeException("Expected to get exit value of ["
+                    + expectedExitValue + "]\n");
+        }
+        return this;
+    }
+
+    /**
+     * Report summary that will help to diagnose the problem Currently includes:
+     * - standard input produced by the process under test - standard output -
+     * exit code Note: the command line is printed by the ProcessTools
+     */
+    private OutputAnalyzer reportDiagnosticSummary() {
+        String msg = " stdout: [" + getStdout() + "];\n" + " stderr: [" + getStderr()
+                + "]\n" + " exitValue = " + getExitValue() + "\n";
+
+        System.err.println(msg);
+        return this;
+    }
+
+    /**
+     * Get the contents of the output buffer (stdout and stderr)
+     *
+     * @return Content of the output buffer
+     */
+    public String getOutput() {
+        return getStdout() + getStderr();
+    }
+
+    /**
+     * Get the contents of the stdout buffer
+     *
+     * @return Content of the stdout buffer
+     */
+    public String getStdout() {
+        return output == null ? stdout : output.getStdout();
+    }
+
+    /**
+     * Get the contents of the stderr buffer
+     *
+     * @return Content of the stderr buffer
+     */
+    public String getStderr() {
+        return output == null ? stderr : output.getStderr();
+    }
+
+    /**
+     * Get the process exit value
+     *
+     * @return Process exit value
+     */
+    public int getExitValue() {
+        return output == null ? exitValue : output.getExitValue();
+    }
+
+
+    /**
+     * Print the stdout buffer to the given {@code PrintStream}.
+     *
+     * @return this OutputAnalyzer
+     */
+    public OutputAnalyzer outputTo(PrintStream out) {
+        out.println(getStdout());
+        return this;
+    }
+
+    /**
+     * Print the stderr buffer to the given {@code PrintStream}.
+     *
+     * @return this OutputAnalyzer
+     */
+    public OutputAnalyzer errorTo(PrintStream out) {
+        out.println(getStderr());
+        return this;
+    }
+
+
+    /**
+     * Get the contents of the output buffer (stdout and stderr) as list of strings.
+     * Output will be split by system property 'line.separator'.
+     *
+     * @return Contents of the output buffer as list of strings
+     */
+    public List<String> asLines() {
+        return asLines(getOutput());
+    }
+
+    private List<String> asLines(String buffer) {
+        List<String> l = new ArrayList<>();
+        String[] a = buffer.split(Utils.NEW_LINE);
+        for (String string : a) {
+            l.add(string);
+        }
+        return l;
+    }
+
+    /**
+     * Check if there is a line matching {@code pattern} and return its index
+     *
+     * @param pattern Matching pattern
+     * @return Index of first matching line
+     */
+    private int indexOf(List<String> lines, String pattern) {
+        for (int i = 0; i < lines.size(); i++) {
+            if (lines.get(i).matches(pattern)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * @see #shouldMatchByLine(String, String, String)
+     */
+    public int shouldMatchByLine(String pattern) {
+        return shouldMatchByLine(null, null, pattern);
+    }
+
+    /**
+     * @see #stdoutShouldMatchByLine(String, String, String)
+     */
+    public int stdoutShouldMatchByLine(String pattern) {
+        return stdoutShouldMatchByLine(null, null, pattern);
+    }
+
+    /**
+     * @see #shouldMatchByLine(String, String, String)
+     */
+    public int shouldMatchByLineFrom(String from, String pattern) {
+        return shouldMatchByLine(from, null, pattern);
+    }
+
+    /**
+     * @see #shouldMatchByLine(String, String, String)
+     */
+    public int shouldMatchByLineTo(String to, String pattern) {
+        return shouldMatchByLine(null, to, pattern);
+    }
+
+    /**
+     * Verify that the stdout and stderr contents of output buffer match the
+     * {@code pattern} line by line. The whole output could be matched or
+     * just a subset of it.
+     *
+     * @param from
+     *            The line from where output will be matched.
+     *            Set {@code from} to null for matching from the first line.
+     * @param to
+     *            The line until where output will be matched.
+     *            Set {@code to} to null for matching until the last line.
+     * @param pattern
+     *            Matching pattern
+     * @return Count of lines which match the {@code pattern}
+     */
+    public int shouldMatchByLine(String from, String to, String pattern) {
+        return shouldMatchByLine(getOutput(), from, to, pattern);
+    }
+
+    /**
+     * Verify that the stdout contents of output buffer matches the
+     * {@code pattern} line by line. The whole stdout could be matched or
+     * just a subset of it.
+     *
+     * @param from
+     *            The line from where stdout will be matched.
+     *            Set {@code from} to null for matching from the first line.
+     * @param to
+     *            The line until where stdout will be matched.
+     *            Set {@code to} to null for matching until the last line.
+     * @param pattern
+     *            Matching pattern
+     * @return Count of lines which match the {@code pattern}
+     */
+    public int stdoutShouldMatchByLine(String from, String to, String pattern) {
+        return shouldMatchByLine(getStdout(), from, to, pattern);
+    }
+
+    private int shouldMatchByLine(String buffer, String from, String to, String pattern) {
+        List<String> lines = asLines(buffer);
+
+        int fromIndex = 0;
+        if (from != null) {
+            fromIndex = indexOf(lines, from);
+            assertGreaterThan(fromIndex, -1,
+                    "The line/pattern '" + from + "' from where the output should match can not be found");
+        }
+
+        int toIndex = lines.size();
+        if (to != null) {
+            toIndex = indexOf(lines, to);
+            assertGreaterThan(toIndex, -1,
+                    "The line/pattern '" + to + "' until where the output should match can not be found");
+        }
+
+        List<String> subList = lines.subList(fromIndex, toIndex);
+        int matchedCount = 0;
+        for (String line : subList) {
+            assertTrue(line.matches(pattern),
+                    "The line '" + line + "' does not match pattern '" + pattern + "'");
+            matchedCount++;
+        }
+
+        return matchedCount;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jdk/testlibrary/OutputBuffer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.testlibrary;
+
+import java.io.ByteArrayOutputStream;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+/**
+ * @deprecated This class is deprecated. Use the one from
+ *             {@code <root>/test/lib/share/classes/jdk/test/lib/process}
+ */
+@Deprecated
+class OutputBuffer {
+    private static class OutputBufferException extends RuntimeException {
+        private static final long serialVersionUID = 8528687792643129571L;
+
+        public OutputBufferException(Throwable cause) {
+            super(cause);
+        }
+    }
+
+    private final Process p;
+    private final Future<Void> outTask;
+    private final Future<Void> errTask;
+    private final ByteArrayOutputStream stderrBuffer = new ByteArrayOutputStream();
+    private final ByteArrayOutputStream stdoutBuffer = new ByteArrayOutputStream();
+
+    /**
+     * Create an OutputBuffer, a class for storing and managing stdout and
+     * stderr results separately
+     *
+     * @param stdout
+     *            stdout result
+     * @param stderr
+     *            stderr result
+     */
+    OutputBuffer(Process p) {
+        this.p = p;
+        StreamPumper outPumper = new StreamPumper(p.getInputStream(),
+                stdoutBuffer);
+        StreamPumper errPumper = new StreamPumper(p.getErrorStream(),
+                stderrBuffer);
+
+        outTask = outPumper.process();
+        errTask = errPumper.process();
+    }
+
+    /**
+     * Returns the stdout result
+     *
+     * @return stdout result
+     */
+    public String getStdout() {
+        try {
+            outTask.get();
+            return stdoutBuffer.toString();
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw new OutputBufferException(e);
+        } catch (ExecutionException | CancellationException e) {
+            throw new OutputBufferException(e);
+        }
+    }
+
+    /**
+     * Returns the stderr result
+     *
+     * @return stderr result
+     */
+    public String getStderr() {
+        try {
+            errTask.get();
+            return stderrBuffer.toString();
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw new OutputBufferException(e);
+        } catch (ExecutionException | CancellationException e) {
+            throw new OutputBufferException(e);
+        }
+    }
+
+    public int getExitValue() {
+        try {
+            return p.waitFor();
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw new OutputBufferException(e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jdk/testlibrary/Platform.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2013, 2015, 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 jdk.testlibrary;
+import java.util.regex.Pattern;
+import java.io.RandomAccessFile;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+/**
+ * @deprecated This class is deprecated. Use the one from
+ *             {@code <root>/test/lib/share/classes/jdk/test/lib}
+ */
+@Deprecated
+public class Platform {
+    private static final String osName      = System.getProperty("os.name");
+    private static final String dataModel   = System.getProperty("sun.arch.data.model");
+    private static final String vmVersion   = System.getProperty("java.vm.version");
+    private static final String jdkDebug    = System.getProperty("jdk.debug");
+    private static final String osArch      = System.getProperty("os.arch");
+    private static final String vmName      = System.getProperty("java.vm.name");
+    private static final String userName    = System.getProperty("user.name");
+    private static final String compiler    = System.getProperty("sun.management.compiler");
+
+    public static boolean isClient() {
+        return vmName.endsWith(" Client VM");
+    }
+
+    public static boolean isServer() {
+        return vmName.endsWith(" Server VM");
+    }
+
+    public static boolean isGraal() {
+        return vmName.endsWith(" Graal VM");
+    }
+
+    public static boolean isMinimal() {
+        return vmName.endsWith(" Minimal VM");
+    }
+
+    public static boolean isEmbedded() {
+        return vmName.contains("Embedded");
+    }
+
+    public static boolean isTieredSupported() {
+        return compiler.contains("Tiered Compilers");
+    }
+
+
+    public static boolean is32bit() {
+        return dataModel.equals("32");
+    }
+
+    public static boolean is64bit() {
+        return dataModel.equals("64");
+    }
+
+    public static boolean isAix() {
+        return isOs("aix");
+    }
+
+    public static boolean isLinux() {
+        return isOs("linux");
+    }
+
+    public static boolean isOSX() {
+        return isOs("mac");
+    }
+
+    public static boolean isSolaris() {
+        return isOs("sunos");
+    }
+
+    public static boolean isWindows() {
+        return isOs("win");
+    }
+
+    private static boolean isOs(String osname) {
+        return osName.toLowerCase().startsWith(osname.toLowerCase());
+    }
+
+    public static String getOsName() {
+        return osName;
+    }
+
+    public static boolean isDebugBuild() {
+        return (jdkDebug.toLowerCase().contains("debug"));
+    }
+
+    public static String getVMVersion() {
+        return vmVersion;
+    }
+
+    // Returns true for sparc and sparcv9.
+    public static boolean isSparc() {
+        return isArch("sparc.*");
+    }
+
+    public static boolean isARM() {
+        return isArch("arm.*");
+    }
+
+    public static boolean isPPC() {
+        return isArch("ppc.*");
+    }
+
+    public static boolean isX86() {
+        // On Linux it's 'i386', Windows 'x86' without '_64' suffix.
+        return isArch("(i386)|(x86(?!_64))");
+    }
+
+    public static boolean isX64() {
+        // On OSX it's 'x86_64' and on other (Linux, Windows and Solaris) platforms it's 'amd64'
+        return isArch("(amd64)|(x86_64)");
+    }
+
+    private static boolean isArch(String archnameRE) {
+        return Pattern.compile(archnameRE, Pattern.CASE_INSENSITIVE)
+                .matcher(osArch)
+                .matches();
+    }
+
+    public static String getOsArch() {
+        return osArch;
+    }
+
+    /**
+     * Return a boolean for whether we expect to be able to attach
+     * the SA to our own processes on this system.
+     */
+    public static boolean shouldSAAttach()
+                               throws IOException {
+
+        if (isAix()) {
+            return false;   // SA not implemented.
+        } else if (isLinux()) {
+            return canPtraceAttachLinux();
+        } else if (isOSX()) {
+            return canAttachOSX();
+        } else {
+            // Other platforms expected to work:
+            return true;
+        }
+    }
+
+    /**
+     * On Linux, first check the SELinux boolean "deny_ptrace" and return false
+     * as we expect to be denied if that is "1".
+     */
+    public static boolean canPtraceAttachLinux()
+                               throws IOException {
+
+        // SELinux deny_ptrace:
+        try(RandomAccessFile file = new RandomAccessFile("/sys/fs/selinux/booleans/deny_ptrace", "r")) {
+            if (file.readByte() != '0') {
+                return false;
+            }
+        }
+        catch(FileNotFoundException ex) {
+            // Ignored
+        }
+
+        // YAMA enhanced security ptrace_scope:
+        // 0 - a process can PTRACE_ATTACH to any other process running under the same uid
+        // 1 - restricted ptrace: a process must be a children of the inferior or user is root
+        // 2 - only processes with CAP_SYS_PTRACE may use ptrace or user is root
+        // 3 - no attach: no processes may use ptrace with PTRACE_ATTACH
+
+        try(RandomAccessFile file = new RandomAccessFile("/proc/sys/kernel/yama/ptrace_scope", "r")) {
+            byte yama_scope = file.readByte();
+            if (yama_scope == '3') {
+                return false;
+            }
+
+            if (!userName.equals("root") && yama_scope != '0') {
+                return false;
+            }
+        }
+        catch(FileNotFoundException ex) {
+            // Ignored
+        }
+
+        // Otherwise expect to be permitted:
+        return true;
+    }
+
+    /**
+     * On OSX, expect permission to attach only if we are root.
+     */
+    public static boolean canAttachOSX() {
+        return userName.equals("root");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jdk/testlibrary/ProcessTools.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,579 @@
+/*
+ * Copyright (c) 2013, 2015, 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 jdk.testlibrary;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.concurrent.CountDownLatch;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.function.Predicate;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+
+
+/**
+ * @deprecated This class is deprecated. Use the one from
+ *             {@code <root>/test/lib/share/classes/jdk/test/lib/process}
+ */
+@Deprecated
+public final class ProcessTools {
+    private static final class LineForwarder extends StreamPumper.LinePump {
+        private final PrintStream ps;
+        private final String prefix;
+        LineForwarder(String prefix, PrintStream os) {
+            this.ps = os;
+            this.prefix = prefix;
+        }
+        @Override
+        protected void processLine(String line) {
+            ps.println("[" + prefix + "] " + line);
+        }
+    }
+
+    private ProcessTools() {
+    }
+
+    /**
+     * <p>Starts a process from its builder.</p>
+     * <span>The default redirects of STDOUT and STDERR are started</span>
+     * @param name The process name
+     * @param processBuilder The process builder
+     * @return Returns the initialized process
+     * @throws IOException
+     */
+    public static Process startProcess(String name,
+                                       ProcessBuilder processBuilder)
+    throws IOException {
+        return startProcess(name, processBuilder, (Consumer<String>)null);
+    }
+
+    /**
+     * <p>Starts a process from its builder.</p>
+     * <span>The default redirects of STDOUT and STDERR are started</span>
+     * <p>It is possible to monitor the in-streams via the provided {@code consumer}
+     * @param name The process name
+     * @param consumer {@linkplain Consumer} instance to process the in-streams
+     * @param processBuilder The process builder
+     * @return Returns the initialized process
+     * @throws IOException
+     */
+    @SuppressWarnings("overloads")
+    public static Process startProcess(String name,
+                                       ProcessBuilder processBuilder,
+                                       Consumer<String> consumer)
+    throws IOException {
+        try {
+            return startProcess(name, processBuilder, consumer, null, -1, TimeUnit.NANOSECONDS);
+        } catch (InterruptedException | TimeoutException e) {
+            // will never happen
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * <p>Starts a process from its builder.</p>
+     * <span>The default redirects of STDOUT and STDERR are started</span>
+     * <p>
+     * It is possible to wait for the process to get to a warmed-up state
+     * via {@linkplain Predicate} condition on the STDOUT
+     * </p>
+     * @param name The process name
+     * @param processBuilder The process builder
+     * @param linePredicate The {@linkplain Predicate} to use on the STDOUT
+     *                      Used to determine the moment the target app is
+     *                      properly warmed-up.
+     *                      It can be null - in that case the warmup is skipped.
+     * @param timeout The timeout for the warmup waiting; -1 = no wait; 0 = wait forever
+     * @param unit The timeout {@linkplain TimeUnit}
+     * @return Returns the initialized {@linkplain Process}
+     * @throws IOException
+     * @throws InterruptedException
+     * @throws TimeoutException
+     */
+    public static Process startProcess(String name,
+                                       ProcessBuilder processBuilder,
+                                       final Predicate<String> linePredicate,
+                                       long timeout,
+                                       TimeUnit unit)
+    throws IOException, InterruptedException, TimeoutException {
+        return startProcess(name, processBuilder, null, linePredicate, timeout, unit);
+    }
+
+    /**
+     * <p>Starts a process from its builder.</p>
+     * <span>The default redirects of STDOUT and STDERR are started</span>
+     * <p>
+     * It is possible to wait for the process to get to a warmed-up state
+     * via {@linkplain Predicate} condition on the STDOUT and monitor the
+     * in-streams via the provided {@linkplain Consumer}
+     * </p>
+     * @param name The process name
+     * @param processBuilder The process builder
+     * @param lineConsumer  The {@linkplain Consumer} the lines will be forwarded to
+     * @param linePredicate The {@linkplain Predicate} to use on the STDOUT
+     *                      Used to determine the moment the target app is
+     *                      properly warmed-up.
+     *                      It can be null - in that case the warmup is skipped.
+     * @param timeout The timeout for the warmup waiting; -1 = no wait; 0 = wait forever
+     * @param unit The timeout {@linkplain TimeUnit}
+     * @return Returns the initialized {@linkplain Process}
+     * @throws IOException
+     * @throws InterruptedException
+     * @throws TimeoutException
+     */
+    public static Process startProcess(String name,
+                                       ProcessBuilder processBuilder,
+                                       final Consumer<String> lineConsumer,
+                                       final Predicate<String> linePredicate,
+                                       long timeout,
+                                       TimeUnit unit)
+    throws IOException, InterruptedException, TimeoutException {
+        System.out.println("["+name+"]:" + processBuilder.command().stream().collect(Collectors.joining(" ")));
+        Process p = processBuilder.start();
+        StreamPumper stdout = new StreamPumper(p.getInputStream());
+        StreamPumper stderr = new StreamPumper(p.getErrorStream());
+
+        stdout.addPump(new LineForwarder(name, System.out));
+        stderr.addPump(new LineForwarder(name, System.err));
+        if (lineConsumer != null) {
+            StreamPumper.LinePump pump = new StreamPumper.LinePump() {
+                @Override
+                protected void processLine(String line) {
+                    lineConsumer.accept(line);
+                }
+            };
+            stdout.addPump(pump);
+            stderr.addPump(pump);
+        }
+
+
+        CountDownLatch latch = new CountDownLatch(1);
+        if (linePredicate != null) {
+            StreamPumper.LinePump pump = new StreamPumper.LinePump() {
+                @Override
+                protected void processLine(String line) {
+                    if (latch.getCount() > 0 && linePredicate.test(line)) {
+                        latch.countDown();
+                    }
+                }
+            };
+            stdout.addPump(pump);
+            stderr.addPump(pump);
+        } else {
+            latch.countDown();
+        }
+        final Future<Void> stdoutTask = stdout.process();
+        final Future<Void> stderrTask = stderr.process();
+
+        try {
+            if (timeout > -1) {
+                if (timeout == 0) {
+                    latch.await();
+                } else {
+                    if (!latch.await(Utils.adjustTimeout(timeout), unit)) {
+                        throw new TimeoutException();
+                    }
+                }
+            }
+        } catch (TimeoutException | InterruptedException e) {
+            System.err.println("Failed to start a process (thread dump follows)");
+            for(Map.Entry<Thread, StackTraceElement[]> s : Thread.getAllStackTraces().entrySet()) {
+                printStack(s.getKey(), s.getValue());
+            }
+
+            if (p.isAlive()) {
+                p.destroyForcibly();
+            }
+
+            stdoutTask.cancel(true);
+            stderrTask.cancel(true);
+            throw e;
+        }
+
+        return new ProcessImpl(p, stdoutTask, stderrTask);
+    }
+
+    /**
+     * <p>Starts a process from its builder.</p>
+     * <span>The default redirects of STDOUT and STDERR are started</span>
+     * <p>
+     * It is possible to wait for the process to get to a warmed-up state
+     * via {@linkplain Predicate} condition on the STDOUT. The warm-up will
+     * wait indefinitely.
+     * </p>
+     * @param name The process name
+     * @param processBuilder The process builder
+     * @param linePredicate The {@linkplain Predicate} to use on the STDOUT
+     *                      Used to determine the moment the target app is
+     *                      properly warmed-up.
+     *                      It can be null - in that case the warmup is skipped.
+     * @return Returns the initialized {@linkplain Process}
+     * @throws IOException
+     * @throws InterruptedException
+     * @throws TimeoutException
+     */
+    @SuppressWarnings("overloads")
+    public static Process startProcess(String name,
+                                       ProcessBuilder processBuilder,
+                                       final Predicate<String> linePredicate)
+    throws IOException, InterruptedException, TimeoutException {
+        return startProcess(name, processBuilder, linePredicate, 0, TimeUnit.SECONDS);
+    }
+
+    /**
+     * Get the process id of the current running Java process
+     *
+     * @return Process id
+     */
+    public static long getProcessId() {
+        return ProcessHandle.current().getPid();
+    }
+
+    /**
+     * Get platform specific VM arguments (e.g. -d64 on 64bit Solaris)
+     *
+     * @return String[] with platform specific arguments, empty if there are
+     *         none
+     */
+    public static String[] getPlatformSpecificVMArgs() {
+        String osName = System.getProperty("os.name");
+        String dataModel = System.getProperty("sun.arch.data.model");
+
+        if (osName.equals("SunOS") && dataModel.equals("64")) {
+            return new String[] { "-d64" };
+        }
+
+        return new String[] {};
+    }
+
+    /**
+     * Create ProcessBuilder using the java launcher from the jdk to be tested,
+     * and with any platform specific arguments prepended.
+     *
+     * @param command Arguments to pass to the java command.
+     * @return The ProcessBuilder instance representing the java command.
+     */
+    public static ProcessBuilder createJavaProcessBuilder(String... command)
+            throws Exception {
+        return createJavaProcessBuilder(false, command);
+    }
+
+    /**
+     * Create ProcessBuilder using the java launcher from the jdk to be tested,
+     * and with any platform specific arguments prepended.
+     *
+     * @param addTestVmAndJavaOptions If true, adds test.vm.opts and test.java.opts
+     *        to the java arguments.
+     * @param command Arguments to pass to the java command.
+     * @return The ProcessBuilder instance representing the java command.
+     */
+    public static ProcessBuilder createJavaProcessBuilder(boolean addTestVmAndJavaOptions, String... command) throws Exception {
+        String javapath = JDKToolFinder.getJDKTool("java");
+
+        ArrayList<String> args = new ArrayList<>();
+        args.add(javapath);
+        Collections.addAll(args, getPlatformSpecificVMArgs());
+
+        if (addTestVmAndJavaOptions) {
+            // -cp is needed to make sure the same classpath is used whether the test is
+            // run in AgentVM mode or OtherVM mode. It was added to the hotspot version
+            // of this API as part of 8077608. However, for the jdk version it is only
+            // added when addTestVmAndJavaOptions is true in order to minimize
+            // disruption to existing JDK tests, which have yet to be tested with -cp
+            // being added. At some point -cp should always be added to be consistent
+            // with what the hotspot version does.
+            args.add("-cp");
+            args.add(System.getProperty("java.class.path"));
+            Collections.addAll(args, Utils.getTestJavaOpts());
+        }
+
+        Collections.addAll(args, command);
+
+        // Reporting
+        StringBuilder cmdLine = new StringBuilder();
+        for (String cmd : args)
+            cmdLine.append(cmd).append(' ');
+        System.out.println("Command line: [" + cmdLine.toString() + "]");
+
+        return new ProcessBuilder(args.toArray(new String[args.size()]));
+    }
+
+    private static void printStack(Thread t, StackTraceElement[] stack) {
+        System.out.println("\t" +  t +
+                           " stack: (length = " + stack.length + ")");
+        if (t != null) {
+            for (StackTraceElement stack1 : stack) {
+                System.out.println("\t" + stack1);
+            }
+            System.out.println();
+        }
+    }
+
+    /**
+     * Executes a test java process, waits for it to finish and returns the process output.
+     * The default options from jtreg, test.vm.opts and test.java.opts, are added.
+     * The java from the test.jdk is used to execute the command.
+     *
+     * The command line will be like:
+     * {test.jdk}/bin/java {test.vm.opts} {test.java.opts} cmds
+     *
+     * The java process will have exited before this method returns.
+     *
+     * @param cmds User specifed arguments.
+     * @return The output from the process.
+     */
+    public static OutputAnalyzer executeTestJava(String... options) throws Exception {
+        ProcessBuilder pb = createJavaProcessBuilder(Utils.addTestJavaOpts(options));
+        return executeProcess(pb);
+    }
+
+    /**
+     * @deprecated Use executeTestJava instead
+     */
+    public static OutputAnalyzer executeTestJvm(String... options) throws Exception {
+        return executeTestJava(options);
+    }
+
+    /**
+     * Executes a process, waits for it to finish and returns the process output.
+     * The process will have exited before this method returns.
+     * @param pb The ProcessBuilder to execute.
+     * @return The {@linkplain OutputAnalyzer} instance wrapping the process.
+     */
+    public static OutputAnalyzer executeProcess(ProcessBuilder pb) throws Exception {
+        return executeProcess(pb, null);
+    }
+
+    /**
+     * Executes a process, pipe some text into its STDIN, waits for it
+     * to finish and returns the process output. The process will have exited
+     * before this method returns.
+     * @param pb The ProcessBuilder to execute.
+     * @param input The text to pipe into STDIN. Can be null.
+     * @return The {@linkplain OutputAnalyzer} instance wrapping the process.
+     */
+    public static OutputAnalyzer executeProcess(ProcessBuilder pb, String input)
+            throws Exception {
+        OutputAnalyzer output = null;
+        Process p = null;
+        boolean failed = false;
+        try {
+            p = pb.start();
+            if (input != null) {
+                try (OutputStream os = p.getOutputStream();
+                        PrintStream ps = new PrintStream(os)) {
+                    ps.print(input);
+                    ps.flush();
+                }
+            }
+            output = new OutputAnalyzer(p);
+            p.waitFor();
+
+            return output;
+        } catch (Throwable t) {
+            if (p != null) {
+                p.destroyForcibly().waitFor();
+            }
+
+            failed = true;
+            System.out.println("executeProcess() failed: " + t);
+            throw t;
+        } finally {
+            if (failed) {
+                System.err.println(getProcessLog(pb, output));
+            }
+        }
+    }
+
+    /**
+     * Executes a process, waits for it to finish and returns the process output.
+     *
+     * The process will have exited before this method returns.
+     *
+     * @param cmds The command line to execute.
+     * @return The output from the process.
+     */
+    public static OutputAnalyzer executeProcess(String... cmds) throws Throwable {
+        return executeProcess(new ProcessBuilder(cmds));
+    }
+
+    /**
+     * Used to log command line, stdout, stderr and exit code from an executed process.
+     * @param pb The executed process.
+     * @param output The output from the process.
+     */
+    public static String getProcessLog(ProcessBuilder pb, OutputAnalyzer output) {
+        String stderr = output == null ? "null" : output.getStderr();
+        String stdout = output == null ? "null" : output.getStdout();
+        String exitValue = output == null ? "null": Integer.toString(output.getExitValue());
+        StringBuilder logMsg = new StringBuilder();
+        final String nl = System.getProperty("line.separator");
+        logMsg.append("--- ProcessLog ---" + nl);
+        logMsg.append("cmd: " + getCommandLine(pb) + nl);
+        logMsg.append("exitvalue: " + exitValue + nl);
+        logMsg.append("stderr: " + stderr + nl);
+        logMsg.append("stdout: " + stdout + nl);
+
+        return logMsg.toString();
+    }
+
+    /**
+     * @return The full command line for the ProcessBuilder.
+     */
+    public static String getCommandLine(ProcessBuilder pb) {
+        if (pb == null) {
+            return "null";
+        }
+        StringBuilder cmd = new StringBuilder();
+        for (String s : pb.command()) {
+            cmd.append(s).append(" ");
+        }
+        return cmd.toString().trim();
+    }
+
+    /**
+     * Executes a process, waits for it to finish, prints the process output
+     * to stdout, and returns the process output.
+     *
+     * The process will have exited before this method returns.
+     *
+     * @param cmds The command line to execute.
+     * @return The {@linkplain OutputAnalyzer} instance wrapping the process.
+     */
+    public static OutputAnalyzer executeCommand(String... cmds)
+            throws Throwable {
+        String cmdLine = Arrays.stream(cmds).collect(Collectors.joining(" "));
+        System.out.println("Command line: [" + cmdLine + "]");
+        OutputAnalyzer analyzer = ProcessTools.executeProcess(cmds);
+        System.out.println(analyzer.getOutput());
+        return analyzer;
+    }
+
+    /**
+     * Executes a process, waits for it to finish, prints the process output
+     * to stdout and returns the process output.
+     *
+     * The process will have exited before this method returns.
+     *
+     * @param pb The ProcessBuilder to execute.
+     * @return The {@linkplain OutputAnalyzer} instance wrapping the process.
+     */
+    public static OutputAnalyzer executeCommand(ProcessBuilder pb)
+            throws Throwable {
+        String cmdLine = pb.command().stream().collect(Collectors.joining(" "));
+        System.out.println("Command line: [" + cmdLine + "]");
+        OutputAnalyzer analyzer = ProcessTools.executeProcess(pb);
+        System.out.println(analyzer.getOutput());
+        return analyzer;
+    }
+
+    private static class ProcessImpl extends Process {
+
+        private final Process p;
+        private final Future<Void> stdoutTask;
+        private final Future<Void> stderrTask;
+
+        public ProcessImpl(Process p, Future<Void> stdoutTask, Future<Void> stderrTask) {
+            this.p = p;
+            this.stdoutTask = stdoutTask;
+            this.stderrTask = stderrTask;
+        }
+
+        @Override
+        public OutputStream getOutputStream() {
+            return p.getOutputStream();
+        }
+
+        @Override
+        public InputStream getInputStream() {
+            return p.getInputStream();
+        }
+
+        @Override
+        public InputStream getErrorStream() {
+            return p.getErrorStream();
+        }
+
+        @Override
+        public int waitFor() throws InterruptedException {
+            int rslt = p.waitFor();
+            waitForStreams();
+            return rslt;
+        }
+
+        @Override
+        public int exitValue() {
+            return p.exitValue();
+        }
+
+        @Override
+        public void destroy() {
+            p.destroy();
+        }
+
+        @Override
+        public long getPid() {
+            return p.getPid();
+        }
+
+        @Override
+        public boolean isAlive() {
+            return p.isAlive();
+        }
+
+        @Override
+        public Process destroyForcibly() {
+            return p.destroyForcibly();
+        }
+
+        @Override
+        public boolean waitFor(long timeout, TimeUnit unit) throws InterruptedException {
+            boolean rslt = p.waitFor(timeout, unit);
+            if (rslt) {
+                waitForStreams();
+            }
+            return rslt;
+        }
+
+        private void waitForStreams() throws InterruptedException {
+            try {
+                stdoutTask.get();
+            } catch (ExecutionException e) {
+            }
+            try {
+                stderrTask.get();
+            } catch (ExecutionException e) {
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jdk/testlibrary/README.txt	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,1 @@
+These files are copies of the corresponding files in test/lib/testlibrary/ from jdk repo.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jdk/testlibrary/StreamPumper.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 jdk.testlibrary;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * @deprecated This class is deprecated. Use the one from
+ *             {@code <root>/test/lib/share/classes/jdk/test/lib/process}
+ */
+@Deprecated
+public final class StreamPumper implements Runnable {
+
+    private static final int BUF_SIZE = 256;
+
+    /**
+     * Pump will be called by the StreamPumper to process the incoming data
+     */
+    abstract public static class Pump {
+        abstract void register(StreamPumper d);
+    }
+
+    /**
+     * OutputStream -> Pump adapter
+     */
+    final public static class StreamPump extends Pump {
+        private final OutputStream out;
+        public StreamPump(OutputStream out) {
+            this.out = out;
+        }
+
+        @Override
+        void register(StreamPumper sp) {
+            sp.addOutputStream(out);
+        }
+    }
+
+    /**
+     * Used to process the incoming data line-by-line
+     */
+    abstract public static class LinePump extends Pump {
+        @Override
+        final void register(StreamPumper sp) {
+            sp.addLineProcessor(this);
+        }
+
+        abstract protected void processLine(String line);
+    }
+
+    private final InputStream in;
+    private final Set<OutputStream> outStreams = new HashSet<>();
+    private final Set<LinePump> linePumps = new HashSet<>();
+
+    private final AtomicBoolean processing = new AtomicBoolean(false);
+    private final FutureTask<Void> processingTask = new FutureTask<>(this, null);
+
+    public StreamPumper(InputStream in) {
+        this.in = in;
+    }
+
+    /**
+     * Create a StreamPumper that reads from in and writes to out.
+     *
+     * @param in
+     *            The stream to read from.
+     * @param out
+     *            The stream to write to.
+     */
+    public StreamPumper(InputStream in, OutputStream out) {
+        this(in);
+        this.addOutputStream(out);
+    }
+
+    /**
+     * Implements Thread.run(). Continuously read from {@code in} and write to
+     * {@code out} until {@code in} has reached end of stream. Abort on
+     * interruption. Abort on IOExceptions.
+     */
+    @Override
+    public void run() {
+        try (BufferedInputStream is = new BufferedInputStream(in)) {
+            ByteArrayOutputStream lineBos = new ByteArrayOutputStream();
+            byte[] buf = new byte[BUF_SIZE];
+            int len = 0;
+            int linelen = 0;
+
+            while ((len = is.read(buf)) > 0 && !Thread.interrupted()) {
+                for(OutputStream out : outStreams) {
+                    out.write(buf, 0, len);
+                }
+                if (!linePumps.isEmpty()) {
+                    int i = 0;
+                    int lastcrlf = -1;
+                    while (i < len) {
+                        if (buf[i] == '\n' || buf[i] == '\r') {
+                            int bufLinelen = i - lastcrlf - 1;
+                            if (bufLinelen > 0) {
+                                lineBos.write(buf, lastcrlf + 1, bufLinelen);
+                            }
+                            linelen += bufLinelen;
+
+                            if (linelen > 0) {
+                                lineBos.flush();
+                                final String line = lineBos.toString();
+                                linePumps.stream().forEach((lp) -> {
+                                    lp.processLine(line);
+                                });
+                                lineBos.reset();
+                                linelen = 0;
+                            }
+                            lastcrlf = i;
+                        }
+
+                        i++;
+                    }
+                    if (lastcrlf == -1) {
+                        lineBos.write(buf, 0, len);
+                        linelen += len;
+                    } else if (lastcrlf < len - 1) {
+                        lineBos.write(buf, lastcrlf + 1, len - lastcrlf - 1);
+                        linelen += len - lastcrlf - 1;
+                    }
+                }
+            }
+
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            for(OutputStream out : outStreams) {
+                try {
+                    out.flush();
+                } catch (IOException e) {}
+            }
+            try {
+                in.close();
+            } catch (IOException e) {}
+        }
+    }
+
+    final void addOutputStream(OutputStream out) {
+        outStreams.add(out);
+    }
+
+    final void addLineProcessor(LinePump lp) {
+        linePumps.add(lp);
+    }
+
+    final public StreamPumper addPump(Pump ... pump) {
+        if (processing.get()) {
+            throw new IllegalStateException("Can not modify pumper while " +
+                                            "processing is in progress");
+        }
+        for(Pump p : pump) {
+            p.register(this);
+        }
+        return this;
+    }
+
+    final public Future<Void> process() {
+        if (!processing.compareAndSet(false, true)) {
+            throw new IllegalStateException("Can not re-run the processing");
+        }
+        Thread t = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                processingTask.run();
+            }
+        });
+        t.setDaemon(true);
+        t.start();
+
+        return processingTask;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jdk/testlibrary/Utils.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) 2013, 2015, 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 jdk.testlibrary;
+
+import static jdk.testlibrary.Asserts.assertTrue;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import java.util.concurrent.TimeUnit;
+import java.util.function.BooleanSupplier;
+import java.util.function.Function;
+
+/**
+ * Common library for various test helper functions.
+ *
+ * @deprecated This class is deprecated. Use the one from
+ *             {@code <root>/test/lib/share/classes/jdk/test/lib}
+ */
+@Deprecated
+public final class Utils {
+
+    /**
+     * Returns the sequence used by operating system to separate lines.
+     */
+    public static final String NEW_LINE = System.getProperty("line.separator");
+
+    /**
+     * Returns the value of 'test.vm.opts'system property.
+     */
+    public static final String VM_OPTIONS = System.getProperty("test.vm.opts", "").trim();
+
+    /**
+     * Returns the value of 'test.java.opts'system property.
+     */
+    public static final String JAVA_OPTIONS = System.getProperty("test.java.opts", "").trim();
+
+    /**
+    * Returns the value of 'test.timeout.factor' system property
+    * converted to {@code double}.
+    */
+    public static final double TIMEOUT_FACTOR;
+    static {
+        String toFactor = System.getProperty("test.timeout.factor", "1.0");
+        TIMEOUT_FACTOR = Double.parseDouble(toFactor);
+    }
+
+    /**
+    * Returns the value of JTREG default test timeout in milliseconds
+    * converted to {@code long}.
+    */
+    public static final long DEFAULT_TEST_TIMEOUT = TimeUnit.SECONDS.toMillis(120);
+
+    private Utils() {
+        // Private constructor to prevent class instantiation
+    }
+
+    /**
+     * Returns the list of VM options.
+     *
+     * @return List of VM options
+     */
+    public static List<String> getVmOptions() {
+        return Arrays.asList(safeSplitString(VM_OPTIONS));
+    }
+
+    /**
+     * Returns the list of VM options with -J prefix.
+     *
+     * @return The list of VM options with -J prefix
+     */
+    public static List<String> getForwardVmOptions() {
+        String[] opts = safeSplitString(VM_OPTIONS);
+        for (int i = 0; i < opts.length; i++) {
+            opts[i] = "-J" + opts[i];
+        }
+        return Arrays.asList(opts);
+    }
+
+    /**
+     * Returns the default JTReg arguments for a jvm running a test.
+     * This is the combination of JTReg arguments test.vm.opts and test.java.opts.
+     * @return An array of options, or an empty array if no opptions.
+     */
+    public static String[] getTestJavaOpts() {
+        List<String> opts = new ArrayList<String>();
+        Collections.addAll(opts, safeSplitString(VM_OPTIONS));
+        Collections.addAll(opts, safeSplitString(JAVA_OPTIONS));
+        return opts.toArray(new String[0]);
+    }
+
+    /**
+     * Combines given arguments with default JTReg arguments for a jvm running a test.
+     * This is the combination of JTReg arguments test.vm.opts and test.java.opts
+     * @return The combination of JTReg test java options and user args.
+     */
+    public static String[] addTestJavaOpts(String... userArgs) {
+        List<String> opts = new ArrayList<String>();
+        Collections.addAll(opts, getTestJavaOpts());
+        Collections.addAll(opts, userArgs);
+        return opts.toArray(new String[0]);
+    }
+
+    /**
+     * Removes any options specifying which GC to use, for example "-XX:+UseG1GC".
+     * Removes any options matching: -XX:(+/-)Use*GC
+     * Used when a test need to set its own GC version. Then any
+     * GC specified by the framework must first be removed.
+     * @return A copy of given opts with all GC options removed.
+     */
+    private static final Pattern useGcPattern = Pattern.compile(
+            "(?:\\-XX\\:[\\+\\-]Use.+GC)"
+            + "|(?:\\-Xconcgc)");
+    public static List<String> removeGcOpts(List<String> opts) {
+        List<String> optsWithoutGC = new ArrayList<String>();
+        for (String opt : opts) {
+            if (useGcPattern.matcher(opt).matches()) {
+                System.out.println("removeGcOpts: removed " + opt);
+            } else {
+                optsWithoutGC.add(opt);
+            }
+        }
+        return optsWithoutGC;
+    }
+
+    /**
+     * Splits a string by white space.
+     * Works like String.split(), but returns an empty array
+     * if the string is null or empty.
+     */
+    private static String[] safeSplitString(String s) {
+        if (s == null || s.trim().isEmpty()) {
+            return new String[] {};
+        }
+        return s.trim().split("\\s+");
+    }
+
+    /**
+     * @return The full command line for the ProcessBuilder.
+     */
+    public static String getCommandLine(ProcessBuilder pb) {
+        StringBuilder cmd = new StringBuilder();
+        for (String s : pb.command()) {
+            cmd.append(s).append(" ");
+        }
+        return cmd.toString();
+    }
+
+    /**
+     * Returns the free port on the local host.
+     * The function will spin until a valid port number is found.
+     *
+     * @return The port number
+     * @throws InterruptedException if any thread has interrupted the current thread
+     * @throws IOException if an I/O error occurs when opening the socket
+     */
+    public static int getFreePort() throws InterruptedException, IOException {
+        int port = -1;
+
+        while (port <= 0) {
+            Thread.sleep(100);
+
+            ServerSocket serverSocket = null;
+            try {
+                serverSocket = new ServerSocket(0);
+                port = serverSocket.getLocalPort();
+            } finally {
+                serverSocket.close();
+            }
+        }
+
+        return port;
+    }
+
+    /**
+     * Returns the name of the local host.
+     *
+     * @return The host name
+     * @throws UnknownHostException if IP address of a host could not be determined
+     */
+    public static String getHostname() throws UnknownHostException {
+        InetAddress inetAddress = InetAddress.getLocalHost();
+        String hostName = inetAddress.getHostName();
+
+        assertTrue((hostName != null && !hostName.isEmpty()),
+                "Cannot get hostname");
+
+        return hostName;
+    }
+
+    /**
+     * Uses "jcmd -l" to search for a jvm pid. This function will wait
+     * forever (until jtreg timeout) for the pid to be found.
+     * @param key Regular expression to search for
+     * @return The found pid.
+     */
+    public static int waitForJvmPid(String key) throws Throwable {
+        final long iterationSleepMillis = 250;
+        System.out.println("waitForJvmPid: Waiting for key '" + key + "'");
+        System.out.flush();
+        while (true) {
+            int pid = tryFindJvmPid(key);
+            if (pid >= 0) {
+                return pid;
+            }
+            Thread.sleep(iterationSleepMillis);
+        }
+    }
+
+    /**
+     * Searches for a jvm pid in the output from "jcmd -l".
+     *
+     * Example output from jcmd is:
+     * 12498 sun.tools.jcmd.JCmd -l
+     * 12254 /tmp/jdk8/tl/jdk/JTwork/classes/com/sun/tools/attach/Application.jar
+     *
+     * @param key A regular expression to search for.
+     * @return The found pid, or -1 if Enot found.
+     * @throws Exception If multiple matching jvms are found.
+     */
+    public static int tryFindJvmPid(String key) throws Throwable {
+        OutputAnalyzer output = null;
+        try {
+            JDKToolLauncher jcmdLauncher = JDKToolLauncher.create("jcmd");
+            jcmdLauncher.addToolArg("-l");
+            output = ProcessTools.executeProcess(jcmdLauncher.getCommand());
+            output.shouldHaveExitValue(0);
+
+            // Search for a line starting with numbers (pid), follwed by the key.
+            Pattern pattern = Pattern.compile("([0-9]+)\\s.*(" + key + ").*\\r?\\n");
+            Matcher matcher = pattern.matcher(output.getStdout());
+
+            int pid = -1;
+            if (matcher.find()) {
+                pid = Integer.parseInt(matcher.group(1));
+                System.out.println("findJvmPid.pid: " + pid);
+                if (matcher.find()) {
+                    throw new Exception("Found multiple JVM pids for key: " + key);
+                }
+            }
+            return pid;
+        } catch (Throwable t) {
+            System.out.println(String.format("Utils.findJvmPid(%s) failed: %s", key, t));
+            throw t;
+        }
+    }
+
+    /**
+     * Adjusts the provided timeout value for the TIMEOUT_FACTOR
+     * @param tOut the timeout value to be adjusted
+     * @return The timeout value adjusted for the value of "test.timeout.factor"
+     *         system property
+     */
+    public static long adjustTimeout(long tOut) {
+        return Math.round(tOut * Utils.TIMEOUT_FACTOR);
+    }
+
+    /**
+     * Wait for condition to be true
+     *
+     * @param condition, a condition to wait for
+     */
+    public static final void waitForCondition(BooleanSupplier condition) {
+        waitForCondition(condition, -1L, 100L);
+    }
+
+    /**
+     * Wait until timeout for condition to be true
+     *
+     * @param condition, a condition to wait for
+     * @param timeout a time in milliseconds to wait for condition to be true
+     * specifying -1 will wait forever
+     * @return condition value, to determine if wait was successfull
+     */
+    public static final boolean waitForCondition(BooleanSupplier condition,
+            long timeout) {
+        return waitForCondition(condition, timeout, 100L);
+    }
+
+    /**
+     * Wait until timeout for condition to be true for specified time
+     *
+     * @param condition, a condition to wait for
+     * @param timeout a time in milliseconds to wait for condition to be true,
+     * specifying -1 will wait forever
+     * @param sleepTime a time to sleep value in milliseconds
+     * @return condition value, to determine if wait was successfull
+     */
+    public static final boolean waitForCondition(BooleanSupplier condition,
+            long timeout, long sleepTime) {
+        long startTime = System.currentTimeMillis();
+        while (!(condition.getAsBoolean() || (timeout != -1L
+                && ((System.currentTimeMillis() - startTime) > timeout)))) {
+            try {
+                Thread.sleep(sleepTime);
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                throw new Error(e);
+            }
+        }
+        return condition.getAsBoolean();
+    }
+
+    /**
+     * Interface same as java.lang.Runnable but with
+     * method {@code run()} able to throw any Throwable.
+     */
+    public static interface ThrowingRunnable {
+        void run() throws Throwable;
+    }
+
+    /**
+     * Filters out an exception that may be thrown by the given
+     * test according to the given filter.
+     *
+     * @param test - method that is invoked and checked for exception.
+     * @param filter - function that checks if the thrown exception matches
+     *                 criteria given in the filter's implementation.
+     * @return - exception that matches the filter if it has been thrown or
+     *           {@code null} otherwise.
+     * @throws Throwable - if test has thrown an exception that does not
+     *                     match the filter.
+     */
+    public static Throwable filterException(ThrowingRunnable test,
+            Function<Throwable, Boolean> filter) throws Throwable {
+        try {
+            test.run();
+        } catch (Throwable t) {
+            if (filter.apply(t)) {
+                return t;
+            } else {
+                throw t;
+            }
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/BasicModularXMLParserTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2016, 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 static org.testng.Assert.assertTrue;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import static jdk.testlibrary.ProcessTools.executeTestJava;
+import jdk.testlibrary.CompilerUtils;
+
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+/*
+ * @test
+ * @library /javax/xml/jaxp/libs
+ * @build jdk.testlibrary.*
+ * @run testng BasicModularXMLParserTest
+ * @bug 8078820
+ * @summary Tests JAXP lib can instantiate the following interfaces
+ *          with customized provider module on boot layer
+ *
+ *          javax.xml.datatype.DatatypeFactory
+ *          javax.xml.parsers.DocumentBuilderFactory
+ *          javax.xml.parsers.SAXParserFactory
+ *          javax.xml.stream.XMLEventFactory
+ *          javax.xml.stream.XMLInputFactory
+ *          javax.xml.stream.XMLOutputFactory
+ *          javax.xml.transform.TransformerFactory
+ *          javax.xml.validation.SchemaFactory
+ *          javax.xml.xpath.XPathFactory
+ */
+
+@Test
+public class BasicModularXMLParserTest {
+
+    private static final String TEST_SRC = System.getProperty("test.src");
+
+    private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
+    private static final Path MOD_DIR1 = Paths.get("mod1");
+    private static final Path MOD_DIR2 = Paths.get("mod2");
+    private static final Path CLASSES_DIR = Paths.get("classes");
+
+    /*
+     * Compiles all modules used by the test
+     */
+    @BeforeTest
+    public void compileAll() throws Exception {
+        assertTrue(CompilerUtils.compile(SRC_DIR.resolve("xmlprovider1"), MOD_DIR1.resolve("xmlprovider1")));
+        assertTrue(CompilerUtils.compile(SRC_DIR.resolve("xmlprovider2"), MOD_DIR2.resolve("xmlprovider2")));
+        assertTrue(CompilerUtils.compile(SRC_DIR.resolve("unnamed"), CLASSES_DIR));
+    }
+
+    /*
+     * test the default JAXP implementation
+     */
+    public void testDefault() throws Exception {
+        int exitValue
+            = executeTestJava("-cp", CLASSES_DIR.toString(),
+                              "Main")
+                .outputTo(System.out)
+                .errorTo(System.out)
+                .getExitValue();
+
+        assertTrue(exitValue == 0);
+    }
+
+    /*
+     * test loading one provider module
+     */
+    public void testWithOneProvider() throws Exception {
+        int exitValue
+            = executeTestJava("-mp", MOD_DIR1.toString(),
+                              "-cp", CLASSES_DIR.toString(),
+                              "Main", "xmlprovider1")
+                .outputTo(System.out)
+                .errorTo(System.out)
+                .getExitValue();
+
+        assertTrue(exitValue == 0);
+    }
+
+    /*
+     * test loading both provider modules
+     */
+    public void testWithTwoProvider() throws Exception {
+        int exitValue
+            = executeTestJava("-mp", MOD_DIR1.toString() + File.pathSeparator + MOD_DIR2.toString(),
+                              "-cp", CLASSES_DIR.toString(),
+                              "Main", "xmlprovider1", "xmlprovider2")
+                .outputTo(System.out)
+                .errorTo(System.out)
+                .getExitValue();
+
+        assertTrue(exitValue == 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/LayerModularXMLParserTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2016, 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 static java.lang.module.ModuleFinder.empty;
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.assertTrue;
+
+import java.lang.ClassLoader;
+import java.lang.String;
+import java.lang.System;
+import java.lang.module.Configuration;
+import java.lang.module.ModuleFinder;
+import java.lang.reflect.Layer;
+import java.lang.reflect.Method;
+import java.lang.reflect.Module;
+import java.nio.file.Paths;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.ServiceLoader;
+import java.util.Set;
+
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import jdk.testlibrary.CompilerUtils;
+
+/*
+ * @test
+ * @library /javax/xml/jaxp/libs
+ * @build jdk.testlibrary.*
+ * @run testng LayerModularXMLParserTest
+ * @bug 8078820
+ * @summary Tests JAXP lib works with layer and TCCL
+ */
+
+@Test
+public class LayerModularXMLParserTest {
+
+    private static final String TEST_SRC = System.getProperty("test.src");
+
+    private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
+    private static final Path MOD_DIR1 = Paths.get("mod1");
+    private static final Path MOD_DIR2 = Paths.get("mod2");
+
+    /*
+     * services provided by provider1
+     */
+    private static final String[] services1 = { "javax.xml.parsers.DocumentBuilderFactory",
+            "javax.xml.parsers.SAXParserFactory", "javax.xml.stream.XMLInputFactory",
+            "javax.xml.stream.XMLOutputFactory", "javax.xml.transform.TransformerFactory",
+            "javax.xml.validation.SchemaFactory", "javax.xml.xpath.XPathFactory" };
+
+    /*
+     * services provided by provider2
+     */
+    private static final String[] services2 = { "javax.xml.datatype.DatatypeFactory",
+            "javax.xml.stream.XMLEventFactory" };
+
+    /*
+     * Compiles all modules used by the test
+     */
+    @BeforeTest
+    public void compileAll() throws Exception {
+        assertTrue(CompilerUtils.compile(SRC_DIR.resolve("xmlprovider1"), MOD_DIR1.resolve("xmlprovider1")));
+        assertTrue(CompilerUtils.compile(SRC_DIR.resolve("xmlprovider2"), MOD_DIR2.resolve("xmlprovider2")));
+        assertTrue(CompilerUtils.compile(SRC_DIR.resolve("test"), MOD_DIR1.resolve("test")));
+        assertTrue(CompilerUtils.compile(SRC_DIR.resolve("test"), MOD_DIR2.resolve("test")));
+    }
+
+    /*
+     * layer 1 is created on top of boot layer, layer1 includes module provider1.
+     *
+     * Instantiate each XML service, verify the services provided by provider1
+     * are loaded from layer 1, the other services are loaded from boot layer
+     */
+    public void testOneLayer() throws Exception {
+        ModuleFinder finder1 = ModuleFinder.of(MOD_DIR1);
+        Configuration cf1 = Layer.boot().configuration()
+                .resolveRequiresAndUses(finder1, empty(), Set.of("test"));
+        ClassLoader scl = ClassLoader.getSystemClassLoader();
+        Layer layer1 = Layer.boot().defineModulesWithManyLoaders(cf1, scl);
+        ClassLoader cl1 = layer1.findLoader("test");
+
+        Method m = cl1.loadClass("test.XMLFactoryHelper").getMethod("instantiateXMLService", String.class);
+        for (String service : services1) {
+            Object o = m.invoke(null, service);
+            Layer providerLayer = o.getClass().getModule().getLayer();
+            assertSame(providerLayer, layer1);
+        }
+
+        for (String service : services2) {
+            Object o = m.invoke(null, service);
+            Layer providerLayer = o.getClass().getModule().getLayer();
+            assertSame(providerLayer, Layer.boot());
+        }
+
+    }
+
+    /*
+     * layer 1 is created on top of boot layer, layer 1 includes module provider1.
+     * layer 2 is created on top of layer 1, layer 2 includes module provider2.
+     *
+     * Instantiate each XML service, verify the services provided by provider1
+     * are loaded from layer 1, the services provided by provider2 are loaded from layer 2
+     */
+    public void testTwoLayer() throws Exception {
+        ModuleFinder finder1 = ModuleFinder.of(MOD_DIR1);
+        Configuration cf1 = Layer.boot().configuration()
+                .resolveRequiresAndUses(finder1, empty(), Set.of("test"));
+        ClassLoader scl = ClassLoader.getSystemClassLoader();
+        Layer layer1 = Layer.boot().defineModulesWithManyLoaders(cf1, scl);
+
+        ModuleFinder finder2 = ModuleFinder.of(MOD_DIR2);
+        Configuration cf2 = cf1.resolveRequiresAndUses(finder2, empty(), Set.of("test"));
+        Layer layer2 = layer1.defineModulesWithOneLoader(cf2, layer1.findLoader("test"));
+        ClassLoader cl2 = layer2.findLoader("test");
+
+        Method m = cl2.loadClass("test.XMLFactoryHelper").getMethod("instantiateXMLService", String.class);
+        for (String service : services1) {
+            Object o = m.invoke(null, service);
+            Layer providerLayer = o.getClass().getModule().getLayer();
+            assertSame(providerLayer, layer1);
+        }
+
+        for (String service : services2) {
+            Object o = m.invoke(null, service);
+            Layer providerLayer = o.getClass().getModule().getLayer();
+            assertSame(providerLayer, layer2);
+        }
+
+    }
+
+    /*
+     * layer 1 is created on top of boot layer, layer 1 includes module provider1 and provider2.
+     * layer 2 is created on top of layer 1, layer 2 includes module provider2.
+     *
+     * Instantiate each XML service, verify the services provided by provider1
+     * are loaded from layer 1, the services provided by provider2 are loaded from layer 2
+     */
+    public void testTwoLayerWithDuplicate() throws Exception {
+        ModuleFinder finder1 = ModuleFinder.of(MOD_DIR1, MOD_DIR2);
+        Configuration cf1 = Layer.boot().configuration()
+                .resolveRequiresAndUses(finder1, empty(), Set.of("test"));
+        ClassLoader scl = ClassLoader.getSystemClassLoader();
+        Layer layer1 = Layer.boot().defineModulesWithManyLoaders(cf1, scl);
+
+        ModuleFinder finder2 = ModuleFinder.of(MOD_DIR2);
+        Configuration cf2 = cf1.resolveRequiresAndUses(finder2, empty(), Set.of("test"));
+        Layer layer2 = layer1.defineModulesWithOneLoader(cf2, layer1.findLoader("test"));
+        ClassLoader cl2 = layer2.findLoader("test");
+
+        Method m = cl2.loadClass("test.XMLFactoryHelper").getMethod("instantiateXMLService", String.class);
+        for (String service : services1) {
+            Object o = m.invoke(null, service);
+            Layer providerLayer = o.getClass().getModule().getLayer();
+            assertSame(providerLayer, layer1);
+        }
+
+        for (String service : services2) {
+            Object o = m.invoke(null, service);
+            Layer providerLayer = o.getClass().getModule().getLayer();
+            assertSame(providerLayer, layer2);
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/test/module-info.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+module test {
+    requires java.xml;
+    exports test;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/test/test/XMLFactoryHelper.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016, 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 test;
+
+import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
+
+import java.lang.Class;
+import java.lang.String;
+import java.lang.System;
+import java.util.Iterator;
+import java.util.ServiceLoader;
+
+public class XMLFactoryHelper {
+    /*
+     * instantiate a xml factory by reflection e.g.
+     * DocumentBuilderFactory.newInstance()
+     */
+    public static Object instantiateXMLService(String serviceName) throws Exception {
+        ClassLoader backup = Thread.currentThread().getContextClassLoader();
+        try {
+            // set thread context class loader to module class loader
+            Thread.currentThread().setContextClassLoader(XMLFactoryHelper.class.getClassLoader());
+            if (serviceName.equals("javax.xml.validation.SchemaFactory"))
+                return Class.forName(serviceName).getMethod("newInstance", String.class)
+                        .invoke(null, W3C_XML_SCHEMA_NS_URI);
+            else
+                return Class.forName(serviceName).getMethod("newInstance").invoke(null);
+        } finally {
+            Thread.currentThread().setContextClassLoader(backup);
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/unnamed/Main.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2016, 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 static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
+
+import java.lang.reflect.Layer;
+import java.lang.reflect.Module;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Stream;
+
+public class Main {
+    /*
+     * @param args, the names of provider modules, which have been loaded
+     */
+    public static void main(String[] args) throws Exception {
+        Module xml = Layer.boot().findModule("java.xml").get();
+
+        Set<String> allServices = new HashSet<>(Arrays.asList(expectedAllServices));
+        if (!allServices.equals(xml.getDescriptor().uses()))
+            throw new AssertionError("Expect xml module uses: " + allServices + " But actually uses: "
+                    + xml.getDescriptor().uses());
+
+        long violationCount = Stream.of(args)
+                .map(xmlProviderName -> Layer.boot().findModule(xmlProviderName).get())
+                .mapToLong(
+                        // services provided by the implementation in provider module
+                        provider -> provider.getDescriptor().provides().keySet().stream()
+                                .filter(serviceName -> {
+                                    allServices.remove(serviceName); // remove service provided by
+                                                                     // customized module from allServices
+                                    return !belongToModule(serviceName, instantiateXMLService(serviceName), provider);
+                                }).count())
+                .sum();
+
+        // the remaining services should be provided by the default implementation
+        violationCount += allServices.stream()
+                .filter(serviceName -> !belongToModule(serviceName, instantiateXMLService(serviceName), xml))
+                .count();
+
+        if (violationCount > 0)
+            throw new AssertionError(violationCount + " services are not provided by expected module");
+    }
+
+    /*
+     * instantiate a xml factory by reflection e.g.
+     * DocumentBuilderFactory.newInstance()
+     */
+    private static Object instantiateXMLService(String serviceName) {
+        try {
+            if (serviceName.equals("javax.xml.validation.SchemaFactory"))
+                return Class.forName(serviceName).getMethod("newInstance", String.class)
+                        .invoke(null, W3C_XML_SCHEMA_NS_URI);
+            else
+                return Class.forName(serviceName).getMethod("newInstance").invoke(null);
+        } catch (Exception e) {
+            e.printStackTrace(System.err);
+            throw new RuntimeException(e);
+        }
+    }
+
+    /*
+     * verify which module provides the xml factory
+     */
+    private static boolean belongToModule(String factoryName, Object factory, Module expected) {
+        Module actual = factory.getClass().getModule();
+        if (!actual.equals(expected)) {
+            System.err.println("Expect " + factoryName + " is provided by " + expected
+                    + ", but actual implementation " + factory.getClass() + " is provided by " + actual);
+            return false;
+        } else {
+            System.out.println(factory.getClass() + " is provided by " + expected);
+            return true;
+        }
+    }
+
+    /*
+     * This list equals the declarations in java.xml module-info.java
+     */
+    private static final String[] expectedAllServices = { "javax.xml.datatype.DatatypeFactory",
+            "javax.xml.parsers.DocumentBuilderFactory", "javax.xml.parsers.SAXParserFactory",
+            "javax.xml.stream.XMLEventFactory", "javax.xml.stream.XMLInputFactory",
+            "javax.xml.stream.XMLOutputFactory", "javax.xml.transform.TransformerFactory",
+            "javax.xml.validation.SchemaFactory", "javax.xml.xpath.XPathFactory" };
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider1/module-info.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+module xmlprovider1 {
+    requires java.xml;
+
+    provides javax.xml.parsers.DocumentBuilderFactory with xp1.DocumentBuilderFactoryImpl;
+    provides javax.xml.parsers.SAXParserFactory with xp1.SAXParserFactoryImpl;
+    provides javax.xml.stream.XMLInputFactory with xp1.XMLInputFactoryImpl;
+    provides javax.xml.stream.XMLOutputFactory with xp1.XMLOutputFactoryImpl;
+    provides javax.xml.transform.TransformerFactory with xp1.TransformerFactoryImpl;
+    provides javax.xml.validation.SchemaFactory with xp1.SchemaFactoryImpl;
+    provides javax.xml.xpath.XPathFactory with xp1.XPathFactoryImpl;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider1/xp1/DocumentBuilderFactoryImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2016, 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 xp1;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+public class DocumentBuilderFactoryImpl extends DocumentBuilderFactory {
+
+    @Override
+    public DocumentBuilder newDocumentBuilder() throws ParserConfigurationException {
+        return null;
+    }
+
+    @Override
+    public void setAttribute(String name, Object value) throws IllegalArgumentException {
+
+    }
+
+    @Override
+    public Object getAttribute(String name) throws IllegalArgumentException {
+        return null;
+    }
+
+    @Override
+    public void setFeature(String name, boolean value) throws ParserConfigurationException {
+
+    }
+
+    @Override
+    public boolean getFeature(String name) throws ParserConfigurationException {
+        return false;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider1/xp1/SAXParserFactoryImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016, 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 xp1;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+
+public class SAXParserFactoryImpl extends SAXParserFactory {
+
+    @Override
+    public SAXParser newSAXParser() throws ParserConfigurationException, SAXException {
+        return null;
+    }
+
+    @Override
+    public void setFeature(String name, boolean value) throws ParserConfigurationException,
+            SAXNotRecognizedException, SAXNotSupportedException {
+
+    }
+
+    @Override
+    public boolean getFeature(String name) throws ParserConfigurationException, SAXNotRecognizedException,
+            SAXNotSupportedException {
+        return false;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider1/xp1/SchemaFactoryImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016, 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 xp1;
+
+import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
+
+import javax.xml.transform.Source;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+
+import org.w3c.dom.ls.LSResourceResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+
+public class SchemaFactoryImpl extends SchemaFactory {
+
+    @Override
+    public boolean isSchemaLanguageSupported(String schemaLanguage) {
+        // must be true, otherwise JAXP library will deny this impl
+        if (schemaLanguage.equals(W3C_XML_SCHEMA_NS_URI))
+            return true;
+        else
+            return false;
+    }
+
+    @Override
+    public void setErrorHandler(ErrorHandler errorHandler) {
+
+    }
+
+    @Override
+    public ErrorHandler getErrorHandler() {
+        return null;
+    }
+
+    @Override
+    public void setResourceResolver(LSResourceResolver resourceResolver) {
+
+    }
+
+    @Override
+    public LSResourceResolver getResourceResolver() {
+        return null;
+    }
+
+    @Override
+    public Schema newSchema(Source[] schemas) throws SAXException {
+        return null;
+    }
+
+    @Override
+    public Schema newSchema() throws SAXException {
+        return null;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider1/xp1/TransformerFactoryImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2016, 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 xp1;
+
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.Source;
+import javax.xml.transform.Templates;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.URIResolver;
+
+public class TransformerFactoryImpl extends TransformerFactory {
+
+    @Override
+    public Transformer newTransformer(Source source) throws TransformerConfigurationException {
+        return null;
+    }
+
+    @Override
+    public Transformer newTransformer() throws TransformerConfigurationException {
+        return null;
+    }
+
+    @Override
+    public Templates newTemplates(Source source) throws TransformerConfigurationException {
+        return null;
+    }
+
+    @Override
+    public Source getAssociatedStylesheet(Source source, String media, String title, String charset)
+            throws TransformerConfigurationException {
+        return null;
+    }
+
+    @Override
+    public void setURIResolver(URIResolver resolver) {
+
+    }
+
+    @Override
+    public URIResolver getURIResolver() {
+        return null;
+    }
+
+    @Override
+    public void setFeature(String name, boolean value) throws TransformerConfigurationException {
+
+    }
+
+    @Override
+    public boolean getFeature(String name) {
+        return false;
+    }
+
+    @Override
+    public void setAttribute(String name, Object value) {
+
+    }
+
+    @Override
+    public Object getAttribute(String name) {
+        return null;
+    }
+
+    @Override
+    public void setErrorListener(ErrorListener listener) {
+
+    }
+
+    @Override
+    public ErrorListener getErrorListener() {
+        return null;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider1/xp1/XMLInputFactoryImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2016, 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 xp1;
+
+import java.io.InputStream;
+import java.io.Reader;
+
+import javax.xml.stream.EventFilter;
+import javax.xml.stream.StreamFilter;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLReporter;
+import javax.xml.stream.XMLResolver;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.util.XMLEventAllocator;
+import javax.xml.transform.Source;
+
+public class XMLInputFactoryImpl extends XMLInputFactory {
+
+    @Override
+    public XMLStreamReader createXMLStreamReader(Reader reader) throws XMLStreamException {
+        return null;
+    }
+
+    @Override
+    public XMLStreamReader createXMLStreamReader(Source source) throws XMLStreamException {
+        return null;
+    }
+
+    @Override
+    public XMLStreamReader createXMLStreamReader(InputStream stream) throws XMLStreamException {
+        return null;
+    }
+
+    @Override
+    public XMLStreamReader createXMLStreamReader(InputStream stream, String encoding)
+            throws XMLStreamException {
+        return null;
+    }
+
+    @Override
+    public XMLStreamReader createXMLStreamReader(String systemId, InputStream stream)
+            throws XMLStreamException {
+        return null;
+    }
+
+    @Override
+    public XMLStreamReader createXMLStreamReader(String systemId, Reader reader) throws XMLStreamException {
+        return null;
+    }
+
+    @Override
+    public XMLEventReader createXMLEventReader(Reader reader) throws XMLStreamException {
+        return null;
+    }
+
+    @Override
+    public XMLEventReader createXMLEventReader(String systemId, Reader reader) throws XMLStreamException {
+        return null;
+    }
+
+    @Override
+    public XMLEventReader createXMLEventReader(XMLStreamReader reader) throws XMLStreamException {
+        return null;
+    }
+
+    @Override
+    public XMLEventReader createXMLEventReader(Source source) throws XMLStreamException {
+        return null;
+    }
+
+    @Override
+    public XMLEventReader createXMLEventReader(InputStream stream) throws XMLStreamException {
+        return null;
+    }
+
+    @Override
+    public XMLEventReader createXMLEventReader(InputStream stream, String encoding) throws XMLStreamException {
+        return null;
+    }
+
+    @Override
+    public XMLEventReader createXMLEventReader(String systemId, InputStream stream) throws XMLStreamException {
+        return null;
+    }
+
+    @Override
+    public XMLStreamReader createFilteredReader(XMLStreamReader reader, StreamFilter filter)
+            throws XMLStreamException {
+        return null;
+    }
+
+    @Override
+    public XMLEventReader createFilteredReader(XMLEventReader reader, EventFilter filter)
+            throws XMLStreamException {
+        return null;
+    }
+
+    @Override
+    public XMLResolver getXMLResolver() {
+        return null;
+    }
+
+    @Override
+    public void setXMLResolver(XMLResolver resolver) {
+
+    }
+
+    @Override
+    public XMLReporter getXMLReporter() {
+        return null;
+    }
+
+    @Override
+    public void setXMLReporter(XMLReporter reporter) {
+
+    }
+
+    @Override
+    public void setProperty(String name, Object value) throws IllegalArgumentException {
+
+    }
+
+    @Override
+    public Object getProperty(String name) throws IllegalArgumentException {
+        return null;
+    }
+
+    @Override
+    public boolean isPropertySupported(String name) {
+        return false;
+    }
+
+    @Override
+    public void setEventAllocator(XMLEventAllocator allocator) {
+
+    }
+
+    @Override
+    public XMLEventAllocator getEventAllocator() {
+        return null;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider1/xp1/XMLOutputFactoryImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2016, 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 xp1;
+
+import java.io.OutputStream;
+import java.io.Writer;
+
+import javax.xml.stream.XMLEventWriter;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.Result;
+
+public class XMLOutputFactoryImpl extends XMLOutputFactory {
+
+    @Override
+    public XMLStreamWriter createXMLStreamWriter(Writer stream) throws XMLStreamException {
+        return null;
+    }
+
+    @Override
+    public XMLStreamWriter createXMLStreamWriter(OutputStream stream) throws XMLStreamException {
+        return null;
+    }
+
+    @Override
+    public XMLStreamWriter createXMLStreamWriter(OutputStream stream, String encoding)
+            throws XMLStreamException {
+        return null;
+    }
+
+    @Override
+    public XMLStreamWriter createXMLStreamWriter(Result result) throws XMLStreamException {
+        return null;
+    }
+
+    @Override
+    public XMLEventWriter createXMLEventWriter(Result result) throws XMLStreamException {
+        return null;
+    }
+
+    @Override
+    public XMLEventWriter createXMLEventWriter(OutputStream stream) throws XMLStreamException {
+        return null;
+    }
+
+    @Override
+    public XMLEventWriter createXMLEventWriter(OutputStream stream, String encoding)
+            throws XMLStreamException {
+        return null;
+    }
+
+    @Override
+    public XMLEventWriter createXMLEventWriter(Writer stream) throws XMLStreamException {
+        return null;
+    }
+
+    @Override
+    public void setProperty(String name, Object value) throws IllegalArgumentException {
+
+    }
+
+    @Override
+    public Object getProperty(String name) throws IllegalArgumentException {
+        return null;
+    }
+
+    @Override
+    public boolean isPropertySupported(String name) {
+        return false;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider1/xp1/XPathFactoryImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2016, 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 xp1;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathFactory;
+import javax.xml.xpath.XPathFactoryConfigurationException;
+import javax.xml.xpath.XPathFunctionResolver;
+import javax.xml.xpath.XPathVariableResolver;
+
+public class XPathFactoryImpl extends XPathFactory {
+
+    @Override
+    public boolean isObjectModelSupported(String objectModel) {
+        // must be true, otherwise JAXP library will deny this impl
+        return true;
+    }
+
+    @Override
+    public void setFeature(String name, boolean value) throws XPathFactoryConfigurationException {
+
+    }
+
+    @Override
+    public boolean getFeature(String name) throws XPathFactoryConfigurationException {
+        return false;
+    }
+
+    @Override
+    public void setXPathVariableResolver(XPathVariableResolver resolver) {
+
+    }
+
+    @Override
+    public void setXPathFunctionResolver(XPathFunctionResolver resolver) {
+
+    }
+
+    @Override
+    public XPath newXPath() {
+        return null;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider2/module-info.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+module xmlprovider2 {
+    requires java.xml;
+
+    provides javax.xml.datatype.DatatypeFactory with xp2.DatatypeFactoryImpl;
+    provides javax.xml.stream.XMLEventFactory with xp2.XMLEventFactoryImpl;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider2/xp2/DatatypeFactoryImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016, 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 xp2;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.GregorianCalendar;
+
+import javax.xml.datatype.DatatypeFactory;
+import javax.xml.datatype.Duration;
+import javax.xml.datatype.XMLGregorianCalendar;
+
+public class DatatypeFactoryImpl extends DatatypeFactory {
+
+    @Override
+    public Duration newDuration(String lexicalRepresentation) {
+        return null;
+    }
+
+    @Override
+    public Duration newDuration(long durationInMilliSeconds) {
+        return null;
+    }
+
+    @Override
+    public Duration newDuration(boolean isPositive, BigInteger years, BigInteger months, BigInteger days,
+            BigInteger hours, BigInteger minutes, BigDecimal seconds) {
+        return null;
+    }
+
+    @Override
+    public XMLGregorianCalendar newXMLGregorianCalendar() {
+        return null;
+    }
+
+    @Override
+    public XMLGregorianCalendar newXMLGregorianCalendar(String lexicalRepresentation) {
+        return null;
+    }
+
+    @Override
+    public XMLGregorianCalendar newXMLGregorianCalendar(GregorianCalendar cal) {
+        return null;
+    }
+
+    @Override
+    public XMLGregorianCalendar newXMLGregorianCalendar(BigInteger year, int month, int day, int hour,
+            int minute, int second, BigDecimal fractionalSecond, int timezone) {
+        return null;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider2/xp2/XMLEventFactoryImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2016, 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 xp2;
+
+import java.util.Iterator;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLEventFactory;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.Characters;
+import javax.xml.stream.events.Comment;
+import javax.xml.stream.events.DTD;
+import javax.xml.stream.events.EndDocument;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.EntityDeclaration;
+import javax.xml.stream.events.EntityReference;
+import javax.xml.stream.events.Namespace;
+import javax.xml.stream.events.ProcessingInstruction;
+import javax.xml.stream.events.StartDocument;
+import javax.xml.stream.events.StartElement;
+
+public class XMLEventFactoryImpl extends XMLEventFactory {
+
+    @Override
+    public void setLocation(Location location) {
+
+    }
+
+    @Override
+    public Attribute createAttribute(String prefix, String namespaceURI, String localName, String value) {
+        return null;
+    }
+
+    @Override
+    public Attribute createAttribute(String localName, String value) {
+        return null;
+    }
+
+    @Override
+    public Attribute createAttribute(QName name, String value) {
+        return null;
+    }
+
+    @Override
+    public Namespace createNamespace(String namespaceURI) {
+        return null;
+    }
+
+    @Override
+    public Namespace createNamespace(String prefix, String namespaceUri) {
+        return null;
+    }
+
+    @Override
+    public StartElement createStartElement(QName name, Iterator attributes, Iterator namespaces) {
+        return null;
+    }
+
+    @Override
+    public StartElement createStartElement(String prefix, String namespaceUri, String localName) {
+        return null;
+    }
+
+    @Override
+    public StartElement createStartElement(String prefix, String namespaceUri, String localName,
+            Iterator attributes, Iterator namespaces) {
+        return null;
+    }
+
+    @Override
+    public StartElement createStartElement(String prefix, String namespaceUri, String localName,
+            Iterator attributes, Iterator namespaces, NamespaceContext context) {
+        return null;
+    }
+
+    @Override
+    public EndElement createEndElement(QName name, Iterator namespaces) {
+        return null;
+    }
+
+    @Override
+    public EndElement createEndElement(String prefix, String namespaceUri, String localName) {
+        return null;
+    }
+
+    @Override
+    public EndElement createEndElement(String prefix, String namespaceUri, String localName,
+            Iterator namespaces) {
+        return null;
+    }
+
+    @Override
+    public Characters createCharacters(String content) {
+        return null;
+    }
+
+    @Override
+    public Characters createCData(String content) {
+        return null;
+    }
+
+    @Override
+    public Characters createSpace(String content) {
+        return null;
+    }
+
+    @Override
+    public Characters createIgnorableSpace(String content) {
+        return null;
+    }
+
+    @Override
+    public StartDocument createStartDocument() {
+        return null;
+    }
+
+    @Override
+    public StartDocument createStartDocument(String encoding, String version, boolean standalone) {
+        return null;
+    }
+
+    @Override
+    public StartDocument createStartDocument(String encoding, String version) {
+        return null;
+    }
+
+    @Override
+    public StartDocument createStartDocument(String encoding) {
+        return null;
+    }
+
+    @Override
+    public EndDocument createEndDocument() {
+        return null;
+    }
+
+    @Override
+    public EntityReference createEntityReference(String name, EntityDeclaration declaration) {
+        return null;
+    }
+
+    @Override
+    public Comment createComment(String text) {
+        return null;
+    }
+
+    @Override
+    public ProcessingInstruction createProcessingInstruction(String target, String data) {
+        return null;
+    }
+
+    @Override
+    public DTD createDTD(String dtd) {
+        return null;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/TEST.properties	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,5 @@
+# Tests that must run in othervm mode
+othervm.dirs= .
+
+# Declare module dependency
+modules=java.xml
--- a/jaxp/test/javax/xml/jaxp/unittest/TEST.properties	Fri Apr 29 04:44:08 2016 +0200
+++ b/jaxp/test/javax/xml/jaxp/unittest/TEST.properties	Thu Apr 28 23:08:16 2016 -0700
@@ -4,5 +4,6 @@
 lib.dirs = /javax/xml/jaxp/libs
 
 # Declare module dependency
-modules=java.xml/com.sun.org.apache.xerces.internal.jaxp \
+modules=java.xml/com.sun.org.apache.xerces.internal.impl \
+        java.xml/com.sun.org.apache.xerces.internal.jaxp \
         java.xml/com.sun.org.apache.xml.internal.serialize
--- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -23,6 +23,7 @@
 package catalog;
 
 import java.io.IOException;
+import java.nio.file.Paths;
 import javax.xml.catalog.Catalog;
 import javax.xml.catalog.CatalogException;
 import javax.xml.catalog.CatalogFeatures;
@@ -34,6 +35,7 @@
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
 import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 import org.xml.sax.Attributes;
@@ -44,10 +46,49 @@
 import org.xml.sax.ext.DefaultHandler2;
 
 /*
- * @bug 8081248, 8144966, 8146606, 8146237, 8151154, 8150969, 8151162, 8152527
+ * @bug 8081248, 8144966, 8146606, 8146237, 8151154, 8150969, 8151162, 8152527, 8154220
  * @summary Tests basic Catalog functions.
  */
 public class CatalogTest {
+    static final String KEY_FILES = "javax.xml.catalog.files";
+
+    public String filepath;
+
+    /*
+     * Initializing fields
+     */
+    @BeforeClass
+    public void setUpClass() throws Exception {
+        String file1 = getClass().getResource("first_cat.xml").getFile();
+        if (System.getProperty("os.name").contains("Windows")) {
+            filepath = file1.substring(1, file1.lastIndexOf("/") + 1);
+        } else {
+            filepath = file1.substring(0, file1.lastIndexOf("/") + 1);
+        }
+    }
+
+    /*
+     * @bug 8154220
+     * Verifies that the file input is validated properly. Valid input includes
+     * multiple file paths separated by semicolon.
+     */
+    @Test(dataProvider = "hierarchyOfCatFilesData")
+    public void hierarchyOfCatFiles2(String systemId, String expectedUri) {
+        String file1 = getClass().getResource("first_cat.xml").getFile();
+        String file2 = getClass().getResource("second_cat.xml").getFile();
+        String files = file1 + ";" + file2;
+
+        try {
+            System.setProperty(KEY_FILES, files);
+            CatalogResolver catalogResolver = CatalogManager.catalogResolver(CatalogFeatures.defaults());
+            String sysId = catalogResolver.resolveEntity(null, systemId).getSystemId();
+            Assert.assertEquals(sysId, Paths.get(filepath + expectedUri).toUri().toString().replace("///", "/"), "System ID match not right");
+        } finally {
+            System.clearProperty(KEY_FILES);
+        }
+
+    }
+
     /*
      * @bug 8152527
      * This test is the same as the JDK test ResolveEntityTests:testMatch1.
@@ -289,6 +330,19 @@
     }
 
     /*
+        DataProvider: used to verify hierarchical catalogs. Refer to JCK test
+    hierarchyOfCatFiles2.
+     */
+    @DataProvider(name = "hierarchyOfCatFilesData")
+    Object[][] getHierarchyOfCatFilesData() {
+        return new Object[][]{
+            {"http://www.oracle.com/sequence.dtd", "first.dtd"},
+            {"http://www.oracle.com/sequence_next.dtd", "next.dtd"},
+            {"http://www.oracle.com/sequence_second.dtd", "second.dtd"}
+        };
+    }
+
+    /*
         DataProvider: used to verify CatalogResolver's resolveEntity function.
         Data columns:
         catalog, prefer, systemId, publicId, expectedUri, expectedFile, msg
@@ -300,6 +354,7 @@
             {"rewriteSystem_id.xml", "system", "http://www.sys00test.com/rewrite.dtd", "PUB-404", expected, expected, "Relative rewriteSystem with xml:base at group level failed"},
         };
     }
+
     static String id = "http://openjdk.java.net/xml/catalog/dtd/system.dtd";
     /*
        DataProvider: used to verify how prefer settings affect the result of the
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/first_cat.xml	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,6 @@
+<catalog prefer="system" xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
+
+    <system systemId="http://www.oracle.com/sequence.dtd" uri="first.dtd"/>
+    <nextCatalog catalog="next_cat.xml"/>
+
+</catalog>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/next_cat.xml	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,6 @@
+<catalog prefer="public" xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
+
+    <system systemId="http://www.oracle.com/sequence.dtd" uri="next.dtd"/>
+    <system systemId="http://www.oracle.com/sequence_next.dtd" uri="next.dtd"/>
+
+</catalog>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/second_cat.xml	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,7 @@
+<catalog prefer="public" xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
+
+    <system systemId="http://www.oracle.com/sequence.dtd" uri="second.dtd"/>
+    <system systemId="http://www.oracle.com/sequence_next.dtd" uri="second.dtd"/>
+    <system systemId="http://www.oracle.com/sequence_second.dtd" uri="second.dtd"/>
+
+</catalog>
\ No newline at end of file
--- a/jaxp/test/javax/xml/jaxp/unittest/stream/XMLEventReaderTest/Bug6668115Test.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jaxp/test/javax/xml/jaxp/unittest/stream/XMLEventReaderTest/Bug6668115Test.java	Thu Apr 28 23:08:16 2016 -0700
@@ -28,7 +28,6 @@
 import javax.xml.stream.XMLEventReader;
 import javax.xml.stream.XMLInputFactory;
 import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.events.XMLEvent;
 
 import org.testng.Assert;
 import org.testng.annotations.Test;
@@ -74,7 +73,7 @@
             er.nextTag();
             er.nextTag();
 
-            XMLEvent event = er.peek();
+            er.peek();
             System.out.println(er.getElementText());
             er.nextTag();
             System.out.println(er.getElementText());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/stream/XMLEventReaderTest/Bug8153781.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2016, 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 stream.XMLEventReaderTest;
+
+import java.io.StringReader;
+
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.XMLEvent;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
+
+/*
+ * @bug 8153781
+ * @summary Test if method skipDTD of class XMLDTDScannerImpl will correctly skip the DTD section,
+ *          even if a call to XMLEntityScanner.scanData for skipping to the closing ']' returns true.
+ */
+public class Bug8153781 {
+    public static int DOCTYPE_SECTION_LENGTH = XMLEntityManager.DEFAULT_BUFFER_SIZE * 2;
+    public static int DOCUMENT_LENGTH = DOCTYPE_SECTION_LENGTH + 4096;
+
+    public String createXMLDocument(int doctypeoffset) {
+        StringBuilder xmlcontentbuilder = new StringBuilder(DOCUMENT_LENGTH);
+        xmlcontentbuilder.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n");
+        xmlcontentbuilder.append("<!DOCTYPE dummy [\r\n");
+        xmlcontentbuilder.append("  <!ELEMENT dummy EMPTY>\r\n");
+        xmlcontentbuilder.append("  <!--\r\n");
+        int doctypelines = DOCTYPE_SECTION_LENGTH / 3;
+        for (int i = 0; i < doctypeoffset; i++)
+            xmlcontentbuilder.append('a');
+        for (int i = 0; i < doctypelines; i++)
+            xmlcontentbuilder.append("a\r\n");
+        xmlcontentbuilder.append("  -->\r\n");
+        xmlcontentbuilder.append("  ]\r\n");
+        xmlcontentbuilder.append(">\r\n");
+        xmlcontentbuilder.append("<dummy>\r\n");
+        xmlcontentbuilder.append("</dummy>\r\n");
+        System.out.println("Document length:" + xmlcontentbuilder.length());
+        return xmlcontentbuilder.toString();
+    }
+
+    public void runReader(XMLInputFactory factory, int offset) throws XMLStreamException {
+        StringReader stringReader = new StringReader(createXMLDocument(offset));
+        XMLEventReader reader = factory.createXMLEventReader(stringReader);
+
+        while (reader.hasNext()) {
+            XMLEvent event = reader.nextEvent();
+            System.out.println("Event Type: " + event.getEventType());
+        }
+    }
+
+    @Test
+    public void test() {
+        try {
+            XMLInputFactory factory = XMLInputFactory.newInstance();
+            factory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
+            for (int i = 0; i < 3; i++) {
+                runReader(factory, i);
+            }
+        } catch (XMLStreamException xe) {
+            xe.printStackTrace();
+            Assert.fail(xe.getMessage());
+        }
+    }
+}
--- a/jaxws/.hgtags	Fri Apr 29 04:44:08 2016 +0200
+++ b/jaxws/.hgtags	Thu Apr 28 23:08:16 2016 -0700
@@ -360,3 +360,5 @@
 21274e7937bae291658d68143aca0e3ee9296db0 jdk-9+112
 e980062475c10d21137051045bf95ee229db9b27 jdk-9+113
 b314bb02182b9ca94708a91f312c377f5435f740 jdk-9+114
+4ff86e5489e4c0513dadfa69def8601c110ca5cd jdk-9+115
+529f0bf896e58525614d863e283ad155531941cb jdk-9+116
--- a/jdk/.hgtags	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/.hgtags	Thu Apr 28 23:08:16 2016 -0700
@@ -357,3 +357,5 @@
 1565a0efe6f0ca411a6df277df1e069431c60988 jdk-9+112
 68f8be44b6a6b33dfa841ec671c0ba6e4056b372 jdk-9+113
 bb8379287f3736f38c52b2d1418784e2592461d1 jdk-9+114
+35225b837d66582037eeadeb471c13235dfd793d jdk-9+115
+baeb5edb38939cdb78ae0ac6f4fd368465cbf188 jdk-9+116
--- a/jdk/make/Import.gmk	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/make/Import.gmk	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2016, 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
@@ -83,20 +83,20 @@
   endif
 
   ifneq ($(OPENJDK_TARGET_OS), windows)
-    ifeq ($(JVM_VARIANT_SERVER), true)
+    ifeq ($(call check-jvm-variant, server), true)
       BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/server/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX)
       ifneq (, $(JSIG_DEBUGINFO))
         BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/server/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I))
       endif
     endif
-    ifeq ($(JVM_VARIANT_CLIENT), true)
+    ifeq ($(call check-jvm-variant, client), true)
       BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/client/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX)
       ifneq (, $(JSIG_DEBUGINFO))
         BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/client/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I))
       endif
     endif
     ifneq ($(OPENJDK_TARGET_OS), macosx)
-      ifeq ($(JVM_VARIANT_MINIMAL1), true)
+      ifeq ($(call check-jvm-variant, minimal), true)
         BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/minimal/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX)
         ifneq (,$(JSIG_DEBUGINFO))
           BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/minimal/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I))
--- a/jdk/make/copy/Copy-java.base.gmk	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/make/copy/Copy-java.base.gmk	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2016, 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
@@ -88,7 +88,7 @@
 #
 # How to install jvm.cfg.
 #
-ifeq ($(JVM_VARIANT_ZERO), true)
+ifeq ($(call check-jvm-variant, zero zeroshark), true)
   JVMCFG_ARCH := zero
 else
   JVMCFG_ARCH := $(OPENJDK_TARGET_CPU_LEGACY)
@@ -99,7 +99,7 @@
 else
   JVMCFG_SRC := $(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/conf/$(JVMCFG_ARCH)/jvm.cfg
   # Allow override by ALT_JVMCFG_SRC if it exists
-  JVMCFG_SRC := $(if $(wildcard $(ALT_JVMCFG_SRC)),$(ALT_JVMCFG_SRC),$(JVMCFG_SRC)) 
+  JVMCFG_SRC := $(if $(wildcard $(ALT_JVMCFG_SRC)),$(ALT_JVMCFG_SRC),$(JVMCFG_SRC))
 endif
 JVMCFG_DIR := $(LIB_DST_DIR)$(OPENJDK_TARGET_CPU_LIBDIR)
 JVMCFG := $(JVMCFG_DIR)/jvm.cfg
@@ -117,12 +117,12 @@
   # The main problem is deciding whether to use aliases for the VMs that are not
   # present and the current position is that we add aliases for client and server, but
   # not for minimal.
-  CLIENT_AND_SERVER := $(and $(findstring true, $(JVM_VARIANT_SERVER)), $(findstring true, $(JVM_VARIANT_CLIENT)))
-  ifeq ($(CLIENT_AND_SERVER), true)
+  CLIENT_AND_SERVER := $(call check-jvm-variant, client)+$(call check-jvm-variant, server)
+  ifeq ($(CLIENT_AND_SERVER), true+true)
     COPY_JVM_CFG_FILE := true
   else
     # For zero, the default jvm.cfg file is sufficient
-    ifeq ($(JVM_VARIANT_ZERO), true)
+    ifeq ($(call check-jvm-variant, zero zeroshark), true)
       COPY_JVM_CFG_FILE := true
     endif
   endif
@@ -136,21 +136,21 @@
 	$(MKDIR) -p $(@D)
 	$(RM) $(@)
         # Now check for other permutations
-        ifeq ($(JVM_VARIANT_SERVER), true)
+        ifeq ($(call check-jvm-variant, server), true)
 	  $(PRINTF) "-server KNOWN\n">>$(@)
 	  $(PRINTF) "-client ALIASED_TO -server\n">>$(@)
-          ifeq ($(JVM_VARIANT_MINIMAL1), true)
+          ifeq ($(call check-jvm-variant, minimal), true)
 	    $(PRINTF) "-minimal KNOWN\n">>$(@)
           endif
         else
-          ifeq ($(JVM_VARIANT_CLIENT), true)
+          ifeq ($(call check-jvm-variant, client), true)
 	    $(PRINTF) "-client KNOWN\n">>$(@)
 	    $(PRINTF) "-server ALIASED_TO -client\n">>$(@)
-            ifeq ($(JVM_VARIANT_MINIMAL1), true)
+            ifeq ($(call check-jvm-variant, minimal), true)
 	      $(PRINTF) "-minimal KNOWN\n">>$(@)
             endif
           else
-            ifeq ($(JVM_VARIANT_MINIMAL1), true)
+            ifeq ($(call check-jvm-variant, minimal), true)
 	      $(PRINTF) "-minimal KNOWN\n">>$(@)
 	      $(PRINTF) "-server ALIASED_TO -minimal\n">>$(@)
 	      $(PRINTF) "-client ALIASED_TO -minimal\n">>$(@)
--- a/jdk/make/data/fontconfig/windows.fontconfig.properties	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/make/data/fontconfig/windows.fontconfig.properties	Thu Apr 28 23:08:16 2016 -0700
@@ -37,6 +37,7 @@
 allfonts.chinese-hkscs=MingLiU_HKSCS
 allfonts.chinese-ms950-extb=MingLiU-ExtB
 allfonts.devanagari=Mangal
+allfonts.kannada=Tunga
 allfonts.dingbats=Wingdings
 allfonts.lucida=Lucida Sans Regular
 allfonts.symbol=Symbol
@@ -239,11 +240,11 @@
 
 sequence.fallback=lucida,symbols,\
                   chinese-ms950,chinese-hkscs,chinese-ms936,chinese-gb18030,\
-                  japanese,korean,chinese-ms950-extb,chinese-ms936-extb,georgian
+                  japanese,korean,chinese-ms950-extb,chinese-ms936-extb,georgian,kannada
 
 # Exclusion Ranges
 
-exclusion.alphabetic=0700-1e9f,1f00-20ab,20ad-f8ff
+exclusion.alphabetic=0700-1e9f,1f00-2017,2020-20ab,20ad-20b8,20bb-20bc,20be-f8ff
 exclusion.chinese-gb18030=0390-03d6,2200-22ef,2701-27be
 exclusion.hebrew=0041-005a,0060-007a,007f-00ff,20ac-20ac
 
@@ -295,6 +296,7 @@
 
 filename.Lucida_Sans_Regular=LucidaSansRegular.ttf
 filename.Mangal=MANGAL.TTF
+filename.Tunga=TUNGA.TTF
 filename.Symbol=SYMBOL.TTF
 filename.Wingdings=WINGDING.TTF
 
--- a/jdk/make/gendata/Gendata-java.base.gmk	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/make/gendata/Gendata-java.base.gmk	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -41,7 +41,7 @@
 GENDATA_UNINAME := $(JDK_OUTPUTDIR)/modules/java.base/java/lang/uniName.dat
 
 $(GENDATA_UNINAME): $(JDK_TOPDIR)/make/data/unicodedata/UnicodeData.txt $(BUILD_TOOLS_JDK)
-	$(MKDIR) -p $(@D)
+	$(call MakeDir, $(@D))
 	$(TOOL_CHARACTERNAME) $< $@
 
 TARGETS += $(GENDATA_UNINAME)
@@ -51,7 +51,7 @@
 GENDATA_CURDATA := $(JDK_OUTPUTDIR)/modules/java.base/java/util/currency.data
 
 $(GENDATA_CURDATA): $(JDK_TOPDIR)/make/data/currency/CurrencyData.properties $(BUILD_TOOLS_JDK)
-	$(MKDIR) -p $(@D)
+	$(call MakeDir, $(@D))
 	$(RM) $@
 	$(TOOL_GENERATECURRENCYDATA) -o $@.tmp < $<
 	$(MV) $@.tmp $@
@@ -67,10 +67,10 @@
 # RESTRICTED_PKGS_SRC is optionally set in custom extension for this makefile
 
 $(GENDATA_JAVA_SECURITY): $(BUILD_TOOLS) $(GENDATA_JAVA_SECURITY_SRC) $(RESTRICTED_PKGS_SRC)
-	$(ECHO) "Generating java.security"
-	$(MKDIR) -p $(@D)
+	$(call LogInfo, Generating java.security)
+	$(call MakeDir, $(@D))
 	$(TOOL_MAKEJAVASECURITY) $(GENDATA_JAVA_SECURITY_SRC) $@ $(OPENJDK_TARGET_OS) \
-		$(OPENJDK_TARGET_CPU_ARCH) $(RESTRICTED_PKGS_SRC) || exit 1
+	    $(OPENJDK_TARGET_CPU_ARCH) $(RESTRICTED_PKGS_SRC)
 
 TARGETS += $(GENDATA_JAVA_SECURITY)
 
@@ -78,7 +78,7 @@
 
 $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/classlist: \
     $(JDK_TOPDIR)/make/data/classlist/classlist.$(OPENJDK_TARGET_OS)
-	$(MKDIR) -p $(@D)
+	$(call MakeDir, $(@D))
 	$(RM) $@ $@.tmp
 	$(TOOL_ADDJSUM) $< $@.tmp
 	$(MV) $@.tmp $@
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/launcher/Launcher-jdk.jstatd.gmk	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+include LauncherCommon.gmk
+
+$(eval $(call SetupBuildLauncher, jstatd, \
+    MAIN_CLASS := sun.tools.jstatd.Jstatd, \
+))
--- a/jdk/make/launcher/Launcher-jdk.jvmstat.rmi.gmk	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.  Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-include LauncherCommon.gmk
-
-$(eval $(call SetupBuildLauncher, jstatd, \
-    MAIN_CLASS := sun.tools.jstatd.Jstatd, \
-))
--- a/jdk/make/lib/Awt2dLibraries.gmk	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/make/lib/Awt2dLibraries.gmk	Thu Apr 28 23:08:16 2016 -0700
@@ -375,6 +375,7 @@
         OPTIMIZATION := LOW, \
         CFLAGS := $(CFLAGS_JDKLIB) $(LIBAWT_XAWT_CFLAGS) \
             $(X_CFLAGS), \
+        WARNINGS_AS_ERRORS_xlc := false, \
         DISABLED_WARNINGS_gcc := type-limits pointer-to-int-cast \
             deprecated-declarations unused-result maybe-uninitialized format \
             format-security int-to-pointer-cast parentheses, \
@@ -587,6 +588,7 @@
             $(CUPS_CFLAGS) \
             $(X_CFLAGS) \
             $(LIBAWT_HEADLESS_CFLAGS), \
+        DISABLED_WARNINGS_xlc := 1506-356, \
         DISABLED_WARNINGS_gcc := maybe-uninitialized int-to-pointer-cast, \
         DISABLED_WARNINGS_solstudio := E_DECLARATION_IN_CODE \
             E_EMPTY_TRANSLATION_UNIT, \
@@ -603,6 +605,10 @@
         OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libawt_headless, \
     ))
 
+    # AIX warning explanation:
+    # 1506-356 : (W) Compilation unit is empty.
+    #            This happens during the headless build
+
     $(BUILD_LIBAWT_HEADLESS): $(BUILD_LIBAWT)
 
     TARGETS += $(BUILD_LIBAWT_HEADLESS)
@@ -700,6 +706,7 @@
     CXXFLAGS := $(CXXFLAGS_JDKLIB) $(LIBFONTMANAGER_CFLAGS), \
     OPTIMIZATION := $(LIBFONTMANAGER_OPTIMIZATION), \
     CFLAGS_windows = -DCC_NOEX, \
+    WARNINGS_AS_ERRORS_xlc := false, \
     DISABLED_WARNINGS_gcc := sign-compare int-to-pointer-cast \
         type-limits missing-field-initializers, \
     DISABLED_WARNINGS_CXX_gcc := reorder delete-non-virtual-dtor strict-overflow \
--- a/jdk/make/lib/CoreLibraries.gmk	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/make/lib/CoreLibraries.gmk	Thu Apr 28 23:08:16 2016 -0700
@@ -146,6 +146,7 @@
         $(LIBJAVA_CFLAGS), \
     System.c_CFLAGS := $(VERSION_CFLAGS), \
     jdk_util.c_CFLAGS := $(VERSION_CFLAGS), \
+    WARNINGS_AS_ERRORS_xlc := false, \
     DISABLED_WARNINGS_gcc := unused-result, \
     DISABLED_WARNINGS_solstudio := E_STATEMENT_NOT_REACHED, \
     MAPFILE := $(LIBJAVA_MAPFILE), \
@@ -266,7 +267,7 @@
     LDFLAGS_windows := -export:JIMAGE_Open -export:JIMAGE_Close \
         -export:JIMAGE_PackageToModule \
         -export:JIMAGE_FindResource -export:JIMAGE_GetResource \
-        -export:JIMAGE_ResourceIterator, \
+        -export:JIMAGE_ResourceIterator -export:JIMAGE_ResourcePath, \
     LIBS_unix := -ljvm -ldl $(LIBCXX), \
     LIBS_solaris := -lc, \
     LIBS_macosx := -lc++, \
@@ -289,7 +290,7 @@
 
 LIBJLI_CFLAGS := $(CFLAGS_JDKLIB)
 
-ifeq ($(JVM_VARIANT_ZERO), true)
+ifeq ($(call check-jvm-variant, zero zeroshark), true)
   ERGO_FAMILY := zero
 else
   ifeq ($(OPENJDK_TARGET_CPU_ARCH), x86)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/lib/Lib-jdk.net.gmk	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,51 @@
+#
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+include LibCommon.gmk
+
+################################################################################
+
+ifeq ($(OPENJDK_TARGET_OS), solaris)
+
+  $(eval $(call SetupNativeCompilation, BUILD_LIBEXTNET, \
+      LIBRARY := extnet, \
+      OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+      SRC := $(JDK_TOPDIR)/src/jdk.net/solaris/native/libextnet, \
+      OPTIMIZATION := LOW, \
+      CFLAGS := $(CFLAGS_JDKLIB) -I$(SUPPORT_OUTPUTDIR)/headers/jdk.net, \
+      MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libextnet/mapfile-vers, \
+      LDFLAGS := $(LDFLAGS_JDKLIB) \
+          $(call SET_SHARED_LIBRARY_ORIGIN), \
+      LIBS := -lsocket -lc -ljava, \
+      OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libextnet, \
+  ))
+
+  $(BUILD_LIBEXTNET): $(call FindLib, java.base, java)
+
+  TARGETS += $(BUILD_LIBEXTNET)
+endif
+
+
+################################################################################
--- a/jdk/make/lib/NioLibraries.gmk	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/make/lib/NioLibraries.gmk	Thu Apr 28 23:08:16 2016 -0700
@@ -70,6 +70,7 @@
     SRC := $(BUILD_LIBNIO_SRC), \
     EXCLUDE_FILES := $(BUILD_LIBNIO_EXFILES), \
     OPTIMIZATION := HIGH, \
+    WARNINGS_AS_ERRORS_xlc := false, \
     CFLAGS := $(CFLAGS_JDKLIB) \
         $(BUILD_LIBNIO_CFLAGS), \
     MAPFILE := $(BUILD_LIBNIO_MAPFILE), \
--- a/jdk/make/mapfiles/libawt_xawt/mapfile-vers	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/make/mapfiles/libawt_xawt/mapfile-vers	Thu Apr 28 23:08:16 2016 -0700
@@ -179,6 +179,7 @@
         Java_sun_awt_UNIXToolkit_load_1gtk_1icon;
         Java_sun_awt_UNIXToolkit_nativeSync;
         Java_sun_awt_UNIXToolkit_gtkCheckVersionImpl;
+        Java_sun_awt_UNIXToolkit_get_1gtk_1version;
         Java_java_awt_AWTEvent_initIDs;
         Java_java_awt_event_InputEvent_initIDs;
         Java_java_awt_event_KeyEvent_initIDs;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/mapfiles/libextnet/mapfile-vers	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2016, 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.
+#
+
+SUNWprivate_1.1 {
+	global:
+	    Java_jdk_net_SolarisSocketOptions_init;
+	    Java_jdk_net_SolarisSocketOptions_setFlowOption;
+	    Java_jdk_net_SolarisSocketOptions_getFlowOption;
+	    Java_jdk_net_SolarisSocketOptions_flowSupported;
+	local:
+	    *;
+};
--- a/jdk/make/mapfiles/libjava/mapfile-vers	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/make/mapfiles/libjava/mapfile-vers	Thu Apr 28 23:08:16 2016 -0700
@@ -139,8 +139,7 @@
 		Java_java_lang_Double_doubleToRawLongBits;
 		Java_java_lang_Float_intBitsToFloat;
 		Java_java_lang_Float_floatToRawIntBits;
-                Java_java_lang_StackFrameInfo_fillInStackFrames;
-                Java_java_lang_StackFrameInfo_setMethodInfo;
+                Java_java_lang_StackFrameInfo_toStackTraceElement0;
                 Java_java_lang_StackStreamFactory_checkStackWalkModes;
                 Java_java_lang_StackStreamFactory_00024AbstractStackWalker_callStackWalk;
                 Java_java_lang_StackStreamFactory_00024AbstractStackWalker_fetchStackFrames;
--- a/jdk/make/mapfiles/libjimage/mapfile-vers	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/make/mapfiles/libjimage/mapfile-vers	Thu Apr 28 23:08:16 2016 -0700
@@ -34,6 +34,7 @@
         JIMAGE_FindResource;
         JIMAGE_GetResource;
         JIMAGE_ResourceIterator;
+        JIMAGE_ResourcePath;
     local:
         *;
 };
--- a/jdk/make/mapfiles/libnet/mapfile-vers	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/make/mapfiles/libnet/mapfile-vers	Thu Apr 28 23:08:16 2016 -0700
@@ -98,10 +98,6 @@
 		Java_sun_net_sdp_SdpSupport_create0;
 		Java_sun_net_spi_DefaultProxySelector_init;
 		Java_sun_net_spi_DefaultProxySelector_getSystemProxy;
-		Java_sun_net_ExtendedOptionsImpl_init;
-		Java_sun_net_ExtendedOptionsImpl_setFlowOption;
-		Java_sun_net_ExtendedOptionsImpl_getFlowOption;
-		Java_sun_net_ExtendedOptionsImpl_flowSupported;
 		NET_AllocSockaddr;
 		NET_SockaddrToInetAddress;
                 NET_SockaddrEqualsInetAddress;
--- a/jdk/make/netbeans/client_sanity/nbproject/genfiles.properties	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/make/netbeans/client_sanity/nbproject/genfiles.properties	Thu Apr 28 23:08:16 2016 -0700
@@ -3,6 +3,6 @@
 build.xml.stylesheet.CRC32=8064a381@1.75.2.48
 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
 # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
-nbproject/build-impl.xml.data.CRC32=55414227
+nbproject/build-impl.xml.data.CRC32=16caf60f
 nbproject/build-impl.xml.script.CRC32=c12f9d04
 nbproject/build-impl.xml.stylesheet.CRC32=05530350@1.79.1.48
--- a/jdk/make/netbeans/client_sanity/nbproject/project.properties	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/make/netbeans/client_sanity/nbproject/project.properties	Thu Apr 28 23:08:16 2016 -0700
@@ -76,4 +76,4 @@
 src.src.dir=..\\..\\..\\test\\sanity\\client\\SwingSet\\src
 src.src2.dir=..\\..\\..\\test\\sanity\\client\\lib\\SwingSet3\\src
 src.src3.dir=..\\..\\..\\test\\sanity\\client\\lib\\jemmy\\src
-src.src4.dir=..\\..\\..\\test\\sanity\\client\\lib\\Jemmy2Ext\\src
+src.src4.dir=..\\..\\..\\test\\sanity\\client\\lib\\Extensions\\src
--- a/jdk/make/netbeans/client_sanity/nbproject/project.xml	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/make/netbeans/client_sanity/nbproject/project.xml	Thu Apr 28 23:08:16 2016 -0700
@@ -6,7 +6,7 @@
             <name>SanityTests</name>
             <source-roots>
                 <root id="src.src3.dir" name="lib\jemmy\src"/>
-                <root id="src.src4.dir" name="lib\Jemmy2Ext\src"/>
+                <root id="src.src4.dir" name="lib\Extensions\src"/>
                 <root id="src.src2.dir" name="lib\SwingSet3\src"/>
                 <root id="src.src.dir" name="SwingSet\src"/>
             </source-roots>
--- a/jdk/make/src/classes/build/tools/generatenimbus/UIProperty.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/make/src/classes/build/tools/generatenimbus/UIProperty.java	Thu Apr 28 23:08:16 2016 -0700
@@ -54,13 +54,13 @@
                 return String.format("        d.put(\"%s%s\", \"%s\");\n",
                                      prefix, getName(), getValue());
             case INT:
-                return String.format("        d.put(\"%s%s\", new Integer(%s));\n",
+                return String.format("        d.put(\"%s%s\", Integer.valueOf(%s));\n",
                                      prefix, getName(), getValue());
             case FLOAT:
-                return String.format("        d.put(\"%s%s\", new Float(%sf));\n",
+                return String.format("        d.put(\"%s%s\", Float.valueOf(%sf));\n",
                                      prefix, getName(), getValue());
             case DOUBLE:
-                return String.format("        d.put(\"%s%s\", new Double(%s));\n",
+                return String.format("        d.put(\"%s%s\", Double.valueOf(%s));\n",
                                      prefix, getName(), getValue());
             case COLOR:
                 return String.format("        addColor(d, \"%s%s\", %s);\n",
--- a/jdk/make/src/classes/build/tools/module/GenModuleInfoSource.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/make/src/classes/build/tools/module/GenModuleInfoSource.java	Thu Apr 28 23:08:16 2016 -0700
@@ -52,7 +52,7 @@
         "Usage: GenModuleInfoSource [option] -o <output file> <module-info-java>\n" +
         "Options are:\n" +
         "  -exports  <package-name>\n" +
-        "  -exports  <package-name>/<module-name>\n" +
+        "  -exports  <package-name>[/<module-name>]\n" +
         "  -uses     <service>\n" +
         "  -provides <service>/<provider-impl-classname>\n";
 
--- a/jdk/src/java.base/aix/native/libnet/aix_close.c	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/aix/native/libnet/aix_close.c	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, SAP SE 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,6 +51,8 @@
    ...
 */
 
+#include <assert.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <signal.h>
@@ -86,10 +89,35 @@
 static int sigWakeup = (SIGRTMAX - 1);
 
 /*
- * The fd table and the number of file descriptors
+ * fdTable holds one entry per file descriptor, up to a certain
+ * maximum.
+ * Theoretically, the number of possible file descriptors can get
+ * large, though usually it does not. Entries for small value file
+ * descriptors are kept in a simple table, which covers most scenarios.
+ * Entries for large value file descriptors are kept in an overflow
+ * table, which is organized as a sparse two dimensional array whose
+ * slabs are allocated on demand. This covers all corner cases while
+ * keeping memory consumption reasonable.
  */
-static fdEntry_t *fdTable = NULL;
-static int fdCount = 0;
+
+/* Base table for low value file descriptors */
+static fdEntry_t* fdTable = NULL;
+/* Maximum size of base table (in number of entries). */
+static const int fdTableMaxSize = 0x1000; /* 4K */
+/* Actual size of base table (in number of entries) */
+static int fdTableLen = 0;
+/* Max. theoretical number of file descriptors on system. */
+static int fdLimit = 0;
+
+/* Overflow table, should base table not be large enough. Organized as
+ *   an array of n slabs, each holding 64k entries.
+ */
+static fdEntry_t** fdOverflowTable = NULL;
+/* Number of slabs in the overflow table */
+static int fdOverflowTableLen = 0;
+/* Number of entries in one slab */
+static const int fdOverflowTableSlabSize = 0x10000; /* 64k */
+pthread_mutex_t fdOverflowTableLock = PTHREAD_MUTEX_INITIALIZER;
 
 /*
  * Null signal handler
@@ -108,42 +136,42 @@
     struct rlimit nbr_files;
     sigset_t sigset;
     struct sigaction sa;
+    int i = 0;
 
-    /* Check already initialized */
-    if (fdCount > 0 && fdTable != NULL) {
-        return;
-    }
-
-    /*
-     * Allocate table based on the maximum number of
-     * file descriptors.
-     */
+    /* Determine the maximum number of possible file descriptors. */
     if (-1 == getrlimit(RLIMIT_NOFILE, &nbr_files)) {
         fprintf(stderr, "library initialization failed - "
                 "unable to get max # of allocated fds\n");
         abort();
     }
-    fdCount = nbr_files.rlim_max;
-    /*
-     * We have a conceptual problem here, when the number of files is
-     * unlimited. As a kind of workaround, we ensure the table is big
-     * enough for handle even a large number of files. Since SAP itself
-     * recommends a limit of 32000 files, we just use 64000 as 'infinity'.
-     */
-    if (nbr_files.rlim_max == RLIM_INFINITY) {
-        fdCount = 64000;
+    if (nbr_files.rlim_max != RLIM_INFINITY) {
+        fdLimit = nbr_files.rlim_max;
+    } else {
+        /* We just do not know. */
+        fdLimit = INT_MAX;
     }
-    fdTable = (fdEntry_t *)calloc(fdCount, sizeof(fdEntry_t));
+
+    /* Allocate table for low value file descriptors. */
+    fdTableLen = fdLimit < fdTableMaxSize ? fdLimit : fdTableMaxSize;
+    fdTable = (fdEntry_t*) calloc(fdTableLen, sizeof(fdEntry_t));
     if (fdTable == NULL) {
         fprintf(stderr, "library initialization failed - "
                 "unable to allocate file descriptor table - out of memory");
         abort();
+    } else {
+        for (i = 0; i < fdTableLen; i ++) {
+            pthread_mutex_init(&fdTable[i].lock, NULL);
+        }
     }
 
-    {
-        int i;
-        for (i=0; i < fdCount; i++) {
-            pthread_mutex_init(&fdTable[i].lock, NULL);
+    /* Allocate overflow table, if needed */
+    if (fdLimit > fdTableMaxSize) {
+        fdOverflowTableLen = ((fdLimit - fdTableMaxSize) / fdOverflowTableSlabSize) + 1;
+        fdOverflowTable = (fdEntry_t**) calloc(fdOverflowTableLen, sizeof(fdEntry_t*));
+        if (fdOverflowTable == NULL) {
+            fprintf(stderr, "library initialization failed - "
+                    "unable to allocate file descriptor overflow table - out of memory");
+            abort();
         }
     }
 
@@ -161,17 +189,60 @@
 }
 
 /*
- * Return the fd table for this fd or NULL is fd out
- * of range.
+ * Return the fd table for this fd.
  */
 static inline fdEntry_t *getFdEntry(int fd)
 {
-    if (fd < 0 || fd >= fdCount) {
+    fdEntry_t* result = NULL;
+
+    if (fd < 0) {
         return NULL;
     }
-    return &fdTable[fd];
+
+    /* This should not happen. If it does, our assumption about
+     * max. fd value was wrong. */
+    assert(fd < fdLimit);
+
+    if (fd < fdTableMaxSize) {
+        /* fd is in base table. */
+        assert(fd < fdTableLen);
+        result = &fdTable[fd];
+    } else {
+        /* fd is in overflow table. */
+        const int indexInOverflowTable = fd - fdTableMaxSize;
+        const int rootindex = indexInOverflowTable / fdOverflowTableSlabSize;
+        const int slabindex = indexInOverflowTable % fdOverflowTableSlabSize;
+        fdEntry_t* slab = NULL;
+        assert(rootindex < fdOverflowTableLen);
+        assert(slabindex < fdOverflowTableSlabSize);
+        pthread_mutex_lock(&fdOverflowTableLock);
+        /* Allocate new slab in overflow table if needed */
+        if (fdOverflowTable[rootindex] == NULL) {
+            fdEntry_t* const newSlab =
+                (fdEntry_t*)calloc(fdOverflowTableSlabSize, sizeof(fdEntry_t));
+            if (newSlab == NULL) {
+                fprintf(stderr, "Unable to allocate file descriptor overflow"
+                        " table slab - out of memory");
+                pthread_mutex_unlock(&fdOverflowTableLock);
+                abort();
+            } else {
+                int i;
+                for (i = 0; i < fdOverflowTableSlabSize; i ++) {
+                    pthread_mutex_init(&newSlab[i].lock, NULL);
+                }
+                fdOverflowTable[rootindex] = newSlab;
+            }
+        }
+        pthread_mutex_unlock(&fdOverflowTableLock);
+        slab = fdOverflowTable[rootindex];
+        result = &slab[slabindex];
+    }
+
+    return result;
+
 }
 
+
 /*
  * Start a blocking operation :-
  *    Insert thread onto thread list for the fd.
--- a/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxFileSystemProvider.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxFileSystemProvider.java	Thu Apr 28 23:08:16 2016 -0700
@@ -102,8 +102,8 @@
 
     @Override
     FileTypeDetector getFileTypeDetector() {
-        Path userMimeTypes = Paths.get(AccessController.doPrivileged(
-            new GetPropertyAction("user.home")), ".mime.types");
+        String userHome = GetPropertyAction.getProperty("user.home");
+        Path userMimeTypes = Paths.get(userHome, ".mime.types");
         Path etcMimeTypes = Paths.get("/etc/mime.types");
 
         return chain(new GioFileTypeDetector(),
--- a/jdk/src/java.base/linux/native/libnet/linux_close.c	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/linux/native/libnet/linux_close.c	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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
@@ -23,6 +23,8 @@
  * questions.
  */
 
+#include <assert.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <signal.h>
@@ -59,10 +61,35 @@
 static int sigWakeup = (__SIGRTMAX - 2);
 
 /*
- * The fd table and the number of file descriptors
+ * fdTable holds one entry per file descriptor, up to a certain
+ * maximum.
+ * Theoretically, the number of possible file descriptors can get
+ * large, though usually it does not. Entries for small value file
+ * descriptors are kept in a simple table, which covers most scenarios.
+ * Entries for large value file descriptors are kept in an overflow
+ * table, which is organized as a sparse two dimensional array whose
+ * slabs are allocated on demand. This covers all corner cases while
+ * keeping memory consumption reasonable.
  */
-static fdEntry_t *fdTable;
-static int fdCount;
+
+/* Base table for low value file descriptors */
+static fdEntry_t* fdTable = NULL;
+/* Maximum size of base table (in number of entries). */
+static const int fdTableMaxSize = 0x1000; /* 4K */
+/* Actual size of base table (in number of entries) */
+static int fdTableLen = 0;
+/* Max. theoretical number of file descriptors on system. */
+static int fdLimit = 0;
+
+/* Overflow table, should base table not be large enough. Organized as
+ *   an array of n slabs, each holding 64k entries.
+ */
+static fdEntry_t** fdOverflowTable = NULL;
+/* Number of slabs in the overflow table */
+static int fdOverflowTableLen = 0;
+/* Number of entries in one slab */
+static const int fdOverflowTableSlabSize = 0x10000; /* 64k */
+pthread_mutex_t fdOverflowTableLock = PTHREAD_MUTEX_INITIALIZER;
 
 /*
  * Null signal handler
@@ -78,18 +105,43 @@
     struct rlimit nbr_files;
     sigset_t sigset;
     struct sigaction sa;
+    int i = 0;
 
-    /*
-     * Allocate table based on the maximum number of
-     * file descriptors.
-     */
-    getrlimit(RLIMIT_NOFILE, &nbr_files);
-    fdCount = nbr_files.rlim_max;
-    fdTable = (fdEntry_t *)calloc(fdCount, sizeof(fdEntry_t));
+    /* Determine the maximum number of possible file descriptors. */
+    if (-1 == getrlimit(RLIMIT_NOFILE, &nbr_files)) {
+        fprintf(stderr, "library initialization failed - "
+                "unable to get max # of allocated fds\n");
+        abort();
+    }
+    if (nbr_files.rlim_max != RLIM_INFINITY) {
+        fdLimit = nbr_files.rlim_max;
+    } else {
+        /* We just do not know. */
+        fdLimit = INT_MAX;
+    }
+
+    /* Allocate table for low value file descriptors. */
+    fdTableLen = fdLimit < fdTableMaxSize ? fdLimit : fdTableMaxSize;
+    fdTable = (fdEntry_t*) calloc(fdTableLen, sizeof(fdEntry_t));
     if (fdTable == NULL) {
         fprintf(stderr, "library initialization failed - "
                 "unable to allocate file descriptor table - out of memory");
         abort();
+    } else {
+        for (i = 0; i < fdTableLen; i ++) {
+            pthread_mutex_init(&fdTable[i].lock, NULL);
+        }
+    }
+
+    /* Allocate overflow table, if needed */
+    if (fdLimit > fdTableMaxSize) {
+        fdOverflowTableLen = ((fdLimit - fdTableMaxSize) / fdOverflowTableSlabSize) + 1;
+        fdOverflowTable = (fdEntry_t**) calloc(fdOverflowTableLen, sizeof(fdEntry_t*));
+        if (fdOverflowTable == NULL) {
+            fprintf(stderr, "library initialization failed - "
+                    "unable to allocate file descriptor overflow table - out of memory");
+            abort();
+        }
     }
 
     /*
@@ -106,15 +158,57 @@
 }
 
 /*
- * Return the fd table for this fd or NULL is fd out
- * of range.
+ * Return the fd table for this fd.
  */
 static inline fdEntry_t *getFdEntry(int fd)
 {
-    if (fd < 0 || fd >= fdCount) {
+    fdEntry_t* result = NULL;
+
+    if (fd < 0) {
         return NULL;
     }
-    return &fdTable[fd];
+
+    /* This should not happen. If it does, our assumption about
+     * max. fd value was wrong. */
+    assert(fd < fdLimit);
+
+    if (fd < fdTableMaxSize) {
+        /* fd is in base table. */
+        assert(fd < fdTableLen);
+        result = &fdTable[fd];
+    } else {
+        /* fd is in overflow table. */
+        const int indexInOverflowTable = fd - fdTableMaxSize;
+        const int rootindex = indexInOverflowTable / fdOverflowTableSlabSize;
+        const int slabindex = indexInOverflowTable % fdOverflowTableSlabSize;
+        fdEntry_t* slab = NULL;
+        assert(rootindex < fdOverflowTableLen);
+        assert(slabindex < fdOverflowTableSlabSize);
+        pthread_mutex_lock(&fdOverflowTableLock);
+        /* Allocate new slab in overflow table if needed */
+        if (fdOverflowTable[rootindex] == NULL) {
+            fdEntry_t* const newSlab =
+                (fdEntry_t*)calloc(fdOverflowTableSlabSize, sizeof(fdEntry_t));
+            if (newSlab == NULL) {
+                fprintf(stderr, "Unable to allocate file descriptor overflow"
+                        " table slab - out of memory");
+                pthread_mutex_unlock(&fdOverflowTableLock);
+                abort();
+            } else {
+                int i;
+                for (i = 0; i < fdOverflowTableSlabSize; i ++) {
+                    pthread_mutex_init(&newSlab[i].lock, NULL);
+                }
+                fdOverflowTable[rootindex] = newSlab;
+            }
+        }
+        pthread_mutex_unlock(&fdOverflowTableLock);
+        slab = fdOverflowTable[rootindex];
+        result = &slab[slabindex];
+    }
+
+    return result;
+
 }
 
 /*
--- a/jdk/src/java.base/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java	Thu Apr 28 23:08:16 2016 -0700
@@ -32,9 +32,9 @@
 package sun.nio.ch;
 
 import java.io.IOException;
-import java.io.FileDescriptor;
 import java.util.Iterator;
 import java.util.LinkedList;
+import sun.security.action.GetPropertyAction;
 
 /*
  * struct kevent {           // 32-bit    64-bit
@@ -84,10 +84,8 @@
     static {
         IOUtil.load();
         initStructSizes();
-        String datamodel = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction("sun.arch.data.model")
-        );
-        is64bit = datamodel.equals("64");
+        String datamodel = GetPropertyAction.getProperty("sun.arch.data.model");
+        is64bit = "64".equals(datamodel);
     }
 
     KQueueArrayWrapper() {
--- a/jdk/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystemProvider.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystemProvider.java	Thu Apr 28 23:08:16 2016 -0700
@@ -28,7 +28,6 @@
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.spi.FileTypeDetector;
-import java.security.AccessController;
 import sun.security.action.GetPropertyAction;
 
 /**
@@ -47,8 +46,8 @@
 
     @Override
     FileTypeDetector getFileTypeDetector() {
-        Path userMimeTypes = Paths.get(AccessController.doPrivileged(
-            new GetPropertyAction("user.home")), ".mime.types");
+        Path userMimeTypes = Paths.get(
+            GetPropertyAction.getProperty("user.home"), ".mime.types");
 
         return chain(new MimeTypesFileTypeDetector(userMimeTypes),
                      new UTIFileTypeDetector());
--- a/jdk/src/java.base/macosx/native/libnet/bsd_close.c	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/macosx/native/libnet/bsd_close.c	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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
@@ -23,6 +23,8 @@
  * questions.
  */
 
+#include <assert.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/param.h>
@@ -61,18 +63,35 @@
 static int sigWakeup = SIGIO;
 
 /*
- * The fd table and the number of file descriptors
+ * fdTable holds one entry per file descriptor, up to a certain
+ * maximum.
+ * Theoretically, the number of possible file descriptors can get
+ * large, though usually it does not. Entries for small value file
+ * descriptors are kept in a simple table, which covers most scenarios.
+ * Entries for large value file descriptors are kept in an overflow
+ * table, which is organized as a sparse two dimensional array whose
+ * slabs are allocated on demand. This covers all corner cases while
+ * keeping memory consumption reasonable.
  */
-static fdEntry_t *fdTable;
-static int fdCount;
 
-/*
- * This limit applies if getlimit() returns unlimited.
- * Unfortunately, this means if someone wants a higher limit
- * then they have to set an explicit limit, higher than this,
- * which is probably counter-intuitive.
+/* Base table for low value file descriptors */
+static fdEntry_t* fdTable = NULL;
+/* Maximum size of base table (in number of entries). */
+static const int fdTableMaxSize = 0x1000; /* 4K */
+/* Actual size of base table (in number of entries) */
+static int fdTableLen = 0;
+/* Max. theoretical number of file descriptors on system. */
+static int fdLimit = 0;
+
+/* Overflow table, should base table not be large enough. Organized as
+ *   an array of n slabs, each holding 64k entries.
  */
-#define MAX_FD_COUNT 4096
+static fdEntry_t** fdOverflowTable = NULL;
+/* Number of slabs in the overflow table */
+static int fdOverflowTableLen = 0;
+/* Number of entries in one slab */
+static const int fdOverflowTableSlabSize = 0x10000; /* 64k */
+pthread_mutex_t fdOverflowTableLock = PTHREAD_MUTEX_INITIALIZER;
 
 /*
  * Null signal handler
@@ -88,26 +107,43 @@
     struct rlimit nbr_files;
     sigset_t sigset;
     struct sigaction sa;
-    int i;
+    int i = 0;
 
-    /*
-     * Allocate table based on the maximum number of
-     * file descriptors.
-     */
-    getrlimit(RLIMIT_NOFILE, &nbr_files);
-    if (nbr_files.rlim_max == RLIM_INFINITY) {
-        fdCount = MAX_FD_COUNT;
+    /* Determine the maximum number of possible file descriptors. */
+    if (-1 == getrlimit(RLIMIT_NOFILE, &nbr_files)) {
+        fprintf(stderr, "library initialization failed - "
+                "unable to get max # of allocated fds\n");
+        abort();
+    }
+    if (nbr_files.rlim_max != RLIM_INFINITY) {
+        fdLimit = nbr_files.rlim_max;
     } else {
-        fdCount = nbr_files.rlim_max;
+        /* We just do not know. */
+        fdLimit = INT_MAX;
     }
-    fdTable = (fdEntry_t *)calloc(fdCount, sizeof(fdEntry_t));
+
+    /* Allocate table for low value file descriptors. */
+    fdTableLen = fdLimit < fdTableMaxSize ? fdLimit : fdTableMaxSize;
+    fdTable = (fdEntry_t*) calloc(fdTableLen, sizeof(fdEntry_t));
     if (fdTable == NULL) {
         fprintf(stderr, "library initialization failed - "
                 "unable to allocate file descriptor table - out of memory");
         abort();
+    } else {
+        for (i = 0; i < fdTableLen; i ++) {
+            pthread_mutex_init(&fdTable[i].lock, NULL);
+        }
     }
-    for (i=0; i<fdCount; i++) {
-        pthread_mutex_init(&fdTable[i].lock, NULL);
+
+    /* Allocate overflow table, if needed */
+    if (fdLimit > fdTableMaxSize) {
+        fdOverflowTableLen = ((fdLimit - fdTableMaxSize) / fdOverflowTableSlabSize) + 1;
+        fdOverflowTable = (fdEntry_t**) calloc(fdOverflowTableLen, sizeof(fdEntry_t*));
+        if (fdOverflowTable == NULL) {
+            fprintf(stderr, "library initialization failed - "
+                    "unable to allocate file descriptor overflow table - out of memory");
+            abort();
+        }
     }
 
     /*
@@ -124,17 +160,60 @@
 }
 
 /*
- * Return the fd table for this fd or NULL is fd out
- * of range.
+ * Return the fd table for this fd.
  */
 static inline fdEntry_t *getFdEntry(int fd)
 {
-    if (fd < 0 || fd >= fdCount) {
+    fdEntry_t* result = NULL;
+
+    if (fd < 0) {
         return NULL;
     }
-    return &fdTable[fd];
+
+    /* This should not happen. If it does, our assumption about
+     * max. fd value was wrong. */
+    assert(fd < fdLimit);
+
+    if (fd < fdTableMaxSize) {
+        /* fd is in base table. */
+        assert(fd < fdTableLen);
+        result = &fdTable[fd];
+    } else {
+        /* fd is in overflow table. */
+        const int indexInOverflowTable = fd - fdTableMaxSize;
+        const int rootindex = indexInOverflowTable / fdOverflowTableSlabSize;
+        const int slabindex = indexInOverflowTable % fdOverflowTableSlabSize;
+        fdEntry_t* slab = NULL;
+        assert(rootindex < fdOverflowTableLen);
+        assert(slabindex < fdOverflowTableSlabSize);
+        pthread_mutex_lock(&fdOverflowTableLock);
+        /* Allocate new slab in overflow table if needed */
+        if (fdOverflowTable[rootindex] == NULL) {
+            fdEntry_t* const newSlab =
+                (fdEntry_t*)calloc(fdOverflowTableSlabSize, sizeof(fdEntry_t));
+            if (newSlab == NULL) {
+                fprintf(stderr, "Unable to allocate file descriptor overflow"
+                        " table slab - out of memory");
+                pthread_mutex_unlock(&fdOverflowTableLock);
+                abort();
+            } else {
+                int i;
+                for (i = 0; i < fdOverflowTableSlabSize; i ++) {
+                    pthread_mutex_init(&newSlab[i].lock, NULL);
+                }
+                fdOverflowTable[rootindex] = newSlab;
+            }
+        }
+        pthread_mutex_unlock(&fdOverflowTableLock);
+        slab = fdOverflowTable[rootindex];
+        result = &slab[slabindex];
+    }
+
+    return result;
+
 }
 
+
 /*
  * Start a blocking operation :-
  *    Insert thread onto thread list for the fd.
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java	Thu Apr 28 23:08:16 2016 -0700
@@ -512,11 +512,17 @@
         byte[] sOut = new byte[s.length];
         GCTR gctrForSToTag = new GCTR(embeddedCipher, this.preCounterBlock);
         gctrForSToTag.doFinal(s, 0, s.length, sOut, 0);
+
+        // check entire authentication tag for time-consistency
+        int mismatch = 0;
         for (int i = 0; i < tagLenBytes; i++) {
-            if (tag[i] != sOut[i]) {
-                throw new AEADBadTagException("Tag mismatch!");
-            }
+            mismatch |= tag[i] ^ sOut[i];
         }
+
+        if (mismatch != 0) {
+            throw new AEADBadTagException("Tag mismatch!");
+        }
+
         return len;
     }
 
--- a/jdk/src/java.base/share/classes/java/io/DataInput.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/io/DataInput.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2016, 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
@@ -182,10 +182,11 @@
      * not all bytes of {@code b} have been
      * updated with data from the input stream.
      *
-     * @param     b   the buffer into which the data is read.
-     * @exception  EOFException  if this stream reaches the end before reading
-     *               all the bytes.
-     * @exception  IOException   if an I/O error occurs.
+     * @param   b   the buffer into which the data is read.
+     * @throws  NullPointerException if {@code b} is {@code null}.
+     * @throws  EOFException  if this stream reaches the end before reading
+     *          all the bytes.
+     * @throws  IOException   if an I/O error occurs.
      */
     void readFully(byte b[]) throws IOException;
 
@@ -226,12 +227,16 @@
      * and so on. The number of bytes read is,
      * at most, equal to {@code len}.
      *
-     * @param     b   the buffer into which the data is read.
-     * @param off  an int specifying the offset into the data.
-     * @param len  an int specifying the number of bytes to read.
-     * @exception  EOFException  if this stream reaches the end before reading
-     *               all the bytes.
-     * @exception  IOException   if an I/O error occurs.
+     * @param   b    the buffer into which the data is read.
+     * @param   off  an int specifying the offset in the data array {@code b}.
+     * @param   len  an int specifying the number of bytes to read.
+     * @throws  NullPointerException if {@code b} is {@code null}.
+     * @throws  IndexOutOfBoundsException if {@code off} is negative,
+     *          {@code len} is negative, or {@code len} is greater than
+     *          {@code b.length - off}.
+     * @throws  EOFException  if this stream reaches the end before reading
+     *          all the bytes.
+     * @throws  IOException   if an I/O error occurs.
      */
     void readFully(byte b[], int off, int len) throws IOException;
 
--- a/jdk/src/java.base/share/classes/java/io/DataInputStream.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/io/DataInputStream.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2016, 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,38 +150,43 @@
     }
 
     /**
-     * See the general contract of the <code>readFully</code>
-     * method of <code>DataInput</code>.
+     * See the general contract of the {@code readFully}
+     * method of {@code DataInput}.
      * <p>
      * Bytes
      * for this operation are read from the contained
      * input stream.
      *
-     * @param      b   the buffer into which the data is read.
-     * @exception  EOFException  if this input stream reaches the end before
-     *             reading all the bytes.
-     * @exception  IOException   the stream has been closed and the contained
-     *             input stream does not support reading after close, or
-     *             another I/O error occurs.
-     * @see        java.io.FilterInputStream#in
+     * @param   b   the buffer into which the data is read.
+     * @throws  NullPointerException if {@code b} is {@code null}.
+     * @throws  EOFException  if this input stream reaches the end before
+     *          reading all the bytes.
+     * @throws  IOException   the stream has been closed and the contained
+     *          input stream does not support reading after close, or
+     *          another I/O error occurs.
+     * @see     java.io.FilterInputStream#in
      */
     public final void readFully(byte b[]) throws IOException {
         readFully(b, 0, b.length);
     }
 
     /**
-     * See the general contract of the <code>readFully</code>
-     * method of <code>DataInput</code>.
+     * See the general contract of the {@code readFully}
+     * method of {@code DataInput}.
      * <p>
      * Bytes
      * for this operation are read from the contained
      * input stream.
      *
      * @param      b     the buffer into which the data is read.
-     * @param      off   the start offset of the data.
+     * @param      off   the start offset in the data array {@code b}.
      * @param      len   the number of bytes to read.
+     * @exception  NullPointerException if {@code b} is {@code null}.
+     * @exception  IndexOutOfBoundsException if {@code off} is negative,
+     *             {@code len} is negative, or {@code len} is greater than
+     *             {@code b.length - off}.
      * @exception  EOFException  if this input stream reaches the end before
-     *               reading all the bytes.
+     *             reading all the bytes.
      * @exception  IOException   the stream has been closed and the contained
      *             input stream does not support reading after close, or
      *             another I/O error occurs.
--- a/jdk/src/java.base/share/classes/java/io/File.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/io/File.java	Thu Apr 28 23:08:16 2016 -0700
@@ -31,7 +31,6 @@
 import java.net.URISyntaxException;
 import java.util.List;
 import java.util.ArrayList;
-import java.security.AccessController;
 import java.security.SecureRandom;
 import java.nio.file.Path;
 import java.nio.file.FileSystems;
@@ -1896,8 +1895,8 @@
         private TempDirectory() { }
 
         // temporary directory location
-        private static final File tmpdir = new File(AccessController
-            .doPrivileged(new GetPropertyAction("java.io.tmpdir")));
+        private static final File tmpdir = new File(
+                GetPropertyAction.getProperty("java.io.tmpdir"));
         static File location() {
             return tmpdir;
         }
--- a/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java	Thu Apr 28 23:08:16 2016 -0700
@@ -40,6 +40,9 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import static java.io.ObjectStreamClass.processQueue;
+import jdk.internal.misc.JavaObjectInputStreamAccess;
+import jdk.internal.misc.ObjectStreamClassValidator;
+import jdk.internal.misc.SharedSecrets;
 import jdk.internal.misc.Unsafe;
 import sun.reflect.misc.ReflectUtil;
 
@@ -853,10 +856,14 @@
      * exactly 'length' bytes.
      *
      * @param   buf the buffer into which the data is read
-     * @param   off the start offset of the data
+     * @param   off the start offset in the destination array {@code buf}
      * @param   len the maximum number of bytes read
      * @return  the actual number of bytes read, -1 is returned when the end of
      *          the stream is reached.
+     * @throws  NullPointerException if {@code buf} is {@code null}.
+     * @throws  IndexOutOfBoundsException if {@code off} is negative,
+     *          {@code len} is negative, or {@code len} is greater than
+     *          {@code buf.length - off}.
      * @throws  IOException If an I/O error has occurred.
      * @see java.io.DataInputStream#readFully(byte[],int,int)
      */
@@ -1014,6 +1021,7 @@
      * Reads bytes, blocking until all bytes are read.
      *
      * @param   buf the buffer into which the data is read
+     * @throws  NullPointerException If {@code buf} is {@code null}.
      * @throws  EOFException If end of file is reached.
      * @throws  IOException If other I/O error has occurred.
      */
@@ -1025,8 +1033,12 @@
      * Reads bytes, blocking until all bytes are read.
      *
      * @param   buf the buffer into which the data is read
-     * @param   off the start offset of the data
+     * @param   off the start offset into the data array {@code buf}
      * @param   len the maximum number of bytes to read
+     * @throws  NullPointerException If {@code buf} is {@code null}.
+     * @throws  IndexOutOfBoundsException If {@code off} is negative,
+     *          {@code len} is negative, or {@code len} is greater than
+     *          {@code buf.length - off}.
      * @throws  EOFException If end of file is reached.
      * @throws  IOException If other I/O error has occurred.
      */
@@ -1509,23 +1521,28 @@
         throws IOException
     {
         byte tc = bin.peekByte();
+        ObjectStreamClass descriptor;
         switch (tc) {
             case TC_NULL:
-                return (ObjectStreamClass) readNull();
-
+                descriptor = (ObjectStreamClass) readNull();
+                break;
             case TC_REFERENCE:
-                return (ObjectStreamClass) readHandle(unshared);
-
+                descriptor = (ObjectStreamClass) readHandle(unshared);
+                break;
             case TC_PROXYCLASSDESC:
-                return readProxyDesc(unshared);
-
+                descriptor = readProxyDesc(unshared);
+                break;
             case TC_CLASSDESC:
-                return readNonProxyDesc(unshared);
-
+                descriptor = readNonProxyDesc(unshared);
+                break;
             default:
                 throw new StreamCorruptedException(
                     String.format("invalid type code: %02X", tc));
         }
+        if (descriptor != null) {
+            validateDescriptor(descriptor);
+        }
+        return descriptor;
     }
 
     private boolean isCustomSubclass() {
@@ -1915,6 +1932,8 @@
                 if (obj == null || handles.lookupException(passHandle) != null) {
                     defaultReadFields(null, slotDesc); // skip field values
                 } else if (slotDesc.hasReadObjectMethod()) {
+                    ThreadDeath t = null;
+                    boolean reset = false;
                     SerialCallbackContext oldContext = curContext;
                     if (oldContext != null)
                         oldContext.check();
@@ -1933,10 +1952,19 @@
                          */
                         handles.markException(passHandle, ex);
                     } finally {
-                        curContext.setUsed();
-                        if (oldContext!= null)
-                            oldContext.check();
-                        curContext = oldContext;
+                        do {
+                            try {
+                                curContext.setUsed();
+                                if (oldContext!= null)
+                                    oldContext.check();
+                                curContext = oldContext;
+                                reset = true;
+                            } catch (ThreadDeath x) {
+                                t = x;  // defer until reset is true
+                            }
+                        } while (!reset);
+                        if (t != null)
+                            throw t;
                     }
 
                     /*
@@ -3647,4 +3675,20 @@
         }
     }
 
+    private void validateDescriptor(ObjectStreamClass descriptor) {
+        ObjectStreamClassValidator validating = validator;
+        if (validating != null) {
+            validating.validateDescriptor(descriptor);
+        }
+    }
+
+    // controlled access to ObjectStreamClassValidator
+    private volatile ObjectStreamClassValidator validator;
+
+    private static void setValidator(ObjectInputStream ois, ObjectStreamClassValidator validator) {
+        ois.validator = validator;
+    }
+    static {
+        SharedSecrets.setJavaObjectInputStreamAccess(ObjectInputStream::setValidator);
+    }
 }
--- a/jdk/src/java.base/share/classes/java/io/RandomAccessFile.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/io/RandomAccessFile.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2016, 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
@@ -418,10 +418,11 @@
      * read. This method blocks until the requested number of bytes are
      * read, the end of the stream is detected, or an exception is thrown.
      *
-     * @param      b   the buffer into which the data is read.
-     * @exception  EOFException  if this file reaches the end before reading
-     *               all the bytes.
-     * @exception  IOException   if an I/O error occurs.
+     * @param   b   the buffer into which the data is read.
+     * @throws  NullPointerException if {@code b} is {@code null}.
+     * @throws  EOFException  if this file reaches the end before reading
+     *              all the bytes.
+     * @throws  IOException   if an I/O error occurs.
      */
     public final void readFully(byte b[]) throws IOException {
         readFully(b, 0, b.length);
@@ -434,12 +435,16 @@
      * read. This method blocks until the requested number of bytes are
      * read, the end of the stream is detected, or an exception is thrown.
      *
-     * @param      b     the buffer into which the data is read.
-     * @param      off   the start offset of the data.
-     * @param      len   the number of bytes to read.
-     * @exception  EOFException  if this file reaches the end before reading
-     *               all the bytes.
-     * @exception  IOException   if an I/O error occurs.
+     * @param   b     the buffer into which the data is read.
+     * @param   off   the start offset into the data array {@code b}.
+     * @param   len   the number of bytes to read.
+     * @throws  NullPointerException if {@code b} is {@code null}.
+     * @throws  IndexOutOfBoundsException if {@code off} is negative,
+     *                {@code len} is negative, or {@code len} is greater than
+     *                {@code b.length - off}.
+     * @throws  EOFException  if this file reaches the end before reading
+     *                all the bytes.
+     * @throws  IOException   if an I/O error occurs.
      */
     public final void readFully(byte b[], int off, int len) throws IOException {
         int n = 0;
--- a/jdk/src/java.base/share/classes/java/lang/Boolean.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/Boolean.java	Thu Apr 28 23:08:16 2016 -0700
@@ -79,13 +79,16 @@
      * Allocates a {@code Boolean} object representing the
      * {@code value} argument.
      *
-     * <p><b>Note: It is rarely appropriate to use this constructor.
-     * Unless a <i>new</i> instance is required, the static factory
-     * {@link #valueOf(boolean)} is generally a better choice. It is
-     * likely to yield significantly better space and time performance.</b>
+     * @param   value   the value of the {@code Boolean}.
      *
-     * @param   value   the value of the {@code Boolean}.
+     * @deprecated
+     * It is rarely appropriate to use this constructor. The static factory
+     * {@link #valueOf(boolean)} is generally a better choice, as it is
+     * likely to yield significantly better space and time performance.
+     * Also consider using the final fields {@link #TRUE} and {@link #FALSE}
+     * if possible.
      */
+    @Deprecated(since="9")
     public Boolean(boolean value) {
         this.value = value;
     }
@@ -94,15 +97,18 @@
      * Allocates a {@code Boolean} object representing the value
      * {@code true} if the string argument is not {@code null}
      * and is equal, ignoring case, to the string {@code "true"}.
-     * Otherwise, allocate a {@code Boolean} object representing the
-     * value {@code false}. Examples:<p>
-     * {@code new Boolean("True")} produces a {@code Boolean} object
-     * that represents {@code true}.<br>
-     * {@code new Boolean("yes")} produces a {@code Boolean} object
-     * that represents {@code false}.
+     * Otherwise, allocates a {@code Boolean} object representing the
+     * value {@code false}.
      *
      * @param   s   the string to be converted to a {@code Boolean}.
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor.
+     * Use {@link #parseBoolean(String)} to convert a string to a
+     * {@code boolean} primitive, or use {@link #valueOf(String)}
+     * to convert a string to a {@code Boolean} object.
      */
+    @Deprecated(since="9")
     public Boolean(String s) {
         this(parseBoolean(s));
     }
--- a/jdk/src/java.base/share/classes/java/lang/Byte.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/Byte.java	Thu Apr 28 23:08:16 2016 -0700
@@ -297,7 +297,13 @@
      *
      * @param value     the value to be represented by the
      *                  {@code Byte}.
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor. The static factory
+     * {@link #valueOf(byte)} is generally a better choice, as it is
+     * likely to yield significantly better space and time performance.
      */
+    @Deprecated(since="9")
     public Byte(byte value) {
         this.value = value;
     }
@@ -311,10 +317,16 @@
      *
      * @param s         the {@code String} to be converted to a
      *                  {@code Byte}
-     * @throws           NumberFormatException If the {@code String}
+     * @throws          NumberFormatException if the {@code String}
      *                  does not contain a parsable {@code byte}.
-     * @see        java.lang.Byte#parseByte(java.lang.String, int)
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor.
+     * Use {@link #parseByte(String)} to convert a string to a
+     * {@code byte} primitive, or use {@link #valueOf(String)}
+     * to convert a string to a {@code Byte} object.
      */
+    @Deprecated(since="9")
     public Byte(String s) throws NumberFormatException {
         this.value = parseByte(s, 10);
     }
--- a/jdk/src/java.base/share/classes/java/lang/Character.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/Character.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1256,14 +1256,14 @@
             new UnicodeBlock("SPECIALS");
 
         /**
-         * @deprecated As of J2SE 5, use {@link #HIGH_SURROGATES},
-         *             {@link #HIGH_PRIVATE_USE_SURROGATES}, and
-         *             {@link #LOW_SURROGATES}. These new constants match
-         *             the block definitions of the Unicode Standard.
-         *             The {@link #of(char)} and {@link #of(int)} methods
-         *             return the new constants, not SURROGATES_AREA.
-         */
-        @Deprecated
+         * @deprecated
+         * Instead of {@code SURROGATES_AREA}, use {@link #HIGH_SURROGATES},
+         * {@link #HIGH_PRIVATE_USE_SURROGATES}, and {@link #LOW_SURROGATES}.
+         * These constants match the block definitions of the Unicode Standard.
+         * The {@link #of(char)} and {@link #of(int)} methods return the
+         * standard constants.
+         */
+        @Deprecated(since="1.5")
         public static final UnicodeBlock SURROGATES_AREA =
             new UnicodeBlock("SURROGATES_AREA");
 
@@ -7451,7 +7451,13 @@
      *
      * @param  value   the value to be represented by the
      *                  {@code Character} object.
-     */
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor. The static factory
+     * {@link #valueOf(char)} is generally a better choice, as it is
+     * likely to yield significantly better space and time performance.
+     */
+    @Deprecated(since="9")
     public Character(char value) {
         this.value = value;
     }
@@ -8799,7 +8805,7 @@
      * @since   1.0.2
      * @deprecated Replaced by isJavaIdentifierStart(char).
      */
-    @Deprecated
+    @Deprecated(since="1.1")
     public static boolean isJavaLetter(char ch) {
         return isJavaIdentifierStart(ch);
     }
@@ -8835,7 +8841,7 @@
      * @since   1.0.2
      * @deprecated Replaced by isJavaIdentifierPart(char).
      */
-    @Deprecated
+    @Deprecated(since="1.1")
     public static boolean isJavaLetterOrDigit(char ch) {
         return isJavaIdentifierPart(ch);
     }
@@ -9580,7 +9586,7 @@
      * @see        Character#isWhitespace(char)
      * @deprecated Replaced by isWhitespace(char).
      */
-    @Deprecated
+    @Deprecated(since="1.1")
     public static boolean isSpace(char ch) {
         return (ch <= 0x0020) &&
             (((((1L << 0x0009) |
--- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java	Thu Apr 28 23:08:16 2016 -0700
@@ -727,7 +727,7 @@
      * @deprecated  Replaced by {@link #defineClass(String, byte[], int, int)
      * defineClass(String, byte[], int, int)}
      */
-    @Deprecated
+    @Deprecated(since="1.1")
     protected final Class<?> defineClass(byte[] b, int off, int len)
         throws ClassFormatError
     {
@@ -817,6 +817,9 @@
         if (!checkName(name))
             throw new NoClassDefFoundError("IllegalName: " + name);
 
+        // Note:  Checking logic in java.lang.invoke.MemberName.checkForTypeAlias
+        // relies on the fact that spoofing is impossible if a class has a name
+        // of the form "java.*"
         if ((name != null) && name.startsWith("java.")
                 && this != getBuiltinPlatformClassLoader()) {
             throw new SecurityException
@@ -2012,7 +2015,7 @@
      *
      * @since  1.2
      */
-    @Deprecated
+    @Deprecated(since="9")
     protected Package getPackage(String name) {
         Package pkg = getDefinedPackage(name);
         if (pkg == null) {
--- a/jdk/src/java.base/share/classes/java/lang/Double.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/Double.java	Thu Apr 28 23:08:16 2016 -0700
@@ -589,7 +589,13 @@
      * represents the primitive {@code double} argument.
      *
      * @param   value   the value to be represented by the {@code Double}.
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor. The static factory
+     * {@link #valueOf(double)} is generally a better choice, as it is
+     * likely to yield significantly better space and time performance.
      */
+    @Deprecated(since="9")
     public Double(double value) {
         this.value = value;
     }
@@ -601,10 +607,16 @@
      * {@code double} value as if by the {@code valueOf} method.
      *
      * @param  s  a string to be converted to a {@code Double}.
-     * @throws    NumberFormatException  if the string does not contain a
+     * @throws    NumberFormatException if the string does not contain a
      *            parsable number.
-     * @see       java.lang.Double#valueOf(java.lang.String)
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor.
+     * Use {@link #parseDouble(String)} to convert a string to a
+     * {@code double} primitive, or use {@link #valueOf(String)}
+     * to convert a string to a {@code Double} object.
      */
+    @Deprecated(since="9")
     public Double(String s) throws NumberFormatException {
         value = parseDouble(s);
     }
--- a/jdk/src/java.base/share/classes/java/lang/Float.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/Float.java	Thu Apr 28 23:08:16 2016 -0700
@@ -502,7 +502,13 @@
      * represents the primitive {@code float} argument.
      *
      * @param   value   the value to be represented by the {@code Float}.
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor. The static factory
+     * {@link #valueOf(float)} is generally a better choice, as it is
+     * likely to yield significantly better space and time performance.
      */
+    @Deprecated(since="9")
     public Float(float value) {
         this.value = value;
     }
@@ -512,7 +518,13 @@
      * represents the argument converted to type {@code float}.
      *
      * @param   value   the value to be represented by the {@code Float}.
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor. Instead, use the
+     * static factory method {@link #valueOf(float)} method as follows:
+     * {@code Float.valueOf((float)value)}.
      */
+    @Deprecated(since="9")
     public Float(double value) {
         this.value = (float)value;
     }
@@ -523,11 +535,17 @@
      * represented by the string. The string is converted to a
      * {@code float} value as if by the {@code valueOf} method.
      *
-     * @param      s   a string to be converted to a {@code Float}.
-     * @throws  NumberFormatException  if the string does not contain a
-     *               parsable number.
-     * @see        java.lang.Float#valueOf(java.lang.String)
+     * @param   s   a string to be converted to a {@code Float}.
+     * @throws      NumberFormatException if the string does not contain a
+     *              parsable number.
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor.
+     * Use {@link #parseFloat(String)} to convert a string to a
+     * {@code float} primitive, or use {@link #valueOf(String)}
+     * to convert a string to a {@code Float} object.
      */
+    @Deprecated(since="9")
     public Float(String s) throws NumberFormatException {
         value = parseFloat(s);
     }
--- a/jdk/src/java.base/share/classes/java/lang/Integer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/Integer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1106,7 +1106,13 @@
      *
      * @param   value   the value to be represented by the
      *                  {@code Integer} object.
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor. The static factory
+     * {@link #valueOf(int)} is generally a better choice, as it is
+     * likely to yield significantly better space and time performance.
      */
+    @Deprecated(since="9")
     public Integer(int value) {
         this.value = value;
     }
@@ -1118,12 +1124,17 @@
      * {@code int} value in exactly the manner used by the
      * {@code parseInt} method for radix 10.
      *
-     * @param      s   the {@code String} to be converted to an
-     *                 {@code Integer}.
-     * @exception  NumberFormatException  if the {@code String} does not
-     *               contain a parsable integer.
-     * @see        java.lang.Integer#parseInt(java.lang.String, int)
+     * @param   s   the {@code String} to be converted to an {@code Integer}.
+     * @throws      NumberFormatException if the {@code String} does not
+     *              contain a parsable integer.
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor.
+     * Use {@link #parseInt(String)} to convert a string to a
+     * {@code int} primitive, or use {@link #valueOf(String)}
+     * to convert a string to an {@code Integer} object.
      */
+    @Deprecated(since="9")
     public Integer(String s) throws NumberFormatException {
         this.value = parseInt(s, 10);
     }
--- a/jdk/src/java.base/share/classes/java/lang/Long.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/Long.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1340,7 +1340,13 @@
      *
      * @param   value   the value to be represented by the
      *          {@code Long} object.
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor. The static factory
+     * {@link #valueOf(long)} is generally a better choice, as it is
+     * likely to yield significantly better space and time performance.
      */
+    @Deprecated(since="9")
     public Long(long value) {
         this.value = value;
     }
@@ -1356,8 +1362,14 @@
      *             {@code Long}.
      * @throws     NumberFormatException  if the {@code String} does not
      *             contain a parsable {@code long}.
-     * @see        java.lang.Long#parseLong(java.lang.String, int)
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor.
+     * Use {@link #parseLong(String)} to convert a string to a
+     * {@code long} primitive, or use {@link #valueOf(String)}
+     * to convert a string to a {@code Long} object.
      */
+    @Deprecated(since="9")
     public Long(String s) throws NumberFormatException {
         this.value = parseLong(s, 10);
     }
--- a/jdk/src/java.base/share/classes/java/lang/Package.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/Package.java	Thu Apr 28 23:08:16 2016 -0700
@@ -333,7 +333,7 @@
      * @see ClassLoader#getDefinedPackage
      */
     @CallerSensitive
-    @Deprecated
+    @Deprecated(since="9")
     @SuppressWarnings("deprecation")
     public static Package getPackage(String name) {
         ClassLoader l = ClassLoader.getClassLoader(Reflection.getCallerClass());
--- a/jdk/src/java.base/share/classes/java/lang/ProcessBuilder.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/ProcessBuilder.java	Thu Apr 28 23:08:16 2016 -0700
@@ -30,13 +30,12 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.nio.channels.Pipe;
 import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
+import sun.security.action.GetPropertyAction;
+
 /**
  * This class is used to create operating system processes.
  *
@@ -468,11 +467,9 @@
      * @since 1.7
      */
     public abstract static class Redirect {
-        private static final File NULL_FILE = AccessController.doPrivileged(
-                (PrivilegedAction<File>) () -> {
-                    return new File((System.getProperty("os.name")
-                            .startsWith("Windows") ? "NUL" : "/dev/null"));
-                }
+        private static final File NULL_FILE = new File(
+                (GetPropertyAction.getProperty("os.name")
+                        .startsWith("Windows") ? "NUL" : "/dev/null")
         );
 
         /**
--- a/jdk/src/java.base/share/classes/java/lang/Runtime.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/Runtime.java	Thu Apr 28 23:08:16 2016 -0700
@@ -289,6 +289,7 @@
      *      finalizers being called on live objects while other threads are
      *      concurrently manipulating those objects, resulting in erratic
      *      behavior or deadlock.
+     *      This method is subject to removal in a future version of Java SE.
      *
      * @throws  SecurityException
      *        if a security manager exists and its {@code checkExit}
@@ -299,7 +300,7 @@
      * @see     java.lang.SecurityManager#checkExit(int)
      * @since   1.1
      */
-    @Deprecated
+    @Deprecated(since="1.2", forRemoval=true)
     public static void runFinalizersOnExit(boolean value) {
         SecurityManager security = System.getSecurityManager();
         if (security != null) {
@@ -717,41 +718,27 @@
     }
 
     /**
-     * Enables/Disables tracing of instructions.
-     * If the {@code boolean} argument is {@code true}, this
-     * method suggests that the Java virtual machine emit debugging
-     * information for each instruction in the virtual machine as it
-     * is executed. The format of this information, and the file or other
-     * output stream to which it is emitted, depends on the host environment.
-     * The virtual machine may ignore this request if it does not support
-     * this feature. The destination of the trace output is system
-     * dependent.
-     * <p>
-     * If the {@code boolean} argument is {@code false}, this
-     * method causes the virtual machine to stop performing the
-     * detailed instruction trace it is performing.
+     * Not implemented, does nothing.
      *
-     * @param   on   {@code true} to enable instruction tracing;
-     *               {@code false} to disable this feature.
+     * @deprecated
+     * This method was intended to control instruction tracing.
+     * It has been superseded by JVM-specific tracing mechanisms.
+     *
+     * @param on ignored
      */
+    @Deprecated(since="9", forRemoval=true)
     public void traceInstructions(boolean on) { }
 
     /**
-     * Enables/Disables tracing of method calls.
-     * If the {@code boolean} argument is {@code true}, this
-     * method suggests that the Java virtual machine emit debugging
-     * information for each method in the virtual machine as it is
-     * called. The format of this information, and the file or other output
-     * stream to which it is emitted, depends on the host environment. The
-     * virtual machine may ignore this request if it does not support
-     * this feature.
-     * <p>
-     * Calling this method with argument false suggests that the
-     * virtual machine cease emitting per-call debugging information.
+     * Not implemented, does nothing.
      *
-     * @param   on   {@code true} to enable instruction tracing;
-     *               {@code false} to disable this feature.
+     * @deprecated
+     * This method was intended to control method call tracing.
+     * It has been superseded by JVM-specific tracing mechanisms.
+     *
+     * @param on ignored
      */
+    @Deprecated(since="9", forRemoval=true)
     public void traceMethodCalls(boolean on) { }
 
     /**
@@ -894,8 +881,9 @@
      * stream in the local encoding into a character stream in Unicode is via
      * the {@code InputStreamReader} and {@code BufferedReader}
      * classes.
+     * This method is subject to removal in a future version of Java SE.
      */
-    @Deprecated
+    @Deprecated(since="1.1", forRemoval=true)
     public InputStream getLocalizedInputStream(InputStream in) {
         return in;
     }
@@ -915,6 +903,7 @@
      * Unicode character stream into a byte stream in the local encoding is via
      * the {@code OutputStreamWriter}, {@code BufferedWriter}, and
      * {@code PrintWriter} classes.
+     * This method is subject to removal in a future version of Java SE.
      *
      * @param      out OutputStream to localize
      * @return     a localized output stream
@@ -923,7 +912,7 @@
      * @see        java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream)
      * @see        java.io.PrintWriter#PrintWriter(java.io.OutputStream)
      */
-    @Deprecated
+    @Deprecated(since="1.1", forRemoval=true)
     public OutputStream getLocalizedOutputStream(OutputStream out) {
         return out;
     }
--- a/jdk/src/java.base/share/classes/java/lang/SecurityManager.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/SecurityManager.java	Thu Apr 28 23:08:16 2016 -0700
@@ -229,7 +229,7 @@
      *  It is recommended that the <code>checkPermission</code>
      *  call be used instead.
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     protected boolean inCheck;
 
     /*
@@ -262,7 +262,7 @@
      *  It is recommended that the <code>checkPermission</code>
      *  call be used instead.
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     public boolean getInCheck() {
         return inCheck;
     }
@@ -345,7 +345,7 @@
      * @see  java.lang.ClassLoader#getSystemClassLoader() getSystemClassLoader
      * @see  #checkPermission(java.security.Permission) checkPermission
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     protected ClassLoader currentClassLoader() {
         ClassLoader cl = currentClassLoader0();
         if ((cl != null) && hasAllPermission())
@@ -391,7 +391,7 @@
      * @see  java.lang.ClassLoader#getSystemClassLoader() getSystemClassLoader
      * @see  #checkPermission(java.security.Permission) checkPermission
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     protected Class<?> currentLoadedClass() {
         Class<?> c = currentLoadedClass0();
         if ((c != null) && hasAllPermission())
@@ -411,7 +411,7 @@
      *  call be used instead.
      *
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     protected native int classDepth(String name);
 
     /**
@@ -449,7 +449,7 @@
      * @see   java.lang.ClassLoader#getSystemClassLoader() getSystemClassLoader
      * @see   #checkPermission(java.security.Permission) checkPermission
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     protected int classLoaderDepth() {
         int depth = classLoaderDepth0();
         if (depth != -1) {
@@ -474,7 +474,7 @@
      *  It is recommended that the <code>checkPermission</code>
      *  call be used instead.
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     protected boolean inClass(String name) {
         return classDepth(name) >= 0;
     }
@@ -491,7 +491,7 @@
      *  call be used instead.
      * @see        #currentClassLoader() currentClassLoader
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     protected boolean inClassLoader() {
         return currentClassLoader() != null;
     }
@@ -1217,7 +1217,7 @@
      * @deprecated Use #checkPermission(java.security.Permission) instead
      * @see        #checkPermission(java.security.Permission) checkPermission
      */
-    @Deprecated
+    @Deprecated(since="1.4")
     public void checkMulticast(InetAddress maddr, byte ttl) {
         String host = maddr.getHostAddress();
         if (!host.startsWith("[") && host.indexOf(':') != -1) {
@@ -1297,9 +1297,10 @@
      *             was trusted to bring up a top-level window. The method has been
      *             obsoleted and code should instead use {@link #checkPermission}
      *             to check {@code AWTPermission("showWindowWithoutWarningBanner")}.
+     *             This method is subject to removal in a future version of Java SE.
      * @see        #checkPermission(java.security.Permission) checkPermission
      */
-    @Deprecated
+    @Deprecated(since="1.8", forRemoval=true)
     public boolean checkTopLevelWindow(Object window) {
         if (window == null) {
             throw new NullPointerException("window can't be null");
@@ -1340,9 +1341,10 @@
      *             thread could access the system clipboard. The method has been
      *             obsoleted and code should instead use {@link #checkPermission}
      *             to check {@code AWTPermission("accessClipboard")}.
+     *             This method is subject to removal in a future version of Java SE.
      * @see        #checkPermission(java.security.Permission) checkPermission
      */
-    @Deprecated
+    @Deprecated(since="1.8", forRemoval=true)
     public void checkSystemClipboardAccess() {
         checkPermission(SecurityConstants.ALL_PERMISSION);
     }
@@ -1358,9 +1360,10 @@
      *             thread could access the AWT event queue. The method has been
      *             obsoleted and code should instead use {@link #checkPermission}
      *             to check {@code AWTPermission("accessEventQueue")}.
+     *             This method is subject to removal in a future version of Java SE.
      * @see        #checkPermission(java.security.Permission) checkPermission
      */
-    @Deprecated
+    @Deprecated(since="1.8", forRemoval=true)
     public void checkAwtEventQueueAccess() {
         checkPermission(SecurityConstants.ALL_PERMISSION);
     }
@@ -1626,12 +1629,13 @@
      *             Users of this method should instead invoke {@link #checkPermission}
      *             directly.  This method will be changed in a future release
      *             to check the permission {@code java.security.AllPermission}.
+     *             This method is subject to removal in a future version of Java SE.
      *
      * @see java.lang.reflect.Member
      * @since 1.1
      * @see        #checkPermission(java.security.Permission) checkPermission
      */
-    @Deprecated
+    @Deprecated(since="1.8", forRemoval=true)
     @CallerSensitive
     public void checkMemberAccess(Class<?> clazz, int which) {
         if (clazz == null) {
--- a/jdk/src/java.base/share/classes/java/lang/Short.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/Short.java	Thu Apr 28 23:08:16 2016 -0700
@@ -302,7 +302,13 @@
      *
      * @param value     the value to be represented by the
      *                  {@code Short}.
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor. The static factory
+     * {@link #valueOf(short)} is generally a better choice, as it is
+     * likely to yield significantly better space and time performance.
      */
+    @Deprecated(since="9")
     public Short(short value) {
         this.value = value;
     }
@@ -318,8 +324,14 @@
      *          {@code Short}
      * @throws  NumberFormatException If the {@code String}
      *          does not contain a parsable {@code short}.
-     * @see     java.lang.Short#parseShort(java.lang.String, int)
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor.
+     * Use {@link #parseShort(String)} to convert a string to a
+     * {@code short} primitive, or use {@link #valueOf(String)}
+     * to convert a string to a {@code Short} object.
      */
+    @Deprecated(since="9")
     public Short(String s) throws NumberFormatException {
         this.value = parseShort(s, 10);
     }
--- a/jdk/src/java.base/share/classes/java/lang/StackFrameInfo.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/StackFrameInfo.java	Thu Apr 28 23:08:16 2016 -0700
@@ -37,24 +37,14 @@
     private final static JavaLangInvokeAccess jlInvokeAccess =
         SharedSecrets.getJavaLangInvokeAccess();
 
-    // -XX:+MemberNameInStackFrame will initialize MemberName and all other fields;
-    // otherwise, VM will set the hidden fields (injected by the VM).
-    // -XX:+MemberNameInStackFrame is temporary to enable performance measurement
-    //
-    // Footprint improvement: MemberName::clazz and MemberName::name
-    // can replace StackFrameInfo::declaringClass and StackFrameInfo::methodName
-    // Currently VM sets StackFrameInfo::methodName instead of expanding MemberName::name
+    // Footprint improvement: MemberName::clazz can replace
+    // StackFrameInfo::declaringClass.
 
     final StackWalker walker;
     final Class<?> declaringClass;
     final Object memberName;
-    final int bci;
-
-    // methodName, fileName, and lineNumber will be lazily set by the VM
-    // when first requested.
-    private String methodName;
-    private String fileName = null;     // default for unavailable filename
-    private int    lineNumber = -1;     // default for unavailable lineNumber
+    final short bci;
+    private volatile StackTraceElement ste;
 
     /*
      * Create StackFrameInfo for StackFrameTraverser and LiveStackFrameTraverser
@@ -78,77 +68,53 @@
         return declaringClass;
     }
 
-    // Call the VM to set methodName, lineNumber, and fileName
-    private synchronized void ensureMethodInfoInitialized() {
-        if (methodName == null) {
-            setMethodInfo();
-        }
-    }
-
     @Override
     public String getMethodName() {
-        ensureMethodInfoInitialized();
-        return methodName;
+        return jlInvokeAccess.getName(memberName);
     }
 
     @Override
-    public Optional<String> getFileName() {
-        ensureMethodInfoInitialized();
-        return fileName != null ? Optional.of(fileName) : Optional.empty();
+    public final Optional<String> getFileName() {
+        StackTraceElement ste = toStackTraceElement();
+        return ste.getFileName() != null ? Optional.of(ste.getFileName()) : Optional.empty();
     }
 
     @Override
-    public OptionalInt getLineNumber() {
-        ensureMethodInfoInitialized();
-        return lineNumber > 0 ? OptionalInt.of(lineNumber) : OptionalInt.empty();
+    public final OptionalInt getLineNumber() {
+        StackTraceElement ste = toStackTraceElement();
+        return ste.getLineNumber() > 0 ? OptionalInt.of(ste.getLineNumber()) : OptionalInt.empty();
     }
 
     @Override
-    public boolean isNativeMethod() {
-        ensureMethodInfoInitialized();
-        return lineNumber == -2;
+    public final boolean isNativeMethod() {
+        StackTraceElement ste = toStackTraceElement();
+        return ste.isNativeMethod();
     }
 
     @Override
     public String toString() {
-        ensureMethodInfoInitialized();
-        // similar format as StackTraceElement::toString
-        if (isNativeMethod()) {
-            return getClassName() + "." + getMethodName() + "(Native Method)";
-        } else {
-            // avoid allocating Optional objects
-            return getClassName() + "." + getMethodName() +
-                "(" + (fileName != null ? fileName : "Unknown Source") +
-                      (lineNumber > 0 ? ":" + lineNumber : " bci:" + bci) + ")";
-        }
+        StackTraceElement ste = toStackTraceElement();
+        return ste.toString();
     }
 
     /**
-     * Lazily initialize method name, file name, line number
+     * Fill in the fields of the given StackTraceElement
      */
-    private native void setMethodInfo();
-
-    /**
-     * Fill in source file name and line number of the given StackFrame array.
-     */
-    static native void fillInStackFrames(int startIndex,
-                                         Object[] stackframes,
-                                         int fromIndex, int toIndex);
+    private native void toStackTraceElement0(StackTraceElement ste);
 
     @Override
     public StackTraceElement toStackTraceElement() {
-        ensureMethodInfoInitialized();
-
-        Module module = declaringClass.getModule();
-        String moduleName = module.isNamed() ? module.getName() : null;
-        String moduleVersion = null;
-        if (module.isNamed() && module.getDescriptor().version().isPresent()) {
-            moduleVersion = module.getDescriptor().version().get().toString();
+        StackTraceElement s = ste;
+        if (s == null) {
+            synchronized (this) {
+                s = ste;
+                if (s == null) {
+                    s = new StackTraceElement();
+                    toStackTraceElement0(s);
+                    ste = s;
+                }
+            }
         }
-        return new StackTraceElement(moduleName, moduleVersion,
-                                     getClassName(), getMethodName(),
-                                     fileName,
-                                     lineNumber);
+        return s;
     }
-
 }
--- a/jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java	Thu Apr 28 23:08:16 2016 -0700
@@ -24,29 +24,22 @@
  */
 package java.lang;
 
-import jdk.internal.misc.VM;
 import jdk.internal.reflect.MethodAccessor;
-
-import java.io.PrintStream;
 import java.lang.StackWalker.Option;
 import java.lang.StackWalker.StackFrame;
 
 import java.lang.annotation.Native;
 import java.lang.reflect.Method;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Arrays;
-import java.util.EnumSet;
 import java.util.HashSet;
 import java.util.NoSuchElementException;
 import java.util.Objects;
-import java.util.Optional;
 import java.util.Set;
 import java.util.Spliterator;
 import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
+import sun.security.action.GetPropertyAction;
 
 import static java.lang.StackStreamFactory.WalkerState.*;
 
@@ -61,8 +54,7 @@
  * to avoid overhead of Stream/Lambda
  * 1. Support traversing Stream<StackFrame>
  * 2. StackWalker::getCallerClass
- * 3. Throwable::init and Throwable::getStackTrace
- * 4. AccessControlContext getting ProtectionDomain
+ * 3. AccessControlContext getting ProtectionDomain
  */
 final class StackStreamFactory {
     private StackStreamFactory() {}
@@ -79,25 +71,22 @@
     // These flags must match the values maintained in the VM
     @Native private static final int DEFAULT_MODE              = 0x0;
     @Native private static final int FILL_CLASS_REFS_ONLY      = 0x2;
-    @Native private static final int FILTER_FILL_IN_STACKTRACE = 0x10;
     @Native private static final int SHOW_HIDDEN_FRAMES        = 0x20;  // LambdaForms are hidden by the VM
     @Native private static final int FILL_LIVE_STACK_FRAMES    = 0x100;
-
     /*
      * For Throwable to use StackWalker, set useNewThrowable to true.
      * Performance work and extensive testing is needed to replace the
      * VM built-in backtrace filled in Throwable with the StackWalker.
      */
-    final static boolean useNewThrowable = getProperty("stackwalk.newThrowable", false);
     final static boolean isDebug = getProperty("stackwalk.debug", false);
 
     static <T> StackFrameTraverser<T>
         makeStackTraverser(StackWalker walker, Function<? super Stream<StackFrame>, ? extends T> function)
     {
         if (walker.hasLocalsOperandsOption())
-            return new LiveStackInfoTraverser<T>(walker, function);
+            return new LiveStackInfoTraverser<>(walker, function);
         else
-            return new StackFrameTraverser<T>(walker, function);
+            return new StackFrameTraverser<>(walker, function);
     }
 
     /**
@@ -107,40 +96,31 @@
         return new CallerClassFinder(walker);
     }
 
-    static boolean useStackTrace(Throwable t) {
-        if (t instanceof VirtualMachineError)
-            return false;
-
-        return VM.isBooted() && StackStreamFactory.useNewThrowable;
-    }
-
-    /*
-     * This should only be used by Throwable::<init>.
-     */
-    static StackTrace makeStackTrace(Throwable ex) {
-        return StackTrace.dump(ex);
-    }
-
-    /*
-     * This creates StackTrace for Thread::dumpThread to use.
-     */
-    static StackTrace makeStackTrace() {
-        return StackTrace.dump();
-    }
-
     enum WalkerState {
         NEW,     // the stream is new and stack walking has not started
         OPEN,    // the stream is open when it is being traversed.
         CLOSED;  // the stream is closed when the stack walking is done
     }
 
-    static abstract class AbstractStackWalker<T> {
+    /**
+     * Subclass of AbstractStackWalker implements a specific stack walking logic.
+     * It needs to set up the frame buffer and stack walking mode.
+     *
+     * It initiates the VM stack walking via the callStackWalk method that serves
+     * as the anchored frame and VM will call up to AbstractStackWalker::doStackWalk.
+     *
+     * @param <R> the type of the result returned from stack walking
+     * @param <T> the type of the data gathered for each frame.
+     *            For example, StackFrameInfo for StackWalker::walk or
+     *            Class<?> for StackWalker::getCallerClass
+     */
+    static abstract class AbstractStackWalker<R, T> {
         protected final StackWalker walker;
         protected final Thread thread;
         protected final int maxDepth;
         protected final long mode;
-        protected int depth;                 // traversed stack depth
-        protected FrameBuffer frameBuffer;   // buffer for VM to fill in
+        protected int depth;    // traversed stack depth
+        protected FrameBuffer<? extends T> frameBuffer;
         protected long anchor;
 
         // buffers to fill in stack frame information
@@ -158,16 +138,13 @@
         private int toStackWalkMode(StackWalker walker, int mode) {
             int newMode = mode;
             if (walker.hasOption(Option.SHOW_HIDDEN_FRAMES) &&
-                    !fillCallerClassOnly(newMode) /* don't show hidden frames for getCallerClass */)
+                    (mode & FILL_CLASS_REFS_ONLY) != FILL_CLASS_REFS_ONLY)
                 newMode |= SHOW_HIDDEN_FRAMES;
             if (walker.hasLocalsOperandsOption())
                 newMode |= FILL_LIVE_STACK_FRAMES;
             return newMode;
         }
 
-        private boolean fillCallerClassOnly(int mode) {
-            return (mode|FILL_CLASS_REFS_ONLY) != FILL_CLASS_REFS_ONLY;
-        }
         /**
          * A callback method to consume the stack frames.  This method is invoked
          * once stack walking begins (i.e. it is only invoked when walkFrames is called).
@@ -180,7 +157,7 @@
          *
          * @return the number of consumed frames
          */
-         protected abstract T consumeFrames();
+         protected abstract R consumeFrames();
 
         /**
          * Initialize FrameBuffer.  Subclass should implement this method to
@@ -253,7 +230,7 @@
          * Walks stack frames until {@link #consumeFrames} is done consuming
          * the frames it is interested in.
          */
-        final T walk() {
+        final R walk() {
             checkState(NEW);
             try {
                 // VM will need to stablize the stack before walking.  It will invoke
@@ -319,7 +296,7 @@
             }
 
             this.anchor = anchor;  // set anchor for this bulk stack frame traversal
-            frameBuffer.setBatch(bufStartIndex, bufEndIndex);
+            frameBuffer.setBatch(depth, bufStartIndex, bufEndIndex);
 
             // traverse all frames and perform the action on the stack frames, if specified
             return consumeFrames();
@@ -382,15 +359,14 @@
          * If all fetched stack frames are traversed, AbstractStackWalker::fetchStackFrames will
          * fetch the next batch of stack frames to continue.
          */
-        private T beginStackWalk() {
+        private R beginStackWalk() {
             // initialize buffers for VM to fill the stack frame info
             initFrameBuffer();
 
             return callStackWalk(mode, 0,
                                  frameBuffer.curBatchFrameCount(),
                                  frameBuffer.startIndex(),
-                                 frameBuffer.classes,
-                                 frameBuffer.stackFrames);
+                                 frameBuffer.frames());
         }
 
         /*
@@ -405,8 +381,7 @@
 
             int endIndex = fetchStackFrames(mode, anchor, batchSize,
                                             startIndex,
-                                            frameBuffer.classes,
-                                            frameBuffer.stackFrames);
+                                            frameBuffer.frames());
             if (isDebug) {
                 System.out.format("  more stack walk requesting %d got %d to %d frames%n",
                                   batchSize, frameBuffer.startIndex(), endIndex);
@@ -415,27 +390,26 @@
             if (numFrames == 0) {
                 frameBuffer.freeze(); // done stack walking
             } else {
-                frameBuffer.setBatch(startIndex, endIndex);
+                frameBuffer.setBatch(depth, startIndex, endIndex);
             }
             return numFrames;
         }
 
         /**
          * Begins stack walking.  This method anchors this frame and invokes
-         * AbstractStackWalker::doStackWalk after fetching the firt batch of stack frames.
+         * AbstractStackWalker::doStackWalk after fetching the first batch of stack frames.
          *
          * @param mode        mode of stack walking
          * @param skipframes  number of frames to be skipped before filling the frame buffer.
          * @param batchSize   the batch size, max. number of elements to be filled in the frame buffers.
          * @param startIndex  start index of the frame buffers to be filled.
-         * @param classes     Classes buffer of the stack frames
-         * @param frames      StackFrame buffer, or null
+         * @param frames      Either a Class<?> array, if mode is {@link #FILL_CLASS_REFS_ONLY}
+         *                    or a {@link StackFrameInfo} (or derivative) array otherwise.
          * @return            Result of AbstractStackWalker::doStackWalk
          */
-        private native T callStackWalk(long mode, int skipframes,
+        private native R callStackWalk(long mode, int skipframes,
                                        int batchSize, int startIndex,
-                                       Class<?>[] classes,
-                                       StackFrame[] frames);
+                                       T[] frames);
 
         /**
          * Fetch the next batch of stack frames.
@@ -444,185 +418,14 @@
          * @param anchor
          * @param batchSize   the batch size, max. number of elements to be filled in the frame buffers.
          * @param startIndex  start index of the frame buffers to be filled.
-         * @param classes     Classes buffer of the stack frames
-         * @param frames      StackFrame buffer, or null
+         * @param frames      Either a Class<?> array, if mode is {@link #FILL_CLASS_REFS_ONLY}
+         *                    or a {@link StackFrameInfo} (or derivative) array otherwise.
          *
          * @return the end index to the frame buffers
          */
         private native int fetchStackFrames(long mode, long anchor,
                                             int batchSize, int startIndex,
-                                            Class<?>[] classes,
-                                            StackFrame[] frames);
-
-
-        /*
-         * Frame buffer
-         *
-         * Each specialized AbstractStackWalker subclass may subclass the FrameBuffer.
-         */
-        class FrameBuffer {
-            static final int START_POS = 2;     // 0th and 1st elements are reserved
-
-            // buffers for VM to fill stack frame info
-            int currentBatchSize;    // current batch size
-            Class<?>[] classes;      // caller class for fast path
-
-            StackFrame[] stackFrames;
-
-            int origin;         // index to the current traversed stack frame
-            int fence;          // index to the last frame in the current batch
-
-            FrameBuffer(int initialBatchSize) {
-                if (initialBatchSize < MIN_BATCH_SIZE) {
-                    throw new IllegalArgumentException(initialBatchSize + " < minimum batch size: " + MIN_BATCH_SIZE);
-                }
-                this.origin = START_POS;
-                this.fence = 0;
-                this.currentBatchSize = initialBatchSize;
-                this.classes = new Class<?>[currentBatchSize];
-            }
-
-            int curBatchFrameCount() {
-                return currentBatchSize-START_POS;
-            }
-
-            /*
-             * Tests if this frame buffer is empty.  All frames are fetched.
-             */
-            final boolean isEmpty() {
-                return origin >= fence || (origin == START_POS && fence == 0);
-            }
-
-            /*
-             * Freezes this frame buffer.  The stack stream source is done fetching.
-             */
-            final void freeze() {
-                origin = 0;
-                fence = 0;
-            }
-
-            /*
-             * Tests if this frame buffer is active.  It is inactive when
-             * it is done for traversal.  All stack frames have been traversed.
-             */
-            final boolean isActive() {
-                return origin > 0 && (fence == 0 || origin < fence || fence == currentBatchSize);
-            }
-
-            /**
-             * Gets the class at the current frame and move to the next frame.
-             */
-            final Class<?> next() {
-                if (isEmpty()) {
-                    throw new NoSuchElementException("origin=" + origin + " fence=" + fence);
-                }
-                Class<?> c = classes[origin++];
-                if (isDebug) {
-                    int index = origin-1;
-                    System.out.format("  next frame at %d: %s (origin %d fence %d)%n", index,
-                                      Objects.toString(c), index, fence);
-                }
-                return c;
-            }
-
-            /**
-             * Gets the class at the current frame.
-             */
-            final Class<?> get() {
-                if (isEmpty()) {
-                    throw new NoSuchElementException("origin=" + origin + " fence=" + fence);
-                }
-                return classes[origin];
-            }
-
-            /*
-             * Returns the index of the current frame.
-             */
-            final int getIndex() {
-                return origin;
-            }
-
-            /*
-             * Set the start and end index of a new batch of stack frames that have
-             * been filled in this frame buffer.
-             */
-            final void setBatch(int startIndex, int endIndex) {
-                if (startIndex <= 0 || endIndex <= 0)
-                    throw new IllegalArgumentException("startIndex=" + startIndex + " endIndex=" + endIndex);
-
-                this.origin = startIndex;
-                this.fence = endIndex;
-                if (depth == 0 && fence > 0) {
-                    // filter the frames due to the stack stream implementation
-                    for (int i = START_POS; i < fence; i++) {
-                        Class<?> c = classes[i];
-                        if (isDebug) System.err.format("  frame %d: %s%n", i, c);
-                        if (filterStackWalkImpl(c)) {
-                            origin++;
-                        } else {
-                            break;
-                        }
-                    }
-                }
-            }
-
-            /*
-             * Checks if the origin is the expected start index.
-             */
-            final void check(int skipFrames) {
-                int index = skipFrames + START_POS;
-                if (origin != index) {
-                    // stack walk must continue with the previous frame depth
-                    throw new IllegalStateException("origin " + origin + " != " + index);
-                }
-            }
-
-            // ------ subclass may override the following methods -------
-            /**
-             * Resizes the buffers for VM to fill in the next batch of stack frames.
-             * The next batch will start at the given startIndex with the maximum number
-             * of elements.
-             *
-             * <p> Subclass may override this method to manage the allocated buffers.
-             *
-             * @param startIndex the start index for the first frame of the next batch to fill in.
-             * @param elements the number of elements for the next batch to fill in.
-             *
-             */
-            void resize(int startIndex, int elements) {
-                if (!isActive())
-                    throw new IllegalStateException("inactive frame buffer can't be resized");
-
-                int size = startIndex+elements;
-                if (classes.length < size) {
-                    // copy the elements in classes array to the newly allocated one.
-                    // classes[0] is a Thread object
-                    Class<?>[] prev = classes;
-                    classes = new Class<?>[size];
-                    System.arraycopy(prev, 0, classes, 0, START_POS);
-                }
-                currentBatchSize = size;
-            }
-
-            /*
-             * Returns the start index for this frame buffer is refilled.
-             *
-             * This implementation reuses the allocated buffer for the next batch
-             * of stack frames.  For subclass to retain the fetched stack frames,
-             * it should override this method to return the index at which the frame
-             * should be filled in for the next batch.
-             */
-            int startIndex() {
-                return START_POS;
-            }
-
-            /**
-             * Returns next StackFrame object in the current batch of stack frames
-             */
-            StackFrame nextStackFrame() {
-                throw new InternalError("should not reach here");
-            }
-        }
+                                            T[] frames);
     }
 
     /*
@@ -630,46 +433,66 @@
      *
      * This class implements Spliterator::forEachRemaining and Spliterator::tryAdvance.
      */
-    static class StackFrameTraverser<T> extends AbstractStackWalker<T>
+    static class StackFrameTraverser<T> extends AbstractStackWalker<T, StackFrameInfo>
             implements Spliterator<StackFrame>
     {
         static {
             stackWalkImplClasses.add(StackFrameTraverser.class);
         }
         private static final int CHARACTERISTICS = Spliterator.ORDERED | Spliterator.IMMUTABLE;
-        class Buffer extends FrameBuffer {
-            Buffer(int initialBatchSize) {
+
+        final class StackFrameBuffer extends FrameBuffer<StackFrameInfo> {
+            private StackFrameInfo[] stackFrames;
+            StackFrameBuffer(int initialBatchSize) {
                 super(initialBatchSize);
 
-                this.stackFrames = new StackFrame[initialBatchSize];
+                this.stackFrames = new StackFrameInfo[initialBatchSize];
                 for (int i = START_POS; i < initialBatchSize; i++) {
                     stackFrames[i] = new StackFrameInfo(walker);
                 }
             }
 
             @Override
+            StackFrameInfo[] frames() {
+                return stackFrames;
+            }
+
+            @Override
             void resize(int startIndex, int elements) {
-                super.resize(startIndex, elements);
+                if (!isActive())
+                    throw new IllegalStateException("inactive frame buffer can't be resized");
+
+                assert startIndex == START_POS :
+                       "bad start index " + startIndex + " expected " + START_POS;
 
                 int size = startIndex+elements;
                 if (stackFrames.length < size) {
-                    stackFrames = new StackFrame[size];
+                    StackFrameInfo[] newFrames = new StackFrameInfo[size];
+                    // copy initial magic...
+                    System.arraycopy(stackFrames, 0, newFrames, 0, startIndex);
+                    stackFrames = newFrames;
                 }
-                for (int i = startIndex(); i < size; i++) {
+                for (int i = startIndex; i < size; i++) {
                     stackFrames[i] = new StackFrameInfo(walker);
                 }
+                currentBatchSize = size;
             }
 
             @Override
-            StackFrame nextStackFrame() {
+            StackFrameInfo nextStackFrame() {
                 if (isEmpty()) {
                     throw new NoSuchElementException("origin=" + origin + " fence=" + fence);
                 }
 
-                StackFrame frame = stackFrames[origin];
+                StackFrameInfo frame = stackFrames[origin];
                 origin++;
                 return frame;
             }
+
+            @Override
+            final Class<?> at(int index) {
+                return stackFrames[index].declaringClass;
+            }
         }
 
         final Function<? super Stream<StackFrame>, ? extends T> function;  // callback
@@ -694,7 +517,7 @@
                 return null;
             }
 
-            StackFrame frame = frameBuffer.nextStackFrame();
+            StackFrameInfo frame = frameBuffer.nextStackFrame();
             depth++;
             return frame;
         }
@@ -711,7 +534,7 @@
 
         @Override
         protected void initFrameBuffer() {
-            this.frameBuffer = new Buffer(getNextBatchSize());
+            this.frameBuffer = new StackFrameBuffer(getNextBatchSize());
         }
 
         @Override
@@ -782,7 +605,7 @@
      * CallerClassFinder is specialized to return Class<?> for each stack frame.
      * StackFrame is not requested.
      */
-    static class CallerClassFinder extends AbstractStackWalker<Integer> {
+    static final class CallerClassFinder extends AbstractStackWalker<Integer, Class<?>> {
         static {
             stackWalkImplClasses.add(CallerClassFinder.class);
         }
@@ -791,6 +614,54 @@
 
         CallerClassFinder(StackWalker walker) {
             super(walker, FILL_CLASS_REFS_ONLY);
+            assert (mode & FILL_CLASS_REFS_ONLY) == FILL_CLASS_REFS_ONLY
+                   : "mode should contain FILL_CLASS_REFS_ONLY";
+        }
+
+        final class ClassBuffer extends FrameBuffer<Class<?>> {
+            Class<?>[] classes;      // caller class for fast path
+            ClassBuffer(int batchSize) {
+                super(batchSize);
+                classes = new Class<?>[batchSize];
+            }
+
+            @Override
+            Class<?>[] frames() { return classes;}
+
+            @Override
+            final Class<?> at(int index) { return classes[index];}
+
+
+            // ------ subclass may override the following methods -------
+            /**
+             * Resizes the buffers for VM to fill in the next batch of stack frames.
+             * The next batch will start at the given startIndex with the maximum number
+             * of elements.
+             *
+             * <p> Subclass may override this method to manage the allocated buffers.
+             *
+             * @param startIndex the start index for the first frame of the next batch to fill in.
+             * @param elements the number of elements for the next batch to fill in.
+             *
+             */
+            @Override
+            void resize(int startIndex, int elements) {
+                if (!isActive())
+                    throw new IllegalStateException("inactive frame buffer can't be resized");
+
+                assert startIndex == START_POS :
+                       "bad start index " + startIndex + " expected " + START_POS;
+
+                int size = startIndex+elements;
+                if (classes.length < size) {
+                    // copy the elements in classes array to the newly allocated one.
+                    // classes[0] is a Thread object
+                    Class<?>[] prev = classes;
+                    classes = new Class<?>[size];
+                    System.arraycopy(prev, 0, classes, 0, startIndex);
+                }
+                currentBatchSize = size;
+            }
         }
 
         Class<?> findCaller() {
@@ -811,15 +682,15 @@
                 if (isMethodHandleFrame(caller)) continue;
                 frames[n++] = caller;
             }
-
-            if (frames[1] == null)
+            if (frames[1] == null) {
                 throw new IllegalStateException("no caller frame");
+            }
             return n;
         }
 
         @Override
         protected void initFrameBuffer() {
-            this.frameBuffer = new FrameBuffer(getNextBatchSize());
+            this.frameBuffer = new ClassBuffer(getNextBatchSize());
         }
 
         @Override
@@ -833,215 +704,64 @@
         }
     }
 
-    /*
-     * StackTrace caches all frames in the buffer.  StackTraceElements are
-     * created lazily when Throwable::getStackTrace is called.
-     */
-    static class StackTrace extends AbstractStackWalker<Integer> {
-        static {
-            stackWalkImplClasses.add(StackTrace.class);
-        }
-
-        class GrowableBuffer extends FrameBuffer {
-            GrowableBuffer(int initialBatchSize) {
-                super(initialBatchSize);
-
-                this.stackFrames = new StackFrame[initialBatchSize];
-                for (int i = START_POS; i < initialBatchSize; i++) {
-                    stackFrames[i] = new StackFrameInfo(walker);
-                }
-            }
-
-            /*
-             * Returns the next index to fill
-             */
-            @Override
-            int startIndex() {
-                return origin;
-            }
-
-            /**
-             * Initialize the buffers for VM to fill in the stack frame information.
-             * The next batch will start at the given startIndex to
-             * the length of the buffer.
-             */
-            @Override
-            void resize(int startIndex, int elements) {
-                // Expand the frame buffer.
-                // Do not call super.resize that will reuse the filled elements
-                // in this frame buffer
-                int size = startIndex+elements;
-                if (classes.length < size) {
-                    // resize the frame buffer
-                    classes = Arrays.copyOf(classes, size);
-                    stackFrames = Arrays.copyOf(stackFrames, size);
-                }
-                for (int i = startIndex; i < size; i++) {
-                    stackFrames[i] = new StackFrameInfo(walker);
-                }
-                currentBatchSize = size;
-            }
-
-            StackTraceElement get(int index) {
-                return new StackTraceElement(classes[index].getName(), "unknown", null, -1);
-            }
-
-            /**
-             * Returns an array of StackTraceElement for all stack frames cached in
-             * this StackTrace object.
-             * <p>
-             * This method is intended for Throwable::getOurStackTrace use only.
-             */
-            StackTraceElement[] toStackTraceElements() {
-                int startIndex = START_POS;
-                for (int i = startIndex; i < classes.length; i++) {
-                    if (classes[i] != null && filterStackWalkImpl(classes[i])) {
-                        startIndex++;
-                    } else {
-                        break;
-                    }
-                }
-
-                // VM fills in the method name, filename, line number info
-                StackFrameInfo.fillInStackFrames(0, stackFrames, startIndex, startIndex + depth);
-
-                StackTraceElement[] stes = new StackTraceElement[depth];
-                for (int i = startIndex, j = 0; i < classes.length && j < depth; i++, j++) {
-                    if (isDebug) {
-                        System.err.println("StackFrame: " + i + " " + stackFrames[i]);
-                    }
-                    stes[j] = stackFrames[i].toStackTraceElement();
-                }
-                return stes;
-            }
-        }
-
-        private static final int MAX_STACK_FRAMES = 1024;
-        private static final StackWalker STACKTRACE_WALKER =
-            StackWalker.newInstanceNoCheck(EnumSet.of(Option.SHOW_REFLECT_FRAMES));
-
-        private StackTraceElement[] stes;
-        static StackTrace dump() {
-            return new StackTrace();
-        }
-
-        static StackTrace dump(Throwable ex) {
-            return new StackTrace(ex);
-        }
-
-        private StackTrace() {
-            this(STACKTRACE_WALKER, DEFAULT_MODE);
-        }
-
-        /*
-         * Throwable::fillInStackTrace and <init> of Throwable and subclasses
-         * are filtered in the VM.
-         */
-        private StackTrace(Throwable ex) {
-            this(STACKTRACE_WALKER, FILTER_FILL_IN_STACKTRACE);  // skip Throwable::init frames
-            if (isDebug) {
-                System.err.println("dump stack for " + ex.getClass().getName());
-            }
-        }
-
-        StackTrace(StackWalker walker, int mode) {
-            super(walker, mode, MAX_STACK_FRAMES);
-
-            // snapshot the stack trace
-            walk();
-        }
-
-        @Override
-        protected Integer consumeFrames() {
-            // traverse all frames and perform the action on the stack frames, if specified
-            int n = 0;
-            while (n < maxDepth && nextFrame() != null) {
-                n++;
-            }
-            return n;
-        }
-
-        @Override
-        protected void initFrameBuffer() {
-            this.frameBuffer = new GrowableBuffer(getNextBatchSize());
-        }
-
-        // TODO: implement better heuristic
-        @Override
-        protected int batchSize(int lastBatchFrameCount) {
-            // chunk size of VM backtrace is 32
-            return lastBatchFrameCount == 0 ? 32 : 32;
-        }
-
-        /**
-         * Returns an array of StackTraceElement for all stack frames cached in
-         * this StackTrace object.
-         * <p>
-         * This method is intended for Throwable::getOurStackTrace use only.
-         */
-        synchronized StackTraceElement[] getStackTraceElements() {
-            if (stes == null) {
-                stes = ((GrowableBuffer) frameBuffer).toStackTraceElements();
-                // release the frameBuffer memory
-                frameBuffer = null;
-            }
-            return stes;
-        }
-
-        /*
-         * Prints stack trace to the given PrintStream.
-         *
-         * Further implementation could skip creating StackTraceElement objects
-         * print directly to the PrintStream.
-         */
-        void printStackTrace(PrintStream s) {
-            StackTraceElement[] stes = getStackTraceElements();
-            synchronized (s) {
-                s.println("Stack trace");
-                for (StackTraceElement traceElement : stes)
-                    s.println("\tat " + traceElement);
-            }
-        }
-    }
-
-    static class LiveStackInfoTraverser<T> extends StackFrameTraverser<T> {
+    static final class LiveStackInfoTraverser<T> extends StackFrameTraverser<T> {
         static {
             stackWalkImplClasses.add(LiveStackInfoTraverser.class);
         }
         // VM will fill in all method info and live stack info directly in StackFrameInfo
-        class Buffer extends FrameBuffer {
-            Buffer(int initialBatchSize) {
+        final class LiveStackFrameBuffer extends FrameBuffer<LiveStackFrameInfo> {
+            private LiveStackFrameInfo[] stackFrames;
+            LiveStackFrameBuffer(int initialBatchSize) {
                 super(initialBatchSize);
-                this.stackFrames = new StackFrame[initialBatchSize];
+                this.stackFrames = new LiveStackFrameInfo[initialBatchSize];
                 for (int i = START_POS; i < initialBatchSize; i++) {
                     stackFrames[i] = new LiveStackFrameInfo(walker);
                 }
             }
 
             @Override
+            LiveStackFrameInfo[] frames() {
+                return stackFrames;
+            }
+
+            @Override
             void resize(int startIndex, int elements) {
-                super.resize(startIndex, elements);
+                if (!isActive()) {
+                    throw new IllegalStateException("inactive frame buffer can't be resized");
+                }
+                assert startIndex == START_POS :
+                       "bad start index " + startIndex + " expected " + START_POS;
+
                 int size = startIndex + elements;
-
                 if (stackFrames.length < size) {
-                    this.stackFrames = new StackFrame[size];
+                    LiveStackFrameInfo[] newFrames = new LiveStackFrameInfo[size];
+                    // copy initial magic...
+                    System.arraycopy(stackFrames, 0, newFrames, 0, startIndex);
+                    stackFrames = newFrames;
                 }
 
                 for (int i = startIndex(); i < size; i++) {
                     stackFrames[i] = new LiveStackFrameInfo(walker);
                 }
+
+                currentBatchSize = size;
             }
 
             @Override
-            StackFrame nextStackFrame() {
+            LiveStackFrameInfo nextStackFrame() {
                 if (isEmpty()) {
                     throw new NoSuchElementException("origin=" + origin + " fence=" + fence);
                 }
 
-                StackFrame frame = stackFrames[origin];
+                LiveStackFrameInfo frame = stackFrames[origin];
                 origin++;
                 return frame;
             }
+
+            @Override
+            final Class<?> at(int index) {
+                return stackFrames[index].declaringClass;
+            }
         }
 
         LiveStackInfoTraverser(StackWalker walker,
@@ -1051,7 +771,183 @@
 
         @Override
         protected void initFrameBuffer() {
-            this.frameBuffer = new Buffer(getNextBatchSize());
+            this.frameBuffer = new LiveStackFrameBuffer(getNextBatchSize());
+        }
+    }
+
+    /*
+     * Frame buffer
+     *
+     * Each specialized AbstractStackWalker subclass may subclass the FrameBuffer.
+     */
+    static abstract class FrameBuffer<F> {
+        static final int START_POS = 2;     // 0th and 1st elements are reserved
+
+        // buffers for VM to fill stack frame info
+        int currentBatchSize;    // current batch size
+        int origin;         // index to the current traversed stack frame
+        int fence;          // index to the last frame in the current batch
+
+        FrameBuffer(int initialBatchSize) {
+            if (initialBatchSize < MIN_BATCH_SIZE) {
+                throw new IllegalArgumentException(initialBatchSize +
+                        " < minimum batch size: " + MIN_BATCH_SIZE);
+            }
+            this.origin = START_POS;
+            this.fence = 0;
+            this.currentBatchSize = initialBatchSize;
+        }
+
+        /**
+         * Returns an array of frames that may be used to store frame objects
+         * when walking the stack.
+         *
+         * May be an array of {@code Class<?>} if the {@code AbstractStackWalker}
+         * mode is {@link #FILL_CLASS_REFS_ONLY}, or an array of
+         * {@link StackFrameInfo} (or derivative) array otherwise.
+         *
+         * @return An array of frames that may be used to store frame objects
+         * when walking the stack. Must not be null.
+         */
+        abstract F[] frames(); // must not return null
+
+        /**
+         * Resizes the buffers for VM to fill in the next batch of stack frames.
+         * The next batch will start at the given startIndex with the maximum number
+         * of elements.
+         *
+         * <p> Subclass may override this method to manage the allocated buffers.
+         *
+         * @param startIndex the start index for the first frame of the next batch to fill in.
+         * @param elements the number of elements for the next batch to fill in.
+         *
+         */
+        abstract void resize(int startIndex, int elements);
+
+        /**
+         * Return the class at the given position in the current batch.
+         * @param index the position of the frame.
+         * @return the class at the given position in the current batch.
+         */
+        abstract Class<?> at(int index);
+
+        // ------ subclass may override the following methods -------
+
+        /*
+         * Returns the start index for this frame buffer is refilled.
+         *
+         * This implementation reuses the allocated buffer for the next batch
+         * of stack frames.  For subclass to retain the fetched stack frames,
+         * it should override this method to return the index at which the frame
+         * should be filled in for the next batch.
+         */
+        int startIndex() {
+            return START_POS;
+        }
+
+        /**
+         * Returns next StackFrame object in the current batch of stack frames
+         */
+        F nextStackFrame() {
+            throw new InternalError("should not reach here");
+        }
+
+        // ------ FrameBuffer implementation ------
+
+        final int curBatchFrameCount() {
+            return currentBatchSize-START_POS;
+        }
+
+        /*
+         * Tests if this frame buffer is empty.  All frames are fetched.
+         */
+        final boolean isEmpty() {
+            return origin >= fence || (origin == START_POS && fence == 0);
+        }
+
+        /*
+         * Freezes this frame buffer.  The stack stream source is done fetching.
+         */
+        final void freeze() {
+            origin = 0;
+            fence = 0;
+        }
+
+        /*
+         * Tests if this frame buffer is active.  It is inactive when
+         * it is done for traversal.  All stack frames have been traversed.
+         */
+        final boolean isActive() {
+            return origin > 0 && (fence == 0 || origin < fence || fence == currentBatchSize);
+        }
+
+        /**
+         * Gets the class at the current frame and move to the next frame.
+         */
+        final Class<?> next() {
+            if (isEmpty()) {
+                throw new NoSuchElementException("origin=" + origin + " fence=" + fence);
+            }
+            Class<?> c = at(origin);
+            origin++;
+            if (isDebug) {
+                int index = origin-1;
+                System.out.format("  next frame at %d: %s (origin %d fence %d)%n", index,
+                        Objects.toString(c), index, fence);
+            }
+            return c;
+        }
+
+        /**
+         * Gets the class at the current frame.
+         */
+        final Class<?> get() {
+            if (isEmpty()) {
+                throw new NoSuchElementException("origin=" + origin + " fence=" + fence);
+            }
+            return at(origin);
+        }
+
+        /*
+         * Returns the index of the current frame.
+         */
+        final int getIndex() {
+            return origin;
+        }
+
+        /*
+         * Set the start and end index of a new batch of stack frames that have
+         * been filled in this frame buffer.
+         */
+        final void setBatch(int depth, int startIndex, int endIndex) {
+            if (startIndex <= 0 || endIndex <= 0)
+                throw new IllegalArgumentException("startIndex=" + startIndex + " endIndex=" + endIndex);
+
+            this.origin = startIndex;
+            this.fence = endIndex;
+            if (depth == 0 && fence > 0) {
+                // filter the frames due to the stack stream implementation
+                for (int i = START_POS; i < fence; i++) {
+                    Class<?> c = at(i);
+                    if (isDebug) System.err.format("  frame %d: %s%n", i, c);
+                    if (filterStackWalkImpl(c)) {
+                        origin++;
+                    } else {
+                        break;
+                    }
+                }
+            }
+        }
+
+        /*
+         * Checks if the origin is the expected start index.
+         */
+        final void check(int skipFrames) {
+            int index = skipFrames + START_POS;
+            if (origin != index) {
+                // stack walk must continue with the previous frame depth
+                throw new IllegalStateException("origin " + origin + " != " + index);
+            }
         }
     }
 
@@ -1093,14 +989,9 @@
     }
 
     private static boolean getProperty(String key, boolean value) {
-        String s = AccessController.doPrivileged(new PrivilegedAction<>() {
-            @Override
-            public String run() {
-                return System.getProperty(key);
-            }
-        });
+        String s = GetPropertyAction.getProperty(key);
         if (s != null) {
-            return Boolean.valueOf(s);
+            return Boolean.parseBoolean(s);
         }
         return value;
     }
--- a/jdk/src/java.base/share/classes/java/lang/String.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/String.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2016, 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
@@ -78,14 +78,8 @@
  * <p>
  * The Java language provides special support for the string
  * concatenation operator (&nbsp;+&nbsp;), and for conversion of
- * other objects to strings. String concatenation is implemented
- * through the {@code StringBuilder}(or {@code StringBuffer})
- * class and its {@code append} method.
- * String conversions are implemented through the method
- * {@code toString}, defined by {@code Object} and
- * inherited by all classes in Java. For additional information on
- * string concatenation and conversion, see Gosling, Joy, and Steele,
- * <i>The Java Language Specification</i>.
+ * other objects to strings. For additional information on string
+ * concatenation and conversion, see <i>The Java&trade; Language Specification</i>.
  *
  * <p> Unless otherwise noted, passing a {@code null} argument to a constructor
  * or method in this class will cause a {@link NullPointerException} to be
@@ -106,6 +100,14 @@
  * into account.  The {@link java.text.Collator} class provides methods for
  * finer-grain, locale-sensitive String comparison.
  *
+ * @implNote The implementation of the string concatenation operator is left to
+ * the discretion of a Java compiler, as long as the compiler ultimately conforms
+ * to <i>The Java&trade; Language Specification</i>. For example, the {@code javac} compiler
+ * may implement the operator with {@code StringBuffer}, {@code StringBuilder},
+ * or {@code java.lang.invoke.StringConcatFactory} depending on the JDK version. The
+ * implementation of string conversion is typically through the method {@code toString},
+ * defined by {@code Object} and inherited by all classes in Java.
+ *
  * @author  Lee Boynton
  * @author  Arthur van Hoff
  * @author  Martin Buchholz
@@ -115,6 +117,7 @@
  * @see     java.lang.StringBuilder
  * @see     java.nio.charset.Charset
  * @since   1.0
+ * @jls     15.18.1 String Concatenation Operator +
  */
 
 public final class String
@@ -363,7 +366,7 @@
      * @see  #String(byte[], java.nio.charset.Charset)
      * @see  #String(byte[])
      */
-    @Deprecated
+    @Deprecated(since="1.1")
     public String(byte ascii[], int hibyte, int offset, int count) {
         checkBoundsOffCount(offset, count, ascii.length);
         if (count == 0) {
@@ -415,7 +418,7 @@
      * @see  #String(byte[], java.nio.charset.Charset)
      * @see  #String(byte[])
      */
-    @Deprecated
+    @Deprecated(since="1.1")
     public String(byte ascii[], int hibyte) {
         this(ascii, hibyte, 0, ascii.length);
     }
@@ -911,7 +914,7 @@
      *                 dst.length}
      *          </ul>
      */
-    @Deprecated
+    @Deprecated(since="1.1")
     public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin) {
         checkBoundsBeginEnd(srcBegin, srcEnd, length());
         Objects.requireNonNull(dst);
@@ -2977,6 +2980,7 @@
      *
      * @return  a string that has the same contents as this string, but is
      *          guaranteed to be from a pool of unique strings.
+     * @jls 3.10.5 String Literals
      */
     public native String intern();
 
--- a/jdk/src/java.base/share/classes/java/lang/System.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/System.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1155,8 +1155,9 @@
          * @param level the log message level.
          * @param msg the string message (or a key in the message catalog, if
          * this logger is a {@link
-         * LoggerFinder#getLocalizedLogger(java.lang.String, java.util.ResourceBundle, java.lang.Class)
-         * localized logger}); can be {@code null}.
+         * LoggerFinder#getLocalizedLogger(java.lang.String,
+         * java.util.ResourceBundle, java.lang.reflect.Module) localized logger});
+         * can be {@code null}.
          *
          * @throws NullPointerException if {@code level} is {@code null}.
          */
@@ -1222,8 +1223,9 @@
          * @param level the log message level.
          * @param msg the string message (or a key in the message catalog, if
          * this logger is a {@link
-         * LoggerFinder#getLocalizedLogger(java.lang.String, java.util.ResourceBundle, java.lang.Class)
-         * localized logger}); can be {@code null}.
+         * LoggerFinder#getLocalizedLogger(java.lang.String,
+         * java.util.ResourceBundle, java.lang.reflect.Module) localized logger});
+         * can be {@code null}.
          * @param thrown a {@code Throwable} associated with the log message;
          *        can be {@code null}.
          *
@@ -1270,8 +1272,9 @@
          * @param format the string message format in {@link
          * java.text.MessageFormat} format, (or a key in the message
          * catalog, if this logger is a {@link
-         * LoggerFinder#getLocalizedLogger(java.lang.String, java.util.ResourceBundle, java.lang.Class)
-         * localized logger}); can be {@code null}.
+         * LoggerFinder#getLocalizedLogger(java.lang.String,
+         * java.util.ResourceBundle, java.lang.reflect.Module) localized logger});
+         * can be {@code null}.
          * @param params an optional list of parameters to the message (may be
          * none).
          *
@@ -1453,30 +1456,30 @@
 
         /**
          * Returns an instance of {@link Logger Logger}
-         * for the given {@code caller}.
+         * for the given {@code module}.
          *
          * @param name the name of the logger.
-         * @param caller the class for which the logger is being requested.
+         * @param module the module for which the logger is being requested.
          *
-         * @return a {@link Logger logger} suitable for the given caller's
-         *         use.
+         * @return a {@link Logger logger} suitable for use within the given
+         *         module.
          * @throws NullPointerException if {@code name} is {@code null} or
-         *        {@code caller} is {@code null}.
+         *        {@code module} is {@code null}.
          * @throws SecurityException if a security manager is present and its
          *         {@code checkPermission} method doesn't allow the
          *         {@code RuntimePermission("loggerFinder")}.
          */
-        public abstract Logger getLogger(String name, /* Module */ Class<?> caller);
+        public abstract Logger getLogger(String name, Module module);
 
         /**
          * Returns a localizable instance of {@link Logger Logger}
-         * for the given {@code caller}.
+         * for the given {@code module}.
          * The returned logger will use the provided resource bundle for
          * message localization.
          *
          * @implSpec By default, this method calls {@link
-         * #getLogger(java.lang.String, java.lang.Class)
-         * this.getLogger(name, caller)} to obtain a logger, then wraps that
+         * #getLogger(java.lang.String, java.lang.reflect.Module)
+         * this.getLogger(name, module)} to obtain a logger, then wraps that
          * logger in a {@link Logger} instance where all methods that do not
          * take a {@link ResourceBundle} as parameter are redirected to one
          * which does - passing the given {@code bundle} for
@@ -1499,19 +1502,19 @@
          *
          * @param name    the name of the logger.
          * @param bundle  a resource bundle; can be {@code null}.
-         * @param caller the class for which the logger is being requested.
+         * @param module  the module for which the logger is being requested.
          * @return an instance of {@link Logger Logger}  which will use the
          * provided resource bundle for message localization.
          *
          * @throws NullPointerException if {@code name} is {@code null} or
-         *         {@code caller} is {@code null}.
+         *         {@code module} is {@code null}.
          * @throws SecurityException if a security manager is present and its
          *         {@code checkPermission} method doesn't allow the
          *         {@code RuntimePermission("loggerFinder")}.
          */
         public Logger getLocalizedLogger(String name, ResourceBundle bundle,
-                                          /* Module */ Class<?> caller) {
-            return new LocalizedLoggerWrapper<>(getLogger(name, caller), bundle);
+                                         Module module) {
+            return new LocalizedLoggerWrapper<>(getLogger(name, module), bundle);
         }
 
         /**
@@ -1558,12 +1561,13 @@
      *
      * @implSpec
      * Instances returned by this method route messages to loggers
-     * obtained by calling {@link LoggerFinder#getLogger(java.lang.String, java.lang.Class)
-     * LoggerFinder.getLogger(name, caller)}.
+     * obtained by calling {@link LoggerFinder#getLogger(java.lang.String,
+     * java.lang.reflect.Module) LoggerFinder.getLogger(name, module)}, where
+     * {@code module} is the caller's module.
      *
      * @apiNote
      * This method may defer calling the {@link
-     * LoggerFinder#getLogger(java.lang.String, java.lang.Class)
+     * LoggerFinder#getLogger(java.lang.String, java.lang.reflect.Module)
      * LoggerFinder.getLogger} method to create an actual logger supplied by
      * the logging backend, for instance, to allow loggers to be obtained during
      * the system initialization time.
@@ -1579,7 +1583,7 @@
     public static Logger getLogger(String name) {
         Objects.requireNonNull(name);
         final Class<?> caller = Reflection.getCallerClass();
-        return LazyLoggers.getLogger(name, caller);
+        return LazyLoggers.getLogger(name, caller.getModule());
     }
 
     /**
@@ -1591,8 +1595,9 @@
      * @implSpec
      * The returned logger will perform message localization as specified
      * by {@link LoggerFinder#getLocalizedLogger(java.lang.String,
-     * java.util.ResourceBundle, java.lang.Class)
-     * LoggerFinder.getLocalizedLogger(name, bundle, caller}.
+     * java.util.ResourceBundle, java.lang.reflect.Module)
+     * LoggerFinder.getLocalizedLogger(name, bundle, module}, where
+     * {@code module} is the caller's module.
      *
      * @apiNote
      * This method is intended to be used after the system is fully initialized.
@@ -1624,12 +1629,14 @@
         // Bootstrap sensitive classes in the JDK do not use resource bundles
         // when logging. This could be revisited later, if it needs to.
         if (sm != null) {
-            return AccessController.doPrivileged((PrivilegedAction<Logger>)
-                    () -> LoggerFinder.accessProvider().getLocalizedLogger(name, rb, caller),
-                    null,
-                    LoggerFinder.LOGGERFINDER_PERMISSION);
+            final PrivilegedAction<Logger> pa =
+                    () -> LoggerFinder.accessProvider()
+                            .getLocalizedLogger(name, rb, caller.getModule());
+            return AccessController.doPrivileged(pa, null,
+                                         LoggerFinder.LOGGERFINDER_PERMISSION);
         }
-        return LoggerFinder.accessProvider().getLocalizedLogger(name, rb, caller);
+        return LoggerFinder.accessProvider()
+                .getLocalizedLogger(name, rb, caller.getModule());
     }
 
     /**
@@ -1715,6 +1722,7 @@
      *      finalizers being called on live objects while other threads are
      *      concurrently manipulating those objects, resulting in erratic
      *      behavior or deadlock.
+     *      This method is subject to removal in a future version of Java SE.
      * @param value indicating enabling or disabling of finalization
      * @throws  SecurityException
      *        if a security manager exists and its <code>checkExit</code>
@@ -1725,7 +1733,7 @@
      * @see     java.lang.SecurityManager#checkExit(int)
      * @since   1.1
      */
-    @Deprecated
+    @Deprecated(since="1.2", forRemoval=true)
     public static void runFinalizersOnExit(boolean value) {
         Runtime.runFinalizersOnExit(value);
     }
--- a/jdk/src/java.base/share/classes/java/lang/Thread.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/Thread.java	Thu Apr 28 23:08:16 2016 -0700
@@ -890,7 +890,7 @@
      *       <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
      *       are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     public final void stop() {
         SecurityManager security = System.getSecurityManager();
         if (security != null) {
@@ -922,8 +922,9 @@
      *        For more information, see
      *        <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
      *        are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
+     *        This method is subject to removal in a future version of Java SE.
      */
-    @Deprecated
+    @Deprecated(since="1.2", forRemoval=true)
     public final synchronized void stop(Throwable obj) {
         throw new UnsupportedOperationException();
     }
@@ -1043,9 +1044,10 @@
      *     "frozen" processes. For more information, see
      *     <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">
      *     Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
+     *     This method is subject to removal in a future version of Java SE.
      * @throws NoSuchMethodError always
      */
-    @Deprecated
+    @Deprecated(since="1.5", forRemoval=true)
     public void destroy() {
         throw new NoSuchMethodError();
     }
@@ -1083,7 +1085,7 @@
      *   <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
      *   are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     public final void suspend() {
         checkAccess();
         suspend0();
@@ -1109,7 +1111,7 @@
      *     <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
      *     are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     public final void resume() {
         checkAccess();
         resume0();
@@ -1270,8 +1272,10 @@
      * @deprecated The definition of this call depends on {@link #suspend},
      *             which is deprecated.  Further, the results of this call
      *             were never well-defined.
+     *             This method is subject to removal in a future version of Java SE.
+     * @see        StackWalker
      */
-    @Deprecated
+    @Deprecated(since="1.2", forRemoval=true)
     public native int countStackFrames();
 
     /**
@@ -1388,7 +1392,7 @@
      * This method is used only for debugging.
      */
     public static void dumpStack() {
-        StackStreamFactory.makeStackTrace().printStackTrace(System.err);
+        new Exception("Stack trace").printStackTrace();
     }
 
     /**
@@ -1610,8 +1614,7 @@
             }
             return stackTrace;
         } else {
-            // Don't need JVM help for current thread
-            return StackStreamFactory.makeStackTrace().getStackTraceElements();
+            return (new Exception()).getStackTrace();
         }
     }
 
--- a/jdk/src/java.base/share/classes/java/lang/ThreadGroup.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/ThreadGroup.java	Thu Apr 28 23:08:16 2016 -0700
@@ -607,7 +607,7 @@
      * @deprecated    This method is inherently unsafe.  See
      *     {@link Thread#stop} for details.
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     public final void stop() {
         if (stopOrSuspend(false))
             Thread.currentThread().stop();
@@ -669,7 +669,7 @@
      * @deprecated    This method is inherently deadlock-prone.  See
      *     {@link Thread#suspend} for details.
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     @SuppressWarnings("deprecation")
     public final void suspend() {
         if (stopOrSuspend(true))
@@ -732,7 +732,7 @@
      *       both of which have been deprecated, as they are inherently
      *       deadlock-prone.  See {@link Thread#suspend} for details.
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     @SuppressWarnings("deprecation")
     public final void resume() {
         int ngroupsSnapshot;
@@ -1073,7 +1073,7 @@
      *             which is deprecated.  Further, the behavior of this call
      *             was never specified.
      */
-    @Deprecated
+    @Deprecated(since="1.2")
     public boolean allowThreadSuspension(boolean b) {
         this.vmAllowSuspension = b;
         if (!b) {
--- a/jdk/src/java.base/share/classes/java/lang/Throwable.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/Throwable.java	Thu Apr 28 23:08:16 2016 -0700
@@ -785,11 +785,7 @@
     public synchronized Throwable fillInStackTrace() {
         if (stackTrace != null ||
             backtrace != null /* Out of protocol state */ ) {
-            if (backtrace == null && StackStreamFactory.useStackTrace(this)) {
-                backtrace = StackStreamFactory.makeStackTrace(this);
-            } else {
-                fillInStackTrace(0);
-            }
+            fillInStackTrace(0);
             stackTrace = UNASSIGNED_STACK;
         }
         return this;
@@ -830,15 +826,11 @@
         // backtrace if this is the first call to this method
         if (stackTrace == UNASSIGNED_STACK ||
             (stackTrace == null && backtrace != null) /* Out of protocol state */) {
-            if (backtrace instanceof StackStreamFactory.StackTrace) {
-                stackTrace = ((StackStreamFactory.StackTrace)backtrace).getStackTraceElements();
-            } else {
-                stackTrace = new StackTraceElement[depth];
-                for (int i = 0; i < depth; i++) {
-                    stackTrace[i] = new StackTraceElement();
-                }
-                getStackTraceElements(stackTrace);
+            stackTrace = new StackTraceElement[depth];
+            for (int i = 0; i < depth; i++) {
+                stackTrace[i] = new StackTraceElement();
             }
+            getStackTraceElements(stackTrace);
         } else if (stackTrace == null) {
             return UNASSIGNED_STACK;
         }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java	Thu Apr 28 23:08:16 2016 -0700
@@ -88,8 +88,7 @@
 
     static {
         final String key = "jdk.internal.lambda.dumpProxyClasses";
-        String path = AccessController.doPrivileged(
-                new GetPropertyAction(key));
+        String path = GetPropertyAction.getProperty(key);
         dumper = (null == path) ? null : ProxyClassesDumper.getInstance(path);
     }
 
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java	Thu Apr 28 23:08:16 2016 -0700
@@ -733,6 +733,7 @@
     }
 
     @Override
+    @SuppressWarnings("deprecation")
     public int hashCode() {
         // Avoid autoboxing getReferenceKind(), since this is used early and will force
         // early initialization of Byte$ByteCache
@@ -826,7 +827,7 @@
         assert(isResolved() == isResolved);
     }
 
-    void checkForTypeAlias() {
+    void checkForTypeAlias(Class<?> refc) {
         if (isInvocable()) {
             MethodType type;
             if (this.type instanceof MethodType)
@@ -834,16 +835,16 @@
             else
                 this.type = type = getMethodType();
             if (type.erase() == type)  return;
-            if (VerifyAccess.isTypeVisible(type, clazz))  return;
-            throw new LinkageError("bad method type alias: "+type+" not visible from "+clazz);
+            if (VerifyAccess.isTypeVisible(type, refc))  return;
+            throw new LinkageError("bad method type alias: "+type+" not visible from "+refc);
         } else {
             Class<?> type;
             if (this.type instanceof Class<?>)
                 type = (Class<?>) this.type;
             else
                 this.type = type = getFieldType();
-            if (VerifyAccess.isTypeVisible(type, clazz))  return;
-            throw new LinkageError("bad field type alias: "+type+" not visible from "+clazz);
+            if (VerifyAccess.isTypeVisible(type, refc))  return;
+            throw new LinkageError("bad field type alias: "+type+" not visible from "+refc);
         }
     }
 
@@ -1015,10 +1016,25 @@
             MemberName m = ref.clone();  // JVM will side-effect the ref
             assert(refKind == m.getReferenceKind());
             try {
+                // There are 4 entities in play here:
+                //   * LC: lookupClass
+                //   * REFC: symbolic reference class (MN.clazz before resolution);
+                //   * DEFC: resolved method holder (MN.clazz after resolution);
+                //   * PTYPES: parameter types (MN.type)
+                //
+                // What we care about when resolving a MemberName is consistency between DEFC and PTYPES.
+                // We do type alias (TA) checks on DEFC to ensure that. DEFC is not known until the JVM
+                // finishes the resolution, so do TA checks right after MHN.resolve() is over.
+                //
+                // All parameters passed by a caller are checked against MH type (PTYPES) on every invocation,
+                // so it is safe to call a MH from any context.
+                //
+                // REFC view on PTYPES doesn't matter, since it is used only as a starting point for resolution and doesn't
+                // participate in method selection.
                 m = MethodHandleNatives.resolve(m, lookupClass);
-                m.checkForTypeAlias();
+                m.checkForTypeAlias(m.getDeclaringClass());
                 m.resolution = null;
-            } catch (LinkageError ex) {
+            } catch (ClassNotFoundException | LinkageError ex) {
                 // JVM reports that the "bytecode behavior" would get an error
                 assert(!m.isResolved());
                 m.resolution = ex;
@@ -1132,6 +1148,10 @@
             public Object newMemberName() {
                 return new MemberName();
             }
+            public String getName(Object mname) {
+                MemberName memberName = (MemberName)mname;
+                return memberName.getName();
+            }
         });
     }
 }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,6 +25,7 @@
 
 package java.lang.invoke;
 
+import java.lang.reflect.Array;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.Arrays;
@@ -1892,7 +1893,8 @@
             MH_tryFinallyExec        = 12,
             MH_tryFinallyVoidExec    = 13,
             MH_decrementCounter      = 14,
-            MH_LIMIT                 = 15;
+            MH_Array_newInstance     = 15,
+            MH_LIMIT                 = 16;
 
     static MethodHandle getConstantHandle(int idx) {
         MethodHandle handle = HANDLES[idx];
@@ -1965,6 +1967,9 @@
                 case MH_decrementCounter:
                     return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "decrementCounter",
                             MethodType.methodType(int.class, int.class));
+                case MH_Array_newInstance:
+                    return IMPL_LOOKUP.findStatic(Array.class, "newInstance",
+                            MethodType.methodType(Object.class, Class.class, int.class));
             }
         } catch (ReflectiveOperationException ex) {
             throw newInternalError(ex);
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java	Thu Apr 28 23:08:16 2016 -0700
@@ -49,7 +49,7 @@
 
     static native void init(MemberName self, Object ref);
     static native void expand(MemberName self);
-    static native MemberName resolve(MemberName self, Class<?> caller) throws LinkageError;
+    static native MemberName resolve(MemberName self, Class<?> caller) throws LinkageError, ClassNotFoundException;
     static native int getMembers(Class<?> defc, String matchName, String matchSig,
             int matchFlags, Class<?> caller, int skip, MemberName[] results);
 
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,9 +25,9 @@
 
 package java.lang.invoke;
 
-import java.security.AccessController;
-import java.security.PrivilegedAction;
+import java.util.Properties;
 import jdk.internal.misc.Unsafe;
+import sun.security.action.GetPropertyAction;
 
 /**
  * This class consists exclusively of static names internal to the
@@ -53,32 +53,27 @@
     static final boolean VAR_HANDLE_GUARDS;
 
     static {
-        final Object[] values = new Object[10];
-        AccessController.doPrivileged(new PrivilegedAction<>() {
-                public Void run() {
-                    values[0] = Boolean.getBoolean("java.lang.invoke.MethodHandle.DEBUG_NAMES");
-                    values[1] = Boolean.getBoolean("java.lang.invoke.MethodHandle.DUMP_CLASS_FILES");
-                    values[2] = Boolean.getBoolean("java.lang.invoke.MethodHandle.TRACE_INTERPRETER");
-                    values[3] = Boolean.getBoolean("java.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE");
-                    values[4] = Integer.getInteger("java.lang.invoke.MethodHandle.COMPILE_THRESHOLD", 0);
-                    values[5] = Integer.getInteger("java.lang.invoke.MethodHandle.DONT_INLINE_THRESHOLD", 30);
-                    values[6] = Integer.getInteger("java.lang.invoke.MethodHandle.PROFILE_LEVEL", 0);
-                    values[7] = Boolean.parseBoolean(System.getProperty("java.lang.invoke.MethodHandle.PROFILE_GWT", "true"));
-                    values[8] = Integer.getInteger("java.lang.invoke.MethodHandle.CUSTOMIZE_THRESHOLD", 127);
-                    values[9] = Boolean.parseBoolean(System.getProperty("java.lang.invoke.VarHandle.VAR_HANDLE_GUARDS", "true"));
-                    return null;
-                }
-            });
-        DEBUG_METHOD_HANDLE_NAMES = (Boolean) values[0];
-        DUMP_CLASS_FILES          = (Boolean) values[1];
-        TRACE_INTERPRETER         = (Boolean) values[2];
-        TRACE_METHOD_LINKAGE      = (Boolean) values[3];
-        COMPILE_THRESHOLD         = (Integer) values[4];
-        DONT_INLINE_THRESHOLD     = (Integer) values[5];
-        PROFILE_LEVEL             = (Integer) values[6];
-        PROFILE_GWT               = (Boolean) values[7];
-        CUSTOMIZE_THRESHOLD       = (Integer) values[8];
-        VAR_HANDLE_GUARDS         = (Boolean) values[9];
+        Properties props = GetPropertyAction.getProperties();
+        DEBUG_METHOD_HANDLE_NAMES = Boolean.parseBoolean(
+                props.getProperty("java.lang.invoke.MethodHandle.DEBUG_NAMES"));
+        DUMP_CLASS_FILES = Boolean.parseBoolean(
+                props.getProperty("java.lang.invoke.MethodHandle.DUMP_CLASS_FILES"));
+        TRACE_INTERPRETER = Boolean.parseBoolean(
+                props.getProperty("java.lang.invoke.MethodHandle.TRACE_INTERPRETER"));
+        TRACE_METHOD_LINKAGE = Boolean.parseBoolean(
+                props.getProperty("java.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE"));
+        COMPILE_THRESHOLD = Integer.parseInt(
+                props.getProperty("java.lang.invoke.MethodHandle.COMPILE_THRESHOLD", "0"));
+        DONT_INLINE_THRESHOLD = Integer.parseInt(
+                props.getProperty("java.lang.invoke.MethodHandle.DONT_INLINE_THRESHOLD", "30"));
+        PROFILE_LEVEL = Integer.parseInt(
+                props.getProperty("java.lang.invoke.MethodHandle.PROFILE_LEVEL", "0"));
+        PROFILE_GWT = Boolean.parseBoolean(
+                props.getProperty("java.lang.invoke.MethodHandle.PROFILE_GWT", "true"));
+        CUSTOMIZE_THRESHOLD = Integer.parseInt(
+                props.getProperty("java.lang.invoke.MethodHandle.CUSTOMIZE_THRESHOLD", "127"));
+        VAR_HANDLE_GUARDS = Boolean.parseBoolean(
+                props.getProperty("java.lang.invoke.VarHandle.VAR_HANDLE_GUARDS", "true"));
 
         if (CUSTOMIZE_THRESHOLD < -1 || CUSTOMIZE_THRESHOLD > 127) {
             throw newInternalError("CUSTOMIZE_THRESHOLD should be in [-1...127] range");
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,34 +25,40 @@
 
 package java.lang.invoke;
 
-import java.lang.reflect.*;
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.List;
-import java.util.Arrays;
-import java.util.Objects;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.reflect.CallerSensitive;
+import jdk.internal.reflect.Reflection;
 import sun.invoke.util.ValueConversions;
 import sun.invoke.util.VerifyAccess;
 import sun.invoke.util.Wrapper;
-import jdk.internal.reflect.CallerSensitive;
-import jdk.internal.reflect.Reflection;
 import sun.reflect.misc.ReflectUtil;
 import sun.security.util.SecurityConstants;
+
 import java.lang.invoke.LambdaForm.BasicType;
-
-import static java.lang.invoke.MethodHandleImpl.Intrinsic;
-import static java.lang.invoke.MethodHandleNatives.Constants.*;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ReflectPermission;
+import java.nio.ByteOrder;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Objects;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
-import jdk.internal.org.objectweb.asm.ClassWriter;
-import jdk.internal.org.objectweb.asm.Opcodes;
-
+import static java.lang.invoke.MethodHandleImpl.Intrinsic;
+import static java.lang.invoke.MethodHandleNatives.Constants.*;
 import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
+import static java.lang.invoke.MethodType.methodType;
 
 /**
  * This class consists exclusively of static methods that operate on or return
@@ -739,10 +745,13 @@
             if (name.startsWith("java.lang.invoke."))
                 throw newIllegalArgumentException("illegal lookupClass: "+lookupClass);
 
-            // For caller-sensitive MethodHandles.lookup()
-            // disallow lookup more restricted packages
+            // For caller-sensitive MethodHandles.lookup() disallow lookup from
+            // restricted packages.  This a fragile and blunt approach.
+            // TODO replace with a more formal and less fragile mechanism
+            // that does not bluntly restrict classes under packages within
+            // java.base from looking up MethodHandles or VarHandles.
             if (allowedModes == ALL_MODES && lookupClass.getClassLoader() == null) {
-                if (name.startsWith("java.") ||
+                if ((name.startsWith("java.") && !name.startsWith("java.util.concurrent.")) ||
                         (name.startsWith("sun.") && !name.startsWith("sun.invoke."))) {
                     throw newIllegalArgumentException("illegal lookupClass: " + lookupClass);
                 }
@@ -1001,6 +1010,9 @@
          * @throws NullPointerException if any argument is null
          */
         public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
+            if (refc.isArray()) {
+                throw new NoSuchMethodException("no constructor for array class: " + refc.getName());
+            }
             String name = "<init>";
             MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
             return getDirectConstructor(refc, ctor);
@@ -2212,6 +2224,27 @@
     }
 
     /**
+     * Produces a method handle constructing arrays of a desired type.
+     * The return type of the method handle will be the array type.
+     * The type of its sole argument will be {@code int}, which specifies the size of the array.
+     * @param arrayClass an array type
+     * @return a method handle which can create arrays of the given type
+     * @throws NullPointerException if the argument is {@code null}
+     * @throws IllegalArgumentException if {@code arrayClass} is not an array type
+     * @see java.lang.reflect.Array#newInstance(Class, int)
+     * @since 9
+     */
+    public static
+    MethodHandle arrayConstructor(Class<?> arrayClass) throws IllegalArgumentException {
+        if (!arrayClass.isArray()) {
+            throw newIllegalArgumentException("not an array class: " + arrayClass.getName());
+        }
+        MethodHandle ani = MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_Array_newInstance).
+                bindTo(arrayClass.getComponentType());
+        return ani.asType(ani.type().changeReturnType(arrayClass));
+    }
+
+    /**
      * Produces a method handle giving read access to elements of an array.
      * The type of the method handle will have a return type of the array's
      * element type.  Its first argument will be the array type,
@@ -2335,13 +2368,12 @@
      *
      * @param viewArrayClass the view array class, with a component type of
      * type {@code T}
-     * @param bigEndian true if the endianness of the view array elements, as
-     * stored in the underlying {@code byte} array, is big endian, otherwise
-     * little endian
+     * @param byteOrder the endianness of the view array elements, as
+     * stored in the underlying {@code byte} array
      * @return a VarHandle giving access to elements of a {@code byte[]} array
      * viewed as if elements corresponding to the components type of the view
      * array class
-     * @throws NullPointerException if viewArrayClass is null
+     * @throws NullPointerException if viewArrayClass or byteOrder is null
      * @throws IllegalArgumentException if viewArrayClass is not an array type
      * @throws UnsupportedOperationException if the component type of
      * viewArrayClass is not supported as a variable type
@@ -2349,8 +2381,10 @@
      */
     public static
     VarHandle byteArrayViewVarHandle(Class<?> viewArrayClass,
-                                     boolean bigEndian) throws IllegalArgumentException {
-        return VarHandles.byteArrayViewHandle(viewArrayClass, bigEndian);
+                                     ByteOrder byteOrder) throws IllegalArgumentException {
+        Objects.requireNonNull(byteOrder);
+        return VarHandles.byteArrayViewHandle(viewArrayClass,
+                                              byteOrder == ByteOrder.BIG_ENDIAN);
     }
 
     /**
@@ -2420,14 +2454,13 @@
      *
      * @param viewArrayClass the view array class, with a component type of
      * type {@code T}
-     * @param bigEndian true if the endianness of the view array elements, as
-     * stored in the underlying {@code ByteBuffer}, is big endian, otherwise
-     * little endian (Note this overrides the endianness of a
-     * {@code ByteBuffer})
+     * @param byteOrder the endianness of the view array elements, as
+     * stored in the underlying {@code ByteBuffer} (Note this overrides the
+     * endianness of a {@code ByteBuffer})
      * @return a VarHandle giving access to elements of a {@code ByteBuffer}
      * viewed as if elements corresponding to the components type of the view
      * array class
-     * @throws NullPointerException if viewArrayClass is null
+     * @throws NullPointerException if viewArrayClass or byteOrder is null
      * @throws IllegalArgumentException if viewArrayClass is not an array type
      * @throws UnsupportedOperationException if the component type of
      * viewArrayClass is not supported as a variable type
@@ -2435,8 +2468,10 @@
      */
     public static
     VarHandle byteBufferViewVarHandle(Class<?> viewArrayClass,
-                                      boolean bigEndian) throws IllegalArgumentException {
-        return VarHandles.makeByteBufferViewHandle(viewArrayClass, bigEndian);
+                                      ByteOrder byteOrder) throws IllegalArgumentException {
+        Objects.requireNonNull(byteOrder);
+        return VarHandles.makeByteBufferViewHandle(viewArrayClass,
+                                                   byteOrder == ByteOrder.BIG_ENDIAN);
     }
 
 
@@ -3000,7 +3035,7 @@
 
     private static final MethodHandle[] IDENTITY_MHS = new MethodHandle[Wrapper.values().length];
     private static MethodHandle makeIdentity(Class<?> ptype) {
-        MethodType mtype = MethodType.methodType(ptype, ptype);
+        MethodType mtype = methodType(ptype, ptype);
         LambdaForm lform = LambdaForm.identityForm(BasicType.basicType(ptype));
         return MethodHandleImpl.makeIntrinsic(mtype, lform, Intrinsic.IDENTITY);
     }
@@ -3018,7 +3053,7 @@
     }
     private static final MethodHandle[] ZERO_MHS = new MethodHandle[Wrapper.values().length];
     private static MethodHandle makeZero(Class<?> rtype) {
-        MethodType mtype = MethodType.methodType(rtype);
+        MethodType mtype = methodType(rtype);
         LambdaForm lform = LambdaForm.zeroForm(BasicType.basicType(rtype));
         return MethodHandleImpl.makeIntrinsic(mtype, lform, Intrinsic.ZERO);
     }
@@ -3929,7 +3964,7 @@
     MethodHandle throwException(Class<?> returnType, Class<? extends Throwable> exType) {
         if (!Throwable.class.isAssignableFrom(exType))
             throw new ClassCastException(exType.getName());
-        return MethodHandleImpl.throwException(MethodType.methodType(returnType, exType));
+        return MethodHandleImpl.throwException(methodType(returnType, exType));
     }
 
     /**
@@ -4166,7 +4201,7 @@
         for (int i = 0; i < nclauses; ++i) {
             Class<?> t = iterationVariableTypes.get(i);
             if (init.get(i) == null) {
-                init.set(i, empty(MethodType.methodType(t, commonSuffix)));
+                init.set(i, empty(methodType(t, commonSuffix)));
             }
             if (step.get(i) == null) {
                 step.set(i, dropArgumentsToMatch(identityOrVoid(t), 0, commonParameterSequence, i));
@@ -4175,7 +4210,7 @@
                 pred.set(i, dropArguments(constant(boolean.class, true), 0, commonParameterSequence));
             }
             if (fini.get(i) == null) {
-                fini.set(i, empty(MethodType.methodType(t, commonParameterSequence)));
+                fini.set(i, empty(methodType(t, commonParameterSequence)));
             }
         }
 
@@ -4269,7 +4304,8 @@
      * @since 9
      */
     public static MethodHandle whileLoop(MethodHandle init, MethodHandle pred, MethodHandle body) {
-        MethodHandle fin = init == null ? zero(void.class) : identity(init.type().returnType());
+        MethodHandle fin = init == null || init.type().returnType() == void.class ? zero(void.class) :
+                identity(init.type().returnType());
         MethodHandle[] checkExit = {null, null, pred, fin};
         MethodHandle[] varBody = {init, body};
         return loop(checkExit, varBody);
@@ -4335,7 +4371,8 @@
      * @since 9
      */
     public static MethodHandle doWhileLoop(MethodHandle init, MethodHandle body, MethodHandle pred) {
-        MethodHandle fin = init == null ? zero(void.class) : identity(init.type().returnType());
+        MethodHandle fin = init == null || init.type().returnType() == void.class ? zero(void.class) :
+                identity(init.type().returnType());
         MethodHandle[] clause = {init, body, pred, fin};
         return loop(clause);
     }
@@ -4472,12 +4509,24 @@
      * @since 9
      */
     public static MethodHandle countedLoop(MethodHandle start, MethodHandle end, MethodHandle init, MethodHandle body) {
-        MethodHandle returnVar = dropArguments(init == null ? zero(void.class) : identity(init.type().returnType()),
-                0, int.class, int.class);
+        Class<?> resultType;
+        MethodHandle actualInit;
+        if (init == null) {
+            resultType = body == null ? void.class : body.type().returnType();
+            actualInit = empty(methodType(resultType));
+        } else {
+            resultType = init.type().returnType();
+            actualInit = init;
+        }
+        MethodHandle defaultResultHandle = resultType == void.class ? zero(void.class) : identity(resultType);
+        MethodHandle actualBody = body == null ? dropArguments(defaultResultHandle, 0, int.class) : body;
+        MethodHandle returnVar = dropArguments(defaultResultHandle, 0, int.class, int.class);
+        MethodHandle actualEnd = end == null ? constant(int.class, 0) : end;
         MethodHandle[] indexVar = {start, MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_countedLoopStep)};
-        MethodHandle[] loopLimit = {end, null, MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_countedLoopPred), returnVar};
-        MethodHandle[] bodyClause = {init,
-                filterArgument(dropArguments(body, 1, int.class), 0,
+        MethodHandle[] loopLimit = {actualEnd, null,
+                MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_countedLoopPred), returnVar};
+        MethodHandle[] bodyClause = {actualInit,
+                filterArgument(dropArguments(actualBody, 1, int.class), 0,
                         MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_decrementCounter))};
         return loop(indexVar, loopLimit, bodyClause);
     }
@@ -4485,6 +4534,7 @@
     /**
      * Constructs a loop that ranges over the elements produced by an {@code Iterator<T>}.
      * The iterator will be produced by the evaluation of the {@code iterator} handle.
+     * This handle must have {@link java.util.Iterator} as its return type.
      * If this handle is passed as {@code null} the method {@link Iterable#iterator} will be used instead,
      * and will be applied to a leading argument of the loop handle.
      * Each value produced by the iterator is passed to the {@code body}, which must accept an initial {@code T} parameter.
@@ -4534,7 +4584,7 @@
      * assertEquals(reversedList, (List<String>) loop.invoke(list));
      * }</pre></blockquote>
      * <p>
-     * @implSpec The implementation of this method is equivalent to:
+     * @implSpec The implementation of this method is equivalent to (excluding error handling):
      * <blockquote><pre>{@code
      * MethodHandle iteratedLoop(MethodHandle iterator, MethodHandle init, MethodHandle body) {
      *     // assume MH_next and MH_hasNext are handles to methods of Iterator
@@ -4550,6 +4600,7 @@
      * }</pre></blockquote>
      *
      * @param iterator a handle to return the iterator to start the loop.
+     *             The handle must have {@link java.util.Iterator} as its return type.
      *             Passing {@code null} will make the loop call {@link Iterable#iterator()} on the first
      *             incoming value.
      * @param init initializer for additional loop state. This determines the loop's result type.
@@ -4565,21 +4616,30 @@
      * @since 9
      */
     public static MethodHandle iteratedLoop(MethodHandle iterator, MethodHandle init, MethodHandle body) {
-        checkIteratedLoop(body);
+        checkIteratedLoop(iterator, body);
+        Class<?> resultType = init == null ?
+                body == null ? void.class : body.type().returnType() :
+                init.type().returnType();
+        boolean voidResult = resultType == void.class;
 
-        MethodHandle initit = MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_initIterator);
-        MethodHandle initIterator = iterator == null ?
-                initit.asType(initit.type().changeParameterType(0, body.type().parameterType(init == null ? 1 : 2))) :
-                iterator;
-        Class<?> itype = initIterator.type().returnType();
+        MethodHandle initIterator;
+        if (iterator == null) {
+            MethodHandle initit = MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_initIterator);
+            initIterator = initit.asType(initit.type().changeParameterType(0,
+                    body.type().parameterType(voidResult ? 1 : 2)));
+        } else {
+            initIterator = iterator.asType(iterator.type().changeReturnType(Iterator.class));
+        }
+
         Class<?> ttype = body.type().parameterType(0);
 
         MethodHandle returnVar =
-                dropArguments(init == null ? zero(void.class) : identity(init.type().returnType()), 0, itype);
+                dropArguments(voidResult ? zero(void.class) : identity(resultType), 0, Iterator.class);
         MethodHandle initnx = MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_iterateNext);
         MethodHandle nextVal = initnx.asType(initnx.type().changeReturnType(ttype));
 
-        MethodHandle[] iterVar = {initIterator, null, MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_iteratePred), returnVar};
+        MethodHandle[] iterVar = {initIterator, null, MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_iteratePred),
+                returnVar};
         MethodHandle[] bodyClause = {init, filterArgument(body, 0, nextVal)};
 
         return loop(iterVar, bodyClause);
@@ -4833,7 +4893,10 @@
         }
     }
 
-    private static void checkIteratedLoop(MethodHandle body) {
+    private static void checkIteratedLoop(MethodHandle iterator, MethodHandle body) {
+        if (null != iterator && !Iterator.class.isAssignableFrom(iterator.type().returnType())) {
+            throw newIllegalArgumentException("iteratedLoop first argument must have Iterator return type");
+        }
         if (null == body) {
             throw newIllegalArgumentException("iterated loop body must not be null");
         }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Thu Apr 28 23:08:16 2016 -0700
@@ -33,7 +33,6 @@
 import jdk.internal.misc.Unsafe;
 
 import java.lang.invoke.MethodHandles.Lookup;
-import java.security.AccessController;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
@@ -124,7 +123,7 @@
      * Concatenation strategy to use. See {@link Strategy} for possible options.
      * This option is controllable with -Djava.lang.invoke.stringConcat JDK option.
      */
-    private static final Strategy STRATEGY;
+    private static Strategy STRATEGY;
 
     /**
      * Default strategy to use for concatenation.
@@ -188,14 +187,25 @@
     private static final ProxyClassesDumper DUMPER;
 
     static {
-        final String strategy = AccessController.doPrivileged(
-                new GetPropertyAction("java.lang.invoke.stringConcat"));
-        CACHE_ENABLE = Boolean.parseBoolean(AccessController.doPrivileged(
-                new GetPropertyAction("java.lang.invoke.stringConcat.cache")));
-        DEBUG = Boolean.parseBoolean(AccessController.doPrivileged(
-                new GetPropertyAction("java.lang.invoke.stringConcat.debug")));
-        final String dumpPath = AccessController.doPrivileged(
-                new GetPropertyAction("java.lang.invoke.stringConcat.dumpClasses"));
+        // In case we need to double-back onto the StringConcatFactory during this
+        // static initialization, make sure we have the reasonable defaults to complete
+        // the static initialization properly. After that, actual users would use the
+        // the proper values we have read from the the properties.
+        STRATEGY = DEFAULT_STRATEGY;
+        // CACHE_ENABLE = false; // implied
+        // CACHE = null;         // implied
+        // DEBUG = false;        // implied
+        // DUMPER = null;        // implied
+
+        Properties props = GetPropertyAction.getProperties();
+        final String strategy =
+                props.getProperty("java.lang.invoke.stringConcat");
+        CACHE_ENABLE = Boolean.parseBoolean(
+                props.getProperty("java.lang.invoke.stringConcat.cache"));
+        DEBUG = Boolean.parseBoolean(
+                props.getProperty("java.lang.invoke.stringConcat.debug"));
+        final String dumpPath =
+                props.getProperty("java.lang.invoke.stringConcat.dumpClasses");
 
         STRATEGY = (strategy == null) ? DEFAULT_STRATEGY : Strategy.valueOf(strategy);
         CACHE = CACHE_ENABLE ? new ConcurrentHashMap<>() : null;
--- a/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Thu Apr 28 23:08:16 2016 -0700
@@ -136,6 +136,7 @@
  * consists of the methods
  * {@link #compareAndSet compareAndSet},
  * {@link #weakCompareAndSet weakCompareAndSet},
+ * {@link #weakCompareAndSetVolatile weakCompareAndSetVolatile},
  * {@link #weakCompareAndSetAcquire weakCompareAndSetAcquire},
  * {@link #weakCompareAndSetRelease weakCompareAndSetRelease},
  * {@link #compareAndExchangeAcquire compareAndExchangeAcquire},
@@ -458,7 +459,7 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code get}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.get)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.GET)} on this VarHandle.
      *
      * <p>This access mode is supported by all VarHandle instances and never
      * throws {@code UnsupportedOperationException}.
@@ -488,7 +489,7 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code set}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.set)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.SET)} on this VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, T newValue)}
@@ -516,7 +517,8 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code getVolatile}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.getVolatile)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.GET_VOLATILE)} on this
+     * VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT)}
@@ -544,7 +546,8 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code setVolatile}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.setVolatile)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.SET_VOLATILE)} on this
+     * VarHandle.
      *
      * @apiNote
      * Ignoring the many semantic differences from C and C++, this method has
@@ -574,7 +577,8 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code getOpaque}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.getOpaque)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.GET_OPAQUE)} on this
+     * VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT)}
@@ -603,7 +607,8 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code setOpaque}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.setOpaque)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.SET_OPAQUE)} on this
+     * VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, T newValue)}
@@ -631,7 +636,8 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code getAcquire}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.getAcquire)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.GET_ACQUIRE)} on this
+     * VarHandle.
      *
      * @apiNote
      * Ignoring the many semantic differences from C and C++, this method has
@@ -664,7 +670,8 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code setRelease}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.setRelease)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.SET_RELEASE)} on this
+     * VarHandle.
      *
      * @apiNote
      * Ignoring the many semantic differences from C and C++, this method has
@@ -700,7 +707,7 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code
      * compareAndSet} must match the access mode type that is the result of
-     * calling {@code accessModeType(VarHandle.AccessMode.compareAndSet)} on
+     * calling {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_SET)} on
      * this VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
@@ -734,7 +741,7 @@
      * <p>The symbolic type descriptor at the call site of {@code
      * compareAndExchangeVolatile}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.compareAndExchangeVolatile)}
+     * {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_VOLATILE)}
      * on this VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
@@ -769,7 +776,7 @@
      * <p>The symbolic type descriptor at the call site of {@code
      * compareAndExchangeAcquire}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.compareAndExchangeAcquire)} on
+     * {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE)} on
      * this VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
@@ -804,7 +811,8 @@
      * <p>The symbolic type descriptor at the call site of {@code
      * compareAndExchangeRelease}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.compareAndExchangeRelease)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE)}
+     * on this VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, T expectedValue, T newValue)}
@@ -836,14 +844,14 @@
      * {@link #get}.
      *
      * <p>This operation may fail spuriously (typically, due to memory
-     * contention) even if the current value does match the expected value.
+     * contention) even if the witness value does match the expected value.
      *
      * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}.
      *
      * <p>The symbolic type descriptor at the call site of {@code
      * weakCompareAndSet} must match the access mode type that is the result of
-     * calling {@code accessModeType(VarHandle.AccessMode.weakCompareAndSet)} on
-     * this VarHandle.
+     * calling {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET)}
+     * on this VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, T expectedValue, T newValue)}
@@ -867,20 +875,58 @@
 
     /**
      * Possibly atomically sets the value of a variable to the {@code newValue}
+     * with the memory semantics of {@link #setVolatile} if the variable's
+     * current value, referred to as the <em>witness value</em>, {@code ==} the
+     * {@code expectedValue}, as accessed with the memory semantics of
+     * {@link #getVolatile}.
+     *
+     * <p>This operation may fail spuriously (typically, due to memory
+     * contention) even if the witness value does match the expected value.
+     *
+     * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}.
+     *
+     * <p>The symbolic type descriptor at the call site of {@code
+     * weakCompareAndSetVolatile} must match the access mode type that is the
+     * result of calling {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE)}
+     * on this VarHandle.
+     *
+     * @param args the signature-polymorphic parameter list of the form
+     * {@code (CT, T expectedValue, T newValue)}
+     * , statically represented using varargs.
+     * @return {@code true} if successful, otherwise {@code false} if the
+     * witness value was not the same as the {@code expectedValue} or if this
+     * operation spuriously failed.
+     * @throws UnsupportedOperationException if the access mode is unsupported
+     * for this VarHandle.
+     * @throws WrongMethodTypeException if the access mode type is not
+     * compatible with the caller's symbolic type descriptor.
+     * @throws ClassCastException if the access mode type is compatible with the
+     * caller's symbolic type descriptor, but a reference cast fails.
+     * @see #setVolatile(Object...)
+     * @see #getVolatile(Object...)
+     */
+    public final native
+    @MethodHandle.PolymorphicSignature
+    @HotSpotIntrinsicCandidate
+    boolean weakCompareAndSetVolatile(Object... args);
+
+    /**
+     * Possibly atomically sets the value of a variable to the {@code newValue}
      * with the semantics of {@link #set} if the variable's current value,
      * referred to as the <em>witness value</em>, {@code ==} the
      * {@code expectedValue}, as accessed with the memory semantics of
      * {@link #getAcquire}.
      *
      * <p>This operation may fail spuriously (typically, due to memory
-     * contention) even if the current value does match the expected value.
+     * contention) even if the witness value does match the expected value.
      *
      * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}.
      *
      * <p>The symbolic type descriptor at the call site of {@code
      * weakCompareAndSetAcquire}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.weakCompareAndSetAcquire)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE)}
+     * on this VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, T expectedValue, T newValue)}
@@ -910,14 +956,15 @@
      * {@link #get}.
      *
      * <p>This operation may fail spuriously (typically, due to memory
-     * contention) even if the current value does match the expected value.
+     * contention) even if the witness value does match the expected value.
      *
      * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}.
      *
      * <p>The symbolic type descriptor at the call site of {@code
      * weakCompareAndSetRelease}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.weakCompareAndSetRelease)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE)}
+     * on this VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, T expectedValue, T newValue)}
@@ -949,7 +996,8 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code getAndSet}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.getAndSet)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.GET_AND_SET)} on this
+     * VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, T newValue)}
@@ -985,7 +1033,8 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code getAndAdd}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.getAndAdd)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.GET_AND_ADD)} on this
+     * VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, T value)}
@@ -1017,7 +1066,8 @@
      *
      * <p>The symbolic type descriptor at the call site of {@code addAndGet}
      * must match the access mode type that is the result of calling
-     * {@code accessModeType(VarHandle.AccessMode.addAndGet)} on this VarHandle.
+     * {@code accessModeType(VarHandle.AccessMode.ADD_AND_GET)} on this
+     * VarHandle.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, T value)}
@@ -1083,109 +1133,115 @@
          * method
          * {@link VarHandle#get VarHandle.get}
          */
-        GET("get", AccessType.GET, Object.class),   // 0
+        GET("get", AccessType.GET, Object.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#set VarHandle.set}
          */
-        SET("set", AccessType.SET, void.class),     // 1
+        SET("set", AccessType.SET, void.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getVolatile VarHandle.getVolatile}
          */
-        GET_VOLATILE("getVolatile", AccessType.GET, Object.class),  // 2
+        GET_VOLATILE("getVolatile", AccessType.GET, Object.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#setVolatile VarHandle.setVolatile}
          */
-        SET_VOLATILE("setVolatile", AccessType.SET, void.class),    // 3
+        SET_VOLATILE("setVolatile", AccessType.SET, void.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getAcquire VarHandle.getAcquire}
          */
-        GET_ACQUIRE("getAcquire", AccessType.GET, Object.class),   // 4
+        GET_ACQUIRE("getAcquire", AccessType.GET, Object.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#setRelease VarHandle.setRelease}
          */
-        SET_RELEASE("setRelease", AccessType.SET, void.class),     // 5
+        SET_RELEASE("setRelease", AccessType.SET, void.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getOpaque VarHandle.getOpaque}
          */
-        GET_OPAQUE("getOpaque", AccessType.GET, Object.class),    // 6
+        GET_OPAQUE("getOpaque", AccessType.GET, Object.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#setOpaque VarHandle.setOpaque}
          */
-        SET_OPAQUE("setOpaque", AccessType.SET, void.class),      // 7
+        SET_OPAQUE("setOpaque", AccessType.SET, void.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#compareAndSet VarHandle.compareAndSet}
          */
-        COMPARE_AND_SET("compareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class),    // 8
+        COMPARE_AND_SET("compareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#compareAndExchangeVolatile VarHandle.compareAndExchangeVolatile}
          */
-        COMPARE_AND_EXCHANGE_VOLATILE("compareAndExchangeVolatile", AccessType.COMPARE_AND_EXCHANGE, Object.class), // 9
+        COMPARE_AND_EXCHANGE_VOLATILE("compareAndExchangeVolatile", AccessType.COMPARE_AND_EXCHANGE, Object.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#compareAndExchangeAcquire VarHandle.compareAndExchangeAcquire}
          */
-        COMPARE_AND_EXCHANGE_ACQUIRE("compareAndExchangeAcquire", AccessType.COMPARE_AND_EXCHANGE, Object.class),  // 10
+        COMPARE_AND_EXCHANGE_ACQUIRE("compareAndExchangeAcquire", AccessType.COMPARE_AND_EXCHANGE, Object.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#compareAndExchangeRelease VarHandle.compareAndExchangeRelease}
          */
-        COMPARE_AND_EXCHANGE_RELEASE("compareAndExchangeRelease", AccessType.COMPARE_AND_EXCHANGE, Object.class),  // 11
+        COMPARE_AND_EXCHANGE_RELEASE("compareAndExchangeRelease", AccessType.COMPARE_AND_EXCHANGE, Object.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#weakCompareAndSet VarHandle.weakCompareAndSet}
          */
-        WEAK_COMPARE_AND_SET("weakCompareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class),        // 12
+        WEAK_COMPARE_AND_SET("weakCompareAndSet", AccessType.COMPARE_AND_SWAP, boolean.class),
+        /**
+         * The access mode whose access is specified by the corresponding
+         * method
+         * {@link VarHandle#weakCompareAndSetVolatile VarHandle.weakCompareAndSetVolatile}
+         */
+        WEAK_COMPARE_AND_SET_VOLATILE("weakCompareAndSetVolatile", AccessType.COMPARE_AND_SWAP, boolean.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#weakCompareAndSetAcquire VarHandle.weakCompareAndSetAcquire}
          */
-        WEAK_COMPARE_AND_SET_ACQUIRE("weakCompareAndSetAcquire", AccessType.COMPARE_AND_SWAP, boolean.class), // 13
+        WEAK_COMPARE_AND_SET_ACQUIRE("weakCompareAndSetAcquire", AccessType.COMPARE_AND_SWAP, boolean.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#weakCompareAndSetRelease VarHandle.weakCompareAndSetRelease}
          */
-        WEAK_COMPARE_AND_SET_RELEASE("weakCompareAndSetRelease", AccessType.COMPARE_AND_SWAP, boolean.class), // 14
+        WEAK_COMPARE_AND_SET_RELEASE("weakCompareAndSetRelease", AccessType.COMPARE_AND_SWAP, boolean.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getAndSet VarHandle.getAndSet}
          */
-        GET_AND_SET("getAndSet", AccessType.GET_AND_UPDATE, Object.class),   // 15
+        GET_AND_SET("getAndSet", AccessType.GET_AND_UPDATE, Object.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#getAndAdd VarHandle.getAndAdd}
          */
-        GET_AND_ADD("getAndAdd", AccessType.GET_AND_UPDATE, Object.class),   // 16
+        GET_AND_ADD("getAndAdd", AccessType.GET_AND_UPDATE, Object.class),
         /**
          * The access mode whose access is specified by the corresponding
          * method
          * {@link VarHandle#addAndGet VarHandle.addAndGet}
          */
-        ADD_AND_GET("addAndGet", AccessType.GET_AND_UPDATE, Object.class),   // 17
+        ADD_AND_GET("addAndGet", AccessType.GET_AND_UPDATE, Object.class),
         ;
 
         static final Map<String, AccessMode> methodNameToAccessMode;
--- a/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template	Thu Apr 28 23:08:16 2016 -0700
@@ -155,6 +155,15 @@
         }
 
         @ForceInline
+        static boolean weakCompareAndSetVolatile(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
+            // TODO defer to strong form until new Unsafe method is added
+            return UNSAFE.compareAndSwap$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
+                                               handle.fieldOffset,
+                                               {#if[Object]?handle.fieldType.cast(expected):expected},
+                                               {#if[Object]?handle.fieldType.cast(value):value});
+        }
+
+        @ForceInline
         static boolean weakCompareAndSetAcquire(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
             return UNSAFE.weakCompareAndSwap$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
                                                handle.fieldOffset,
@@ -319,6 +328,15 @@
         }
 
         @ForceInline
+        static boolean weakCompareAndSetVolatile(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
+            // TODO defer to strong form until new Unsafe method is added
+            return UNSAFE.compareAndSwap$Type$(handle.base,
+                                               handle.fieldOffset,
+                                               {#if[Object]?handle.fieldType.cast(expected):expected},
+                                               {#if[Object]?handle.fieldType.cast(value):value});
+        }
+
+        @ForceInline
         static boolean weakCompareAndSetAcquire(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
             return UNSAFE.weakCompareAndSwap$Type$Acquire(handle.base,
                                                handle.fieldOffset,
@@ -535,6 +553,20 @@
         }
 
         @ForceInline
+        static boolean weakCompareAndSetVolatile(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
+#if[Object]
+            Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+            $type$[] array = ($type$[]) oarray;
+#end[Object]
+            // TODO defer to strong form until new Unsafe method is added
+            return UNSAFE.compareAndSwap$Type$(array,
+                    (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+                    {#if[Object]?handle.componentType.cast(expected):expected},
+                    {#if[Object]?handle.componentType.cast(value):value});
+        }
+
+        @ForceInline
         static boolean weakCompareAndSetAcquire(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
 #if[Object]
             Object[] array = (Object[]) handle.arrayType.cast(oarray);
--- a/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template	Thu Apr 28 23:08:16 2016 -0700
@@ -228,6 +228,16 @@
         }
 
         @ForceInline
+        static boolean weakCompareAndSetVolatile(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
+            byte[] ba = (byte[]) oba;
+            // TODO defer to strong form until new Unsafe method is added
+            return UNSAFE.compareAndSwap$RawType$(
+                    ba,
+                    address(ba, index(ba, index)),
+                    convEndian(handle.be, expected), convEndian(handle.be, value));
+        }
+
+        @ForceInline
         static boolean weakCompareAndSetAcquire(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
             byte[] ba = (byte[]) oba;
             return UNSAFE.weakCompareAndSwap$RawType$Acquire(
@@ -444,6 +454,16 @@
         }
 
         @ForceInline
+        static boolean weakCompareAndSetVolatile(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
+            ByteBuffer bb = (ByteBuffer) obb;
+            // TODO defer to strong form until new Unsafe method is added
+            return UNSAFE.compareAndSwap$RawType$(
+                    UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+                    address(bb, indexRO(bb, index)),
+                    convEndian(handle.be, expected), convEndian(handle.be, value));
+        }
+
+        @ForceInline
         static boolean weakCompareAndSetAcquire(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
             ByteBuffer bb = (ByteBuffer) obb;
             return UNSAFE.weakCompareAndSwap$RawType$Acquire(
--- a/jdk/src/java.base/share/classes/java/lang/module/ModuleFinder.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleFinder.java	Thu Apr 28 23:08:16 2016 -0700
@@ -39,6 +39,7 @@
 import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
+import sun.security.action.GetPropertyAction;
 
 /**
  * A finder of modules. A {@code ModuleFinder} is used to find modules during
@@ -152,7 +153,7 @@
 
         SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
-            PrivilegedAction<String> pa = () -> System.getProperty("java.home");
+            PrivilegedAction<String> pa = new GetPropertyAction("java.home");
             home = AccessController.doPrivileged(pa);
             Permission p = new FilePermission(home + File.separator + "-", "read");
             sm.checkPermission(p);
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java	Thu Apr 28 23:08:16 2016 -0700
@@ -50,6 +50,7 @@
 import jdk.internal.reflect.CallerSensitive;
 import jdk.internal.reflect.Reflection;
 import sun.reflect.misc.ReflectUtil;
+import sun.security.action.GetPropertyAction;
 import sun.security.util.SecurityConstants;
 
 /**
@@ -581,11 +582,7 @@
         }
 
         private static final String DEBUG =
-            AccessController.doPrivileged(new PrivilegedAction<>() {
-                public String run() {
-                    return System.getProperty("jdk.proxy.debug", "");
-                }
-            });
+                GetPropertyAction.getProperty("jdk.proxy.debug", "");
 
         private static boolean isDebug() {
             return !DEBUG.isEmpty();
--- a/jdk/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1750,7 +1750,7 @@
          * Get or assign the index for a CONSTANT_Float entry.
          */
         public short getFloat(float f) {
-            return getValue(new Float(f));
+            return getValue(f);
         }
 
         /**
--- a/jdk/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -31,6 +31,7 @@
 import java.util.Set;
 import java.util.HashSet;
 import java.util.Collections;
+import sun.security.action.GetPropertyAction;
 
 /**
  * Abstract datagram and multicast socket implementation base class.
@@ -51,9 +52,7 @@
     protected InetAddress connectedAddress = null;
     private int connectedPort = -1;
 
-    private static final String os = AccessController.doPrivileged(
-        new sun.security.action.GetPropertyAction("os.name")
-    );
+    private static final String os = GetPropertyAction.getProperty("os.name");
 
     /**
      * flag set if the native connect() call not to be used
--- a/jdk/src/java.base/share/classes/java/net/InetAddress.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/net/InetAddress.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1123,8 +1123,8 @@
      */
     private static NameService createNameService() {
 
-        String hostsFileName = AccessController
-                .doPrivileged(new GetPropertyAction("jdk.net.hosts.file"));
+        String hostsFileName =
+                GetPropertyAction.getProperty("jdk.net.hosts.file");
         NameService theNameService;
         if (hostsFileName != null) {
             theNameService = new HostsFileNameService(hostsFileName);
@@ -1643,8 +1643,7 @@
          * property can vary across implementations of the java.
          * classes.  The default is an empty String "".
          */
-        String prefix = AccessController.doPrivileged(
-                      new GetPropertyAction("impl.prefix", ""));
+        String prefix = GetPropertyAction.getProperty("impl.prefix", "");
         try {
             impl = Class.forName("java.net." + prefix + implName).newInstance();
         } catch (ClassNotFoundException e) {
--- a/jdk/src/java.base/share/classes/java/net/SocksSocketImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/net/SocksSocketImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -33,6 +33,7 @@
 import sun.net.SocksProxy;
 import sun.net.spi.DefaultProxySelector;
 import sun.net.www.ParseUtil;
+import sun.security.action.GetPropertyAction;
 /* import org.ietf.jgss.*; */
 
 /**
@@ -177,8 +178,7 @@
                 userName = pw.getUserName();
                 password = new String(pw.getPassword());
             } else {
-                userName = java.security.AccessController.doPrivileged(
-                        new sun.security.action.GetPropertyAction("user.name"));
+                userName = GetPropertyAction.getProperty("user.name");
             }
             if (userName == null)
                 return false;
@@ -1088,8 +1088,7 @@
                 userName = System.getProperty("user.name");
             } catch (SecurityException se) { /* swallow Exception */ }
         } else {
-            userName = java.security.AccessController.doPrivileged(
-                new sun.security.action.GetPropertyAction("user.name"));
+            userName = GetPropertyAction.getProperty("user.name");
         }
         return userName;
     }
--- a/jdk/src/java.base/share/classes/java/net/URL.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/net/URL.java	Thu Apr 28 23:08:16 2016 -0700
@@ -42,6 +42,7 @@
 import java.util.ServiceLoader;
 
 import sun.security.util.SecurityConstants;
+import sun.security.action.GetPropertyAction;
 
 /**
  * Class {@code URL} represents a Uniform Resource
@@ -1210,12 +1211,8 @@
     }
 
     private static URLStreamHandler lookupViaProperty(String protocol) {
-        String packagePrefixList = java.security.AccessController.doPrivileged(
-                new PrivilegedAction<>() {
-                    public String run() {
-                        return System.getProperty(protocolPathProp, null);
-                    }
-                });
+        String packagePrefixList =
+                GetPropertyAction.getProperty(protocolPathProp);
         if (packagePrefixList == null) {
             // not set
             return null;
--- a/jdk/src/java.base/share/classes/java/net/URLConnection.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/net/URLConnection.java	Thu Apr 28 23:08:16 2016 -0700
@@ -43,6 +43,7 @@
 import java.security.AccessController;
 import sun.security.util.SecurityConstants;
 import sun.net.www.MessageHeader;
+import sun.security.action.GetPropertyAction;
 
 /**
  * The abstract class {@code URLConnection} is the superclass
@@ -1395,8 +1396,8 @@
      * is always the last one on the returned package list.
      */
     private String getContentHandlerPkgPrefixes() {
-        String packagePrefixList = AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction(contentPathProp, ""));
+        String packagePrefixList =
+                GetPropertyAction.getProperty(contentPathProp, "");
 
         if (packagePrefixList != "") {
             packagePrefixList += "|";
--- a/jdk/src/java.base/share/classes/java/net/URLEncoder.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/net/URLEncoder.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,19 +25,12 @@
 
 package java.net;
 
-import java.io.ByteArrayOutputStream;
-import java.io.BufferedWriter;
-import java.io.OutputStreamWriter;
-import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.io.CharArrayWriter;
 import java.nio.charset.Charset;
 import java.nio.charset.IllegalCharsetNameException;
 import java.nio.charset.UnsupportedCharsetException ;
 import java.util.BitSet;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import sun.security.action.GetBooleanAction;
 import sun.security.action.GetPropertyAction;
 
 /**
@@ -140,9 +133,7 @@
         dontNeedEncoding.set('.');
         dontNeedEncoding.set('*');
 
-        dfltEncName = AccessController.doPrivileged(
-            new GetPropertyAction("file.encoding")
-        );
+        dfltEncName = GetPropertyAction.getProperty("file.encoding");
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/net/URLPermission.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/net/URLPermission.java	Thu Apr 28 23:08:16 2016 -0700
@@ -170,7 +170,8 @@
         parseURI(getName());
         int colon = actions.indexOf(':');
         if (actions.lastIndexOf(':') != colon) {
-            throw new IllegalArgumentException("invalid actions string");
+            throw new IllegalArgumentException(
+                "Invalid actions string: \"" + actions + "\"");
         }
 
         String methods, headers;
@@ -371,7 +372,8 @@
                     l.add(s);
                 b = new StringBuilder();
             } else if (c == ' ' || c == '\t') {
-                throw new IllegalArgumentException("white space not allowed");
+                throw new IllegalArgumentException(
+                    "White space not allowed in methods: \"" + methods + "\"");
             } else {
                 if (c >= 'a' && c <= 'z') {
                     c += 'A' - 'a';
@@ -398,7 +400,8 @@
                 }
                 b.append(c);
             } else if (c == ' ' || c == '\t') {
-                throw new IllegalArgumentException("white space not allowed");
+                throw new IllegalArgumentException(
+                    "White space not allowed in headers: \"" + headers + "\"");
             } else if (c == '-') {
                     capitalizeNext = true;
                 b.append(c);
@@ -423,14 +426,16 @@
         int len = url.length();
         int delim = url.indexOf(':');
         if (delim == -1 || delim + 1 == len) {
-            throw new IllegalArgumentException("invalid URL string");
+            throw new IllegalArgumentException(
+                "Invalid URL string: \"" + url + "\"");
         }
         scheme = url.substring(0, delim).toLowerCase();
         this.ssp = url.substring(delim + 1);
 
         if (!ssp.startsWith("//")) {
             if (!ssp.equals("*")) {
-                throw new IllegalArgumentException("invalid URL string");
+                throw new IllegalArgumentException(
+                    "Invalid URL string: \"" + url + "\"");
             }
             this.authority = new Authority(scheme, "*");
             return;
--- a/jdk/src/java.base/share/classes/java/nio/charset/Charset.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/nio/charset/Charset.java	Thu Apr 28 23:08:16 2016 -0700
@@ -283,8 +283,8 @@
         if (level == null) {
             if (!VM.isBooted())
                 return false;
-            bugLevel = level = AccessController.doPrivileged(
-                new GetPropertyAction("sun.nio.cs.bugLevel", ""));
+            bugLevel = level =
+                    GetPropertyAction.getProperty("sun.nio.cs.bugLevel", "");
         }
         return level.equals(bl);
     }
@@ -609,8 +609,7 @@
     public static Charset defaultCharset() {
         if (defaultCharset == null) {
             synchronized (Charset.class) {
-                String csn = AccessController.doPrivileged(
-                    new GetPropertyAction("file.encoding"));
+                String csn = GetPropertyAction.getProperty("file.encoding");
                 Charset cs = lookup(csn);
                 if (cs != null)
                     defaultCharset = cs;
--- a/jdk/src/java.base/share/classes/java/nio/file/TempFileHelper.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/nio/file/TempFileHelper.java	Thu Apr 28 23:08:16 2016 -0700
@@ -28,7 +28,6 @@
 import java.util.Set;
 import java.util.EnumSet;
 import java.security.SecureRandom;
-import static java.security.AccessController.*;
 import java.io.IOException;
 import java.nio.file.attribute.FileAttribute;
 import java.nio.file.attribute.PosixFilePermission;
@@ -47,7 +46,7 @@
 
     // temporary directory location
     private static final Path tmpdir =
-        Paths.get(doPrivileged(new GetPropertyAction("java.io.tmpdir")));
+        Paths.get(GetPropertyAction.getProperty("java.io.tmpdir"));
 
     private static final boolean isPosix =
         FileSystems.getDefault().supportedFileAttributeViews().contains("posix");
--- a/jdk/src/java.base/share/classes/java/text/ChoiceFormat.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/text/ChoiceFormat.java	Thu Apr 28 23:08:16 2016 -0700
@@ -437,7 +437,7 @@
         if (status.index == start) {
             status.errorIndex = furthest;
         }
-        return new Double(bestNumber);
+        return Double.valueOf(bestNumber);
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/text/DecimalFormat.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/text/DecimalFormat.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1996,7 +1996,7 @@
         // special case NaN
         if (text.regionMatches(pos.index, symbols.getNaN(), 0, symbols.getNaN().length())) {
             pos.index = pos.index + symbols.getNaN().length();
-            return new Double(Double.NaN);
+            return Double.valueOf(Double.NaN);
         }
 
         boolean[] status = new boolean[STATUS_LENGTH];
@@ -2007,19 +2007,19 @@
         // special case INFINITY
         if (status[STATUS_INFINITE]) {
             if (status[STATUS_POSITIVE] == (multiplier >= 0)) {
-                return new Double(Double.POSITIVE_INFINITY);
+                return Double.valueOf(Double.POSITIVE_INFINITY);
             } else {
-                return new Double(Double.NEGATIVE_INFINITY);
+                return Double.valueOf(Double.NEGATIVE_INFINITY);
             }
         }
 
         if (multiplier == 0) {
             if (digitList.isZero()) {
-                return new Double(Double.NaN);
+                return Double.valueOf(Double.NaN);
             } else if (status[STATUS_POSITIVE]) {
-                return new Double(Double.POSITIVE_INFINITY);
+                return Double.valueOf(Double.POSITIVE_INFINITY);
             } else {
-                return new Double(Double.NEGATIVE_INFINITY);
+                return Double.valueOf(Double.NEGATIVE_INFINITY);
             }
         }
 
@@ -2093,8 +2093,8 @@
                             !isParseIntegerOnly();
             }
 
-            return gotDouble ?
-                (Number)new Double(doubleResult) : (Number)Long.valueOf(longResult);
+            // cast inside of ?: because of binary numeric promotion, JLS 15.25
+            return gotDouble ? (Number)doubleResult : (Number)longResult;
         }
     }
 
--- a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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
@@ -284,6 +284,7 @@
  *   D       day-of-year                 number            189
  *   M/L     month-of-year               number/text       7; 07; Jul; July; J
  *   d       day-of-month                number            10
+ *   g       modified-julian-day         number            2451334
  *
  *   Q/q     quarter-of-year             number/text       3; 03; Q3; 3rd quarter
  *   Y       week-based-year             year              1996; 96
@@ -308,10 +309,10 @@
  *
  *   V       time-zone ID                zone-id           America/Los_Angeles; Z; -08:30
  *   z       time-zone name              zone-name         Pacific Standard Time; PST
- *   O       localized zone-offset       offset-O          GMT+8; GMT+08:00; UTC-08:00;
- *   X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15;
- *   x       zone-offset                 offset-x          +0000; -08; -0830; -08:30; -083015; -08:30:15;
- *   Z       zone-offset                 offset-Z          +0000; -0800; -08:00;
+ *   O       localized zone-offset       offset-O          GMT+8; GMT+08:00; UTC-08:00
+ *   X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15
+ *   x       zone-offset                 offset-x          +0000; -08; -0830; -08:30; -083015; -08:30:15
+ *   Z       zone-offset                 offset-Z          +0000; -0800; -08:00
  *
  *   p       pad next                    pad modifier      1
  *
--- a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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
@@ -90,6 +90,7 @@
 import java.time.format.DateTimeTextProvider.LocaleStore;
 import java.time.temporal.ChronoField;
 import java.time.temporal.IsoFields;
+import java.time.temporal.JulianFields;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalField;
 import java.time.temporal.TemporalQueries;
@@ -666,8 +667,11 @@
      * No rounding occurs due to the maximum width - digits are simply dropped.
      * <p>
      * When parsing in strict mode, the number of parsed digits must be between
-     * the minimum and maximum width. When parsing in lenient mode, the minimum
-     * width is considered to be zero and the maximum is nine.
+     * the minimum and maximum width. In strict mode, if the minimum and maximum widths
+     * are equal and there is no decimal point then the parser will
+     * participate in adjacent value parsing, see
+     * {@link appendValue(java.time.temporal.TemporalField, int)}. When parsing in lenient mode,
+     * the minimum width is considered to be zero and the maximum is nine.
      * <p>
      * If the value cannot be obtained then an exception will be thrown.
      * If the value is negative an exception will be thrown.
@@ -686,7 +690,12 @@
      */
     public DateTimeFormatterBuilder appendFraction(
             TemporalField field, int minWidth, int maxWidth, boolean decimalPoint) {
-        appendInternal(new FractionPrinterParser(field, minWidth, maxWidth, decimalPoint));
+        if (minWidth == maxWidth && decimalPoint == false) {
+            // adjacent parsing
+            appendValue(new FractionPrinterParser(field, minWidth, maxWidth, decimalPoint));
+        } else {
+            appendInternal(new FractionPrinterParser(field, minWidth, maxWidth, decimalPoint));
+        }
         return this;
     }
 
@@ -1383,6 +1392,7 @@
      *   D       day-of-year                 number            189
      *   M/L     month-of-year               number/text       7; 07; Jul; July; J
      *   d       day-of-month                number            10
+     *   g       modified-julian-day         number            2451334
      *
      *   Q/q     quarter-of-year             number/text       3; 03; Q3; 3rd quarter
      *   Y       week-based-year             year              1996; 96
@@ -1408,9 +1418,9 @@
      *   V       time-zone ID                zone-id           America/Los_Angeles; Z; -08:30
      *   z       time-zone name              zone-name         Pacific Standard Time; PST
      *   O       localized zone-offset       offset-O          GMT+8; GMT+08:00; UTC-08:00;
-     *   X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15;
-     *   x       zone-offset                 offset-x          +0000; -08; -0830; -08:30; -083015; -08:30:15;
-     *   Z       zone-offset                 offset-Z          +0000; -0800; -08:00;
+     *   X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15
+     *   x       zone-offset                 offset-x          +0000; -08; -0830; -08:30; -083015; -08:30:15
+     *   Z       zone-offset                 offset-Z          +0000; -0800; -08:00
      *
      *   p       pad next                    pad modifier      1
      *
@@ -1437,37 +1447,37 @@
      *    GGGG    4      appendText(ChronoField.ERA, TextStyle.FULL)
      *    GGGGG   5      appendText(ChronoField.ERA, TextStyle.NARROW)
      *
-     *    u       1      appendValue(ChronoField.YEAR, 1, 19, SignStyle.NORMAL);
-     *    uu      2      appendValueReduced(ChronoField.YEAR, 2, 2000);
-     *    uuu     3      appendValue(ChronoField.YEAR, 3, 19, SignStyle.NORMAL);
-     *    u..u    4..n   appendValue(ChronoField.YEAR, n, 19, SignStyle.EXCEEDS_PAD);
-     *    y       1      appendValue(ChronoField.YEAR_OF_ERA, 1, 19, SignStyle.NORMAL);
-     *    yy      2      appendValueReduced(ChronoField.YEAR_OF_ERA, 2, 2000);
-     *    yyy     3      appendValue(ChronoField.YEAR_OF_ERA, 3, 19, SignStyle.NORMAL);
-     *    y..y    4..n   appendValue(ChronoField.YEAR_OF_ERA, n, 19, SignStyle.EXCEEDS_PAD);
+     *    u       1      appendValue(ChronoField.YEAR, 1, 19, SignStyle.NORMAL)
+     *    uu      2      appendValueReduced(ChronoField.YEAR, 2, 2000)
+     *    uuu     3      appendValue(ChronoField.YEAR, 3, 19, SignStyle.NORMAL)
+     *    u..u    4..n   appendValue(ChronoField.YEAR, n, 19, SignStyle.EXCEEDS_PAD)
+     *    y       1      appendValue(ChronoField.YEAR_OF_ERA, 1, 19, SignStyle.NORMAL)
+     *    yy      2      appendValueReduced(ChronoField.YEAR_OF_ERA, 2, 2000)
+     *    yyy     3      appendValue(ChronoField.YEAR_OF_ERA, 3, 19, SignStyle.NORMAL)
+     *    y..y    4..n   appendValue(ChronoField.YEAR_OF_ERA, n, 19, SignStyle.EXCEEDS_PAD)
      *    Y       1      append special localized WeekFields element for numeric week-based-year
-     *    YY      2      append special localized WeekFields element for reduced numeric week-based-year 2 digits;
-     *    YYY     3      append special localized WeekFields element for numeric week-based-year (3, 19, SignStyle.NORMAL);
-     *    Y..Y    4..n   append special localized WeekFields element for numeric week-based-year (n, 19, SignStyle.EXCEEDS_PAD);
+     *    YY      2      append special localized WeekFields element for reduced numeric week-based-year 2 digits
+     *    YYY     3      append special localized WeekFields element for numeric week-based-year (3, 19, SignStyle.NORMAL)
+     *    Y..Y    4..n   append special localized WeekFields element for numeric week-based-year (n, 19, SignStyle.EXCEEDS_PAD)
      *
-     *    Q       1      appendValue(IsoFields.QUARTER_OF_YEAR);
-     *    QQ      2      appendValue(IsoFields.QUARTER_OF_YEAR, 2);
+     *    Q       1      appendValue(IsoFields.QUARTER_OF_YEAR)
+     *    QQ      2      appendValue(IsoFields.QUARTER_OF_YEAR, 2)
      *    QQQ     3      appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.SHORT)
      *    QQQQ    4      appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.FULL)
      *    QQQQQ   5      appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.NARROW)
-     *    q       1      appendValue(IsoFields.QUARTER_OF_YEAR);
-     *    qq      2      appendValue(IsoFields.QUARTER_OF_YEAR, 2);
+     *    q       1      appendValue(IsoFields.QUARTER_OF_YEAR)
+     *    qq      2      appendValue(IsoFields.QUARTER_OF_YEAR, 2)
      *    qqq     3      appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.SHORT_STANDALONE)
      *    qqqq    4      appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.FULL_STANDALONE)
      *    qqqqq   5      appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.NARROW_STANDALONE)
      *
-     *    M       1      appendValue(ChronoField.MONTH_OF_YEAR);
-     *    MM      2      appendValue(ChronoField.MONTH_OF_YEAR, 2);
+     *    M       1      appendValue(ChronoField.MONTH_OF_YEAR)
+     *    MM      2      appendValue(ChronoField.MONTH_OF_YEAR, 2)
      *    MMM     3      appendText(ChronoField.MONTH_OF_YEAR, TextStyle.SHORT)
      *    MMMM    4      appendText(ChronoField.MONTH_OF_YEAR, TextStyle.FULL)
      *    MMMMM   5      appendText(ChronoField.MONTH_OF_YEAR, TextStyle.NARROW)
-     *    L       1      appendValue(ChronoField.MONTH_OF_YEAR);
-     *    LL      2      appendValue(ChronoField.MONTH_OF_YEAR, 2);
+     *    L       1      appendValue(ChronoField.MONTH_OF_YEAR)
+     *    LL      2      appendValue(ChronoField.MONTH_OF_YEAR, 2)
      *    LLL     3      appendText(ChronoField.MONTH_OF_YEAR, TextStyle.SHORT_STANDALONE)
      *    LLLL    4      appendText(ChronoField.MONTH_OF_YEAR, TextStyle.FULL_STANDALONE)
      *    LLLLL   5      appendText(ChronoField.MONTH_OF_YEAR, TextStyle.NARROW_STANDALONE)
@@ -1481,6 +1491,7 @@
      *    DD      2      appendValue(ChronoField.DAY_OF_YEAR, 2)
      *    DDD     3      appendValue(ChronoField.DAY_OF_YEAR, 3)
      *    F       1      appendValue(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH)
+     *    g..g    1..n   appendValue(JulianFields.MODIFIED_JULIAN_DAY, n, 19, SignStyle.NORMAL)
      *    E       1      appendText(ChronoField.DAY_OF_WEEK, TextStyle.SHORT)
      *    EE      2      appendText(ChronoField.DAY_OF_WEEK, TextStyle.SHORT)
      *    EEE     3      appendText(ChronoField.DAY_OF_WEEK, TextStyle.SHORT)
@@ -1539,8 +1550,8 @@
      * <pre>
      *  Pattern  Count  Equivalent builder methods
      *  -------  -----  --------------------------
-     *    O       1      appendLocalizedOffsetPrefixed(TextStyle.SHORT);
-     *    OOOO    4      appendLocalizedOffsetPrefixed(TextStyle.FULL);
+     *    O       1      appendLocalizedOffset(TextStyle.SHORT)
+     *    OOOO    4      appendLocalizedOffset(TextStyle.FULL)
      *    X       1      appendOffset("+HHmm","Z")
      *    XX      2      appendOffset("+HHMM","Z")
      *    XXX     3      appendOffset("+HH:MM","Z")
@@ -1554,7 +1565,7 @@
      *    Z       1      appendOffset("+HHMM","+0000")
      *    ZZ      2      appendOffset("+HHMM","+0000")
      *    ZZZ     3      appendOffset("+HHMM","+0000")
-     *    ZZZZ    4      appendLocalizedOffset(TextStyle.FULL);
+     *    ZZZZ    4      appendLocalizedOffset(TextStyle.FULL)
      *    ZZZZZ   5      appendOffset("+HH:MM:ss","Z")
      * </pre>
      * <p>
@@ -1836,6 +1847,9 @@
                     throw new IllegalArgumentException("Too many pattern letters: " + cur);
                 }
                 break;
+            case 'g':
+                appendValue(field, count, 19, SignStyle.NORMAL);
+                break;
             default:
                 if (count == 1) {
                     appendValue(field);
@@ -1874,6 +1888,7 @@
         FIELD_MAP.put('A', ChronoField.MILLI_OF_DAY);              // LDML
         FIELD_MAP.put('n', ChronoField.NANO_OF_SECOND);            // 310 (proposed for LDML)
         FIELD_MAP.put('N', ChronoField.NANO_OF_DAY);               // 310 (proposed for LDML)
+        FIELD_MAP.put('g', JulianFields.MODIFIED_JULIAN_DAY);
         // 310 - z - time-zone names, matches LDML and SimpleDateFormat 1 to 4
         // 310 - Z - matches SimpleDateFormat and LDML
         // 310 - V - time-zone id, matches LDML
@@ -1884,7 +1899,6 @@
         // LDML - U - cycle year name, not supported by 310 yet
         // LDML - l - deprecated
         // LDML - j - not relevant
-        // LDML - g - modified-julian-day
         // LDML - v,V - extended time-zone names
     }
 
@@ -2919,11 +2933,8 @@
     /**
      * Prints and parses a numeric date-time field with optional padding.
      */
-    static final class FractionPrinterParser implements DateTimePrinterParser {
-        private final TemporalField field;
-        private final int minWidth;
-        private final int maxWidth;
-        private final boolean decimalPoint;
+    static final class FractionPrinterParser extends NumberPrinterParser {
+       private final boolean decimalPoint;
 
         /**
          * Constructor.
@@ -2934,6 +2945,7 @@
          * @param decimalPoint  whether to output the localized decimal point symbol
          */
         FractionPrinterParser(TemporalField field, int minWidth, int maxWidth, boolean decimalPoint) {
+            this(field, minWidth, maxWidth, decimalPoint, 0);
             Objects.requireNonNull(field, "field");
             if (field.range().isFixed() == false) {
                 throw new IllegalArgumentException("Field must have a fixed set of values: " + field);
@@ -2948,12 +2960,61 @@
                 throw new IllegalArgumentException("Maximum width must exceed or equal the minimum width but " +
                         maxWidth + " < " + minWidth);
             }
-            this.field = field;
-            this.minWidth = minWidth;
-            this.maxWidth = maxWidth;
+        }
+
+        /**
+         * Constructor.
+         *
+         * @param field  the field to output, not null
+         * @param minWidth  the minimum width to output, from 0 to 9
+         * @param maxWidth  the maximum width to output, from 0 to 9
+         * @param decimalPoint  whether to output the localized decimal point symbol
+         * @param subsequentWidth the subsequentWidth for this instance
+         */
+        FractionPrinterParser(TemporalField field, int minWidth, int maxWidth, boolean decimalPoint, int subsequentWidth) {
+            super(field, minWidth, maxWidth, SignStyle.NOT_NEGATIVE, subsequentWidth);
             this.decimalPoint = decimalPoint;
         }
 
+        /**
+         * Returns a new instance with fixed width flag set.
+         *
+         * @return a new updated printer-parser, not null
+         */
+        @Override
+        FractionPrinterParser withFixedWidth() {
+            if (subsequentWidth == -1) {
+                return this;
+            }
+            return new FractionPrinterParser(field, minWidth, maxWidth, decimalPoint, -1);
+        }
+
+        /**
+         * Returns a new instance with an updated subsequent width.
+         *
+         * @param subsequentWidth  the width of subsequent non-negative numbers, 0 or greater
+         * @return a new updated printer-parser, not null
+         */
+        @Override
+        FractionPrinterParser withSubsequentWidth(int subsequentWidth) {
+            return new FractionPrinterParser(field, minWidth, maxWidth, decimalPoint, this.subsequentWidth + subsequentWidth);
+        }
+
+        /**
+         * For FractionPrinterPrinterParser, the width is fixed if context is sttrict,
+         * minWidth equal to maxWidth and decimalpoint is absent.
+         * @param context the context
+         * @return if the field is fixed width
+         * @see DateTimeFormatterBuilder#appendValueFraction(java.time.temporal.TemporalField, int, int, boolean)
+         */
+        @Override
+        boolean isFixedWidth(DateTimeParseContext context) {
+            if (context.isStrict() && minWidth == maxWidth && decimalPoint == false) {
+                return true;
+            }
+            return false;
+        }
+
         @Override
         public boolean format(DateTimePrintContext context, StringBuilder buf) {
             Long value = context.getValue(field);
@@ -2986,8 +3047,8 @@
 
         @Override
         public int parse(DateTimeParseContext context, CharSequence text, int position) {
-            int effectiveMin = (context.isStrict() ? minWidth : 0);
-            int effectiveMax = (context.isStrict() ? maxWidth : 9);
+            int effectiveMin = (context.isStrict() || isFixedWidth(context) ? minWidth : 0);
+            int effectiveMax = (context.isStrict() || isFixedWidth(context) ? maxWidth : 9);
             int length = text.length();
             if (position == length) {
                 // valid if whole field is optional, invalid if minimum width
@@ -3519,9 +3580,7 @@
                 return false;
             }
             String gmtText = "GMT";  // TODO: get localized version of 'GMT'
-            if (gmtText != null) {
-                buf.append(gmtText);
-            }
+            buf.append(gmtText);
             int totalSecs = Math.toIntExact(offsetSecs);
             if (totalSecs != 0) {
                 int absHours = Math.abs((totalSecs / 3600) % 100);  // anything larger than 99 silently dropped
@@ -3565,14 +3624,12 @@
         @Override
         public int parse(DateTimeParseContext context, CharSequence text, int position) {
             int pos = position;
-            int end = pos + text.length();
+            int end = text.length();
             String gmtText = "GMT";  // TODO: get localized version of 'GMT'
-            if (gmtText != null) {
-                if (!context.subSequenceEquals(text, pos, gmtText, 0, gmtText.length())) {
+            if (!context.subSequenceEquals(text, pos, gmtText, 0, gmtText.length())) {
                     return ~position;
                 }
-                pos += gmtText.length();
-            }
+            pos += gmtText.length();
             // parse normal plus/minus offset
             int negative = 0;
             if (pos == end) {
--- a/jdk/src/java.base/share/classes/java/time/temporal/JulianFields.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/time/temporal/JulianFields.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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
@@ -117,7 +117,13 @@
      *
      * <h3>Astronomical and Scientific Notes</h3>
      * The standard astronomical definition uses a fraction to indicate the time-of-day,
-     * thus 3.25 would represent the time 18:00, since days start at midday.
+     * where each day is counted from midday to midday. For example,
+     * a fraction of 0 represents midday, a fraction of 0.25
+     * represents 18:00, a fraction of 0.5 represents midnight and a fraction
+     * of 0.75 represents 06:00.
+     * <p>
+     * By contrast, this implementation has no fractional part, and counts
+     * days from midnight to midnight.
      * This implementation uses an integer and days starting at midnight.
      * The integer value for the Julian Day Number is the astronomical Julian Day value at midday
      * of the date in question.
--- a/jdk/src/java.base/share/classes/java/util/Arrays.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/util/Arrays.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -4403,6 +4403,35 @@
         public void sort(Comparator<? super E> c) {
             Arrays.sort(a, c);
         }
+
+        @Override
+        public Iterator<E> iterator() {
+            return new ArrayItr<>(a);
+        }
+    }
+
+    private static class ArrayItr<E> implements Iterator<E> {
+        private int cursor;
+        private final E[] a;
+
+        ArrayItr(E[] a) {
+            this.a = a;
+        }
+
+        @Override
+        public boolean hasNext() {
+            return cursor < a.length;
+        }
+
+        @Override
+        public E next() {
+            int i = cursor;
+            if (i >= a.length) {
+                throw new NoSuchElementException();
+            }
+            cursor = i + 1;
+            return a[i];
+        }
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/util/Locale.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/util/Locale.java	Thu Apr 28 23:08:16 2016 -0700
@@ -45,7 +45,6 @@
 import java.io.ObjectOutputStream;
 import java.io.ObjectStreamField;
 import java.io.Serializable;
-import java.security.AccessController;
 import java.text.MessageFormat;
 import java.util.spi.LocaleNameProvider;
 
@@ -859,11 +858,10 @@
 
     private static Locale initDefault() {
         String language, region, script, country, variant;
-        language = AccessController.doPrivileged(
-            new GetPropertyAction("user.language", "en"));
+        Properties props = GetPropertyAction.getProperties();
+        language = props.getProperty("user.language", "en");
         // for compatibility, check for old user.region property
-        region = AccessController.doPrivileged(
-            new GetPropertyAction("user.region"));
+        region = props.getProperty("user.region");
         if (region != null) {
             // region can be of form country, country_variant, or _variant
             int i = region.indexOf('_');
@@ -876,27 +874,25 @@
             }
             script = "";
         } else {
-            script = AccessController.doPrivileged(
-                new GetPropertyAction("user.script", ""));
-            country = AccessController.doPrivileged(
-                new GetPropertyAction("user.country", ""));
-            variant = AccessController.doPrivileged(
-                new GetPropertyAction("user.variant", ""));
+            script = props.getProperty("user.script", "");
+            country = props.getProperty("user.country", "");
+            variant = props.getProperty("user.variant", "");
         }
 
         return getInstance(language, script, country, variant, null);
     }
 
     private static Locale initDefault(Locale.Category category) {
+        Properties props = GetPropertyAction.getProperties();
         return getInstance(
-            AccessController.doPrivileged(
-                new GetPropertyAction(category.languageKey, defaultLocale.getLanguage())),
-            AccessController.doPrivileged(
-                new GetPropertyAction(category.scriptKey, defaultLocale.getScript())),
-            AccessController.doPrivileged(
-                new GetPropertyAction(category.countryKey, defaultLocale.getCountry())),
-            AccessController.doPrivileged(
-                new GetPropertyAction(category.variantKey, defaultLocale.getVariant())),
+            props.getProperty(category.languageKey,
+                    defaultLocale.getLanguage()),
+            props.getProperty(category.scriptKey,
+                    defaultLocale.getScript()),
+            props.getProperty(category.countryKey,
+                    defaultLocale.getCountry()),
+            props.getProperty(category.variantKey,
+                    defaultLocale.getVariant()),
             null);
     }
 
--- a/jdk/src/java.base/share/classes/java/util/Observable.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/util/Observable.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2016, 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
@@ -58,7 +58,19 @@
  * @see     java.util.Observer
  * @see     java.util.Observer#update(java.util.Observable, java.lang.Object)
  * @since   1.0
+ *
+ * @deprecated
+ * This class and the {@link Observer} interface have been deprecated.
+ * The event model supported by {@code Observer} and {@code Observable}
+ * is quite limited, the order of notifications delivered by
+ * {@code Observable} is unspecified, and state changes are not in
+ * one-for-one correspondence with notifications.
+ * For a richer event model, consider using the
+ * {@link java.beans} package.  For reliable and ordered
+ * messaging among threads, consider using one of the concurrent data
+ * structures in the {@link java.util.concurrent} package.
  */
+@Deprecated(since="9")
 public class Observable {
     private boolean changed = false;
     private Vector<Observer> obs;
--- a/jdk/src/java.base/share/classes/java/util/Observer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/util/Observer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,12 @@
  * @author  Chris Warth
  * @see     java.util.Observable
  * @since   1.0
+ *
+ * @deprecated
+ * This interface has been deprecated. See the {@link Observable}
+ * class for further information.
  */
+@Deprecated(since="9")
 public interface Observer {
     /**
      * This method is called whenever the observed object is changed. An
--- a/jdk/src/java.base/share/classes/java/util/PropertyResourceBundle.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/util/PropertyResourceBundle.java	Thu Apr 28 23:08:16 2016 -0700
@@ -43,7 +43,6 @@
 import java.io.InputStreamReader;
 import java.io.Reader;
 import java.io.IOException;
-import java.nio.charset.Charset;
 import java.nio.charset.MalformedInputException;
 import java.nio.charset.StandardCharsets;
 import java.nio.charset.UnmappableCharacterException;
@@ -142,8 +141,8 @@
     // Check whether the strict encoding is specified.
     // The possible encoding is either "ISO-8859-1" or "UTF-8".
     private static final String encoding =
-        AccessController.doPrivileged(
-            new GetPropertyAction("java.util.PropertyResourceBundle.encoding", ""))
+        GetPropertyAction
+                .getProperty("java.util.PropertyResourceBundle.encoding", "")
         .toUpperCase(Locale.ROOT);
 
     /**
--- a/jdk/src/java.base/share/classes/java/util/TimeZone.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/util/TimeZone.java	Thu Apr 28 23:08:16 2016 -0700
@@ -660,14 +660,12 @@
     private static synchronized TimeZone setDefaultZone() {
         TimeZone tz;
         // get the time zone ID from the system properties
-        String zoneID = AccessController.doPrivileged(
-                new GetPropertyAction("user.timezone"));
+        String zoneID = GetPropertyAction.getProperty("user.timezone");
 
         // if the time zone ID is not set (yet), perform the
         // platform to Java time zone ID mapping.
         if (zoneID == null || zoneID.isEmpty()) {
-            String javaHome = AccessController.doPrivileged(
-                    new GetPropertyAction("java.home"));
+            String javaHome = GetPropertyAction.getProperty("java.home");
             try {
                 zoneID = getSystemTimeZoneID(javaHome);
                 if (zoneID == null) {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java	Thu Apr 28 23:08:16 2016 -0700
@@ -455,7 +455,7 @@
             s = v1 * v1 + v2 * v2;
         } while (s >= 1 || s == 0);
         double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s)/s);
-        nextLocalGaussian.set(new Double(v2 * multiplier));
+        nextLocalGaussian.set(Double.valueOf(v2 * multiplier));
         return v1 * multiplier;
     }
 
--- a/jdk/src/java.base/share/classes/java/util/jar/JarFile.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/util/jar/JarFile.java	Thu Apr 28 23:08:16 2016 -0700
@@ -34,7 +34,6 @@
 import java.util.zip.*;
 import java.security.CodeSigner;
 import java.security.cert.Certificate;
-import java.security.AccessController;
 import java.security.CodeSource;
 import jdk.internal.misc.SharedSecrets;
 import sun.security.action.GetPropertyAction;
@@ -155,16 +154,16 @@
 
         BASE_VERSION = 8;  // one less than lowest version for versioned entries
         int runtimeVersion = jdk.Version.current().major();
-        String jarVersion = AccessController.doPrivileged(
-                new GetPropertyAction("jdk.util.jar.version"));
+        String jarVersion =
+                GetPropertyAction.getProperty("jdk.util.jar.version");
         if (jarVersion != null) {
             int jarVer = Integer.parseInt(jarVersion);
             runtimeVersion = (jarVer > runtimeVersion)
                     ? runtimeVersion : Math.max(jarVer, 0);
         }
         RUNTIME_VERSION = runtimeVersion;
-        String enableMultiRelease = AccessController.doPrivileged(
-                new GetPropertyAction("jdk.util.jar.enableMultiRelease", "true"));
+        String enableMultiRelease = GetPropertyAction
+                .getProperty("jdk.util.jar.enableMultiRelease", "true");
         switch (enableMultiRelease) {
             case "true":
             default:
--- a/jdk/src/java.base/share/classes/java/util/jar/Pack200.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/util/jar/Pack200.java	Thu Apr 28 23:08:16 2016 -0700
@@ -29,6 +29,7 @@
 import java.io.OutputStream;
 import java.io.File;
 import java.io.IOException;
+import sun.security.action.GetPropertyAction;
 
 
 /**
@@ -694,8 +695,7 @@
             Class<?> impl = (PACK_PROVIDER.equals(prop))? packerImpl: unpackerImpl;
             if (impl == null) {
                 // The first time, we must decide which class to use.
-                implName = java.security.AccessController.doPrivileged(
-                    new sun.security.action.GetPropertyAction(prop,""));
+                implName = GetPropertyAction.getProperty(prop,"");
                 if (implName != null && !implName.equals(""))
                     impl = Class.forName(implName);
                 else if (PACK_PROVIDER.equals(prop))
--- a/jdk/src/java.base/share/classes/java/util/regex/PatternSyntaxException.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/util/regex/PatternSyntaxException.java	Thu Apr 28 23:08:16 2016 -0700
@@ -94,8 +94,7 @@
     }
 
     private static final String nl =
-        java.security.AccessController
-            .doPrivileged(new GetPropertyAction("line.separator"));
+            GetPropertyAction.getProperty("line.separator");
 
     /**
      * Returns a multi-line string containing the description of the syntax
--- a/jdk/src/java.base/share/classes/java/util/stream/DoublePipeline.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/util/stream/DoublePipeline.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, 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
@@ -167,6 +167,19 @@
         return Nodes.doubleBuilder(exactSizeIfKnown);
     }
 
+    private <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper, int opFlags) {
+        return new ReferencePipeline.StatelessOp<Double, U>(this, StreamShape.DOUBLE_VALUE, opFlags) {
+            @Override
+            Sink<Double> opWrapSink(int flags, Sink<U> sink) {
+                return new Sink.ChainedDouble<U>(sink) {
+                    @Override
+                    public void accept(double t) {
+                        downstream.accept(mapper.apply(t));
+                    }
+                };
+            }
+        };
+    }
 
     // DoubleStream
 
@@ -184,7 +197,7 @@
 
     @Override
     public final Stream<Double> boxed() {
-        return mapToObj(Double::valueOf);
+        return mapToObj(Double::valueOf, 0);
     }
 
     @Override
@@ -207,18 +220,7 @@
     @Override
     public final <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper) {
         Objects.requireNonNull(mapper);
-        return new ReferencePipeline.StatelessOp<Double, U>(this, StreamShape.DOUBLE_VALUE,
-                                                            StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
-            @Override
-            Sink<Double> opWrapSink(int flags, Sink<U> sink) {
-                return new Sink.ChainedDouble<U>(sink) {
-                    @Override
-                    public void accept(double t) {
-                        downstream.accept(mapper.apply(t));
-                    }
-                };
-            }
-        };
+        return mapToObj(mapper, StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT);
     }
 
     @Override
--- a/jdk/src/java.base/share/classes/java/util/stream/IntPipeline.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/util/stream/IntPipeline.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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
@@ -170,6 +170,19 @@
         return Nodes.intBuilder(exactSizeIfKnown);
     }
 
+    private <U> Stream<U> mapToObj(IntFunction<? extends U> mapper, int opFlags) {
+        return new ReferencePipeline.StatelessOp<Integer, U>(this, StreamShape.INT_VALUE, opFlags) {
+            @Override
+            Sink<Integer> opWrapSink(int flags, Sink<U> sink) {
+                return new Sink.ChainedInt<U>(sink) {
+                    @Override
+                    public void accept(int t) {
+                        downstream.accept(mapper.apply(t));
+                    }
+                };
+            }
+        };
+    }
 
     // IntStream
 
@@ -187,8 +200,7 @@
 
     @Override
     public final LongStream asLongStream() {
-        return new LongPipeline.StatelessOp<Integer>(this, StreamShape.INT_VALUE,
-                                                     StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
+        return new LongPipeline.StatelessOp<Integer>(this, StreamShape.INT_VALUE, 0) {
             @Override
             Sink<Integer> opWrapSink(int flags, Sink<Long> sink) {
                 return new Sink.ChainedInt<Long>(sink) {
@@ -203,8 +215,7 @@
 
     @Override
     public final DoubleStream asDoubleStream() {
-        return new DoublePipeline.StatelessOp<Integer>(this, StreamShape.INT_VALUE,
-                                                       StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
+        return new DoublePipeline.StatelessOp<Integer>(this, StreamShape.INT_VALUE, 0) {
             @Override
             Sink<Integer> opWrapSink(int flags, Sink<Double> sink) {
                 return new Sink.ChainedInt<Double>(sink) {
@@ -219,7 +230,7 @@
 
     @Override
     public final Stream<Integer> boxed() {
-        return mapToObj(Integer::valueOf);
+        return mapToObj(Integer::valueOf, 0);
     }
 
     @Override
@@ -242,18 +253,7 @@
     @Override
     public final <U> Stream<U> mapToObj(IntFunction<? extends U> mapper) {
         Objects.requireNonNull(mapper);
-        return new ReferencePipeline.StatelessOp<Integer, U>(this, StreamShape.INT_VALUE,
-                                                             StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
-            @Override
-            Sink<Integer> opWrapSink(int flags, Sink<U> sink) {
-                return new Sink.ChainedInt<U>(sink) {
-                    @Override
-                    public void accept(int t) {
-                        downstream.accept(mapper.apply(t));
-                    }
-                };
-            }
-        };
+        return mapToObj(mapper, StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT);
     }
 
     @Override
--- a/jdk/src/java.base/share/classes/java/util/stream/LongPipeline.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/util/stream/LongPipeline.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, 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
@@ -167,6 +167,19 @@
         return Nodes.longBuilder(exactSizeIfKnown);
     }
 
+    private <U> Stream<U> mapToObj(LongFunction<? extends U> mapper, int opFlags) {
+        return new ReferencePipeline.StatelessOp<Long, U>(this, StreamShape.LONG_VALUE, opFlags) {
+            @Override
+            Sink<Long> opWrapSink(int flags, Sink<U> sink) {
+                return new Sink.ChainedLong<U>(sink) {
+                    @Override
+                    public void accept(long t) {
+                        downstream.accept(mapper.apply(t));
+                    }
+                };
+            }
+        };
+    }
 
     // LongStream
 
@@ -184,8 +197,7 @@
 
     @Override
     public final DoubleStream asDoubleStream() {
-        return new DoublePipeline.StatelessOp<Long>(this, StreamShape.LONG_VALUE,
-                                                    StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
+        return new DoublePipeline.StatelessOp<Long>(this, StreamShape.LONG_VALUE, StreamOpFlag.NOT_DISTINCT) {
             @Override
             Sink<Long> opWrapSink(int flags, Sink<Double> sink) {
                 return new Sink.ChainedLong<Double>(sink) {
@@ -200,7 +212,7 @@
 
     @Override
     public final Stream<Long> boxed() {
-        return mapToObj(Long::valueOf);
+        return mapToObj(Long::valueOf, 0);
     }
 
     @Override
@@ -223,18 +235,7 @@
     @Override
     public final <U> Stream<U> mapToObj(LongFunction<? extends U> mapper) {
         Objects.requireNonNull(mapper);
-        return new ReferencePipeline.StatelessOp<Long, U>(this, StreamShape.LONG_VALUE,
-                                                          StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
-            @Override
-            Sink<Long> opWrapSink(int flags, Sink<U> sink) {
-                return new Sink.ChainedLong<U>(sink) {
-                    @Override
-                    public void accept(long t) {
-                        downstream.accept(mapper.apply(t));
-                    }
-                };
-            }
-        };
+        return mapToObj(mapper, StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT);
     }
 
     @Override
--- a/jdk/src/java.base/share/classes/java/util/stream/StreamSpliterators.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/util/stream/StreamSpliterators.java	Thu Apr 28 23:08:16 2016 -0700
@@ -28,6 +28,7 @@
 import java.util.Objects;
 import java.util.Spliterator;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ForkJoinPool;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.function.BooleanSupplier;
 import java.util.function.Consumer;
@@ -905,6 +906,7 @@
         // The spliterator to slice
         protected final T_SPLITR s;
         protected final boolean unlimited;
+        protected final int chunkSize;
         private final long skipThreshold;
         private final AtomicLong permits;
 
@@ -912,6 +914,8 @@
             this.s = s;
             this.unlimited = limit < 0;
             this.skipThreshold = limit >= 0 ? limit : 0;
+            this.chunkSize = limit >= 0 ? (int)Math.min(CHUNK_SIZE,
+                ((skip + limit) / AbstractTask.LEAF_TARGET) + 1) : CHUNK_SIZE;
             this.permits = new AtomicLong(limit >= 0 ? skip + limit : skip);
         }
 
@@ -921,6 +925,7 @@
             this.unlimited = parent.unlimited;
             this.permits = parent.permits;
             this.skipThreshold = parent.skipThreshold;
+            this.chunkSize = parent.chunkSize;
         }
 
         /**
@@ -1029,13 +1034,13 @@
                 PermitStatus permitStatus;
                 while ((permitStatus = permitStatus()) != PermitStatus.NO_MORE) {
                     if (permitStatus == PermitStatus.MAYBE_MORE) {
-                        // Optimistically traverse elements up to a threshold of CHUNK_SIZE
+                        // Optimistically traverse elements up to a threshold of chunkSize
                         if (sb == null)
-                            sb = new ArrayBuffer.OfRef<>(CHUNK_SIZE);
+                            sb = new ArrayBuffer.OfRef<>(chunkSize);
                         else
                             sb.reset();
                         long permitsRequested = 0;
-                        do { } while (s.tryAdvance(sb) && ++permitsRequested < CHUNK_SIZE);
+                        do { } while (s.tryAdvance(sb) && ++permitsRequested < chunkSize);
                         if (permitsRequested == 0)
                             return;
                         sb.forEach(action, acquirePermits(permitsRequested));
@@ -1102,15 +1107,15 @@
                 PermitStatus permitStatus;
                 while ((permitStatus = permitStatus()) != PermitStatus.NO_MORE) {
                     if (permitStatus == PermitStatus.MAYBE_MORE) {
-                        // Optimistically traverse elements up to a threshold of CHUNK_SIZE
+                        // Optimistically traverse elements up to a threshold of chunkSize
                         if (sb == null)
-                            sb = bufferCreate(CHUNK_SIZE);
+                            sb = bufferCreate(chunkSize);
                         else
                             sb.reset();
                         @SuppressWarnings("unchecked")
                         T_CONS sbc = (T_CONS) sb;
                         long permitsRequested = 0;
-                        do { } while (s.tryAdvance(sbc) && ++permitsRequested < CHUNK_SIZE);
+                        do { } while (s.tryAdvance(sbc) && ++permitsRequested < chunkSize);
                         if (permitsRequested == 0)
                             return;
                         sb.forEach(action, acquirePermits(permitsRequested));
--- a/jdk/src/java.base/share/classes/java/util/zip/ZipOutputStream.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/util/zip/ZipOutputStream.java	Thu Apr 28 23:08:16 2016 -0700
@@ -33,6 +33,7 @@
 import java.util.HashSet;
 import static java.util.zip.ZipConstants64.*;
 import static java.util.zip.ZipUtils.*;
+import sun.security.action.GetPropertyAction;
 
 /**
  * This class implements an output stream filter for writing files in the
@@ -54,9 +55,7 @@
      */
     private static final boolean inhibitZip64 =
         Boolean.parseBoolean(
-            java.security.AccessController.doPrivileged(
-                new sun.security.action.GetPropertyAction(
-                    "jdk.util.zip.inhibitZip64", "false")));
+            GetPropertyAction.getProperty("jdk.util.zip.inhibitZip64"));
 
     private static class XEntry {
         final ZipEntry entry;
--- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java	Thu Apr 28 23:08:16 2016 -0700
@@ -51,9 +51,9 @@
     static final boolean DEBUG;
 
     static {
-        String s = java.security.AccessController.doPrivileged(
-            new GetPropertyAction("javax.net.debug", "")).toLowerCase(
-                                                            Locale.ENGLISH);
+        String s = GetPropertyAction.getProperty("javax.net.debug", "")
+                .toLowerCase(Locale.ENGLISH);
+
         DEBUG = s.contains("all") || s.contains("ssl");
     }
 
--- a/jdk/src/java.base/share/classes/jdk/Version.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/jdk/Version.java	Thu Apr 28 23:08:16 2016 -0700
@@ -26,8 +26,6 @@
 package jdk;
 
 import java.math.BigInteger;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
 import java.util.ArrayList;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -35,6 +33,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
+import sun.security.action.GetPropertyAction;
 
 /**
  * A representation of the JDK version-string which contains a version
@@ -274,12 +273,7 @@
      */
     public static Version current() {
         if (current == null) {
-            current = parse(AccessController.doPrivileged(
-                new PrivilegedAction<>() {
-                    public String run() {
-                        return System.getProperty("java.version");
-                    }
-                }));
+            current = parse(GetPropertyAction.getProperty("java.version"));
         }
         return current;
     }
--- a/jdk/src/java.base/share/classes/jdk/internal/jimage/BasicImageReader.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/jdk/internal/jimage/BasicImageReader.java	Thu Apr 28 23:08:16 2016 -0700
@@ -183,7 +183,9 @@
     }
 
     public static void releaseByteBuffer(ByteBuffer buffer) {
-        ImageBufferCache.releaseBuffer(buffer);
+        if (!MAP_ALL) {
+            ImageBufferCache.releaseBuffer(buffer);
+        }
     }
 
     public String getName() {
--- a/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageReader.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageReader.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,6 +25,7 @@
 package jdk.internal.jimage;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.UncheckedIOException;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
@@ -36,8 +37,11 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
 import java.util.function.Consumer;
 
 /**
@@ -47,80 +51,486 @@
  * but also compiled and delivered as part of the jrtfs.jar to support access
  * to the jimage file provided by the shipped JDK by tools running on JDK 8.
  */
-public class ImageReader extends BasicImageReader {
-
-    private static final int SIZE_OF_OFFSET = 4;
-
-    // Map of files opened as LITTLE_ENDIAN
-    private static final HashMap<Path, ImageReader> OPEN_LE_FILES
-            = new HashMap<>();
-
-    // Map of files opened as BIG_ENDIAN
-    private static final HashMap<Path, ImageReader> OPEN_BE_FILES
-            = new HashMap<>();
-
-    private int openCount;
+public final class ImageReader implements AutoCloseable {
+    private SharedImageReader reader;
 
-    // attributes of the .jimage file. jimage file does not contain
-    // attributes for the individual resources (yet). We use attributes
-    // of the jimage file itself (creation, modification, access times).
-    // Iniitalized lazily, see {@link #imageFileAttributes()}.
-    private BasicFileAttributes imageFileAttributes;
-
-    // directory management implementation
-    private final HashMap<String, Node> nodes;
-    private volatile Directory rootDir;
-
-    private Directory packagesDir;
-    private Directory modulesDir;
-
-    private ImageReader(Path imagePath, ByteOrder byteOrder) throws IOException {
-        super(imagePath, byteOrder);
-        this.nodes = new HashMap<>();
+    private ImageReader(SharedImageReader reader) {
+        this.reader = reader;
     }
 
     public static ImageReader open(Path imagePath, ByteOrder byteOrder) throws IOException {
-        HashMap<Path, ImageReader> openFiles = getOpenFilesMap(byteOrder);
-        ImageReader reader;
-        synchronized (openFiles) {
-            reader = openFiles.get(imagePath);
-            if (reader == null) {
-                reader = new ImageReader(imagePath, byteOrder);
-                ImageReader existingReader = openFiles.putIfAbsent(imagePath, reader);
-                assert (existingReader == null);
-            }
-            reader.openCount++;
-        }
-        return reader;
+        return SharedImageReader.open(imagePath, byteOrder);
     }
 
-    private static HashMap<Path, ImageReader> getOpenFilesMap(ByteOrder byteOrder) {
-        return (byteOrder == ByteOrder.BIG_ENDIAN) ? OPEN_BE_FILES : OPEN_LE_FILES;
-    }
-
-    /**
-     * Opens the given file path as an image file, returning an {@code ImageReader}.
-     */
     public static ImageReader open(Path imagePath) throws IOException {
         return open(imagePath, ByteOrder.nativeOrder());
     }
 
-    private boolean canClose() {
-        HashMap<Path, ImageReader> openFiles = getOpenFilesMap(this.getByteOrder());
-        synchronized (openFiles) {
-            if (--this.openCount == 0) {
-                return openFiles.remove(this.getName(), this);
+    @Override
+    public void close() throws IOException {
+        if (reader == null) {
+            throw new IOException("image file already closed");
+        }
+
+        reader.close(this);
+        reader = null;
+    }
+
+    // directory management interface
+    public Directory getRootDirectory() throws IOException {
+        if (reader == null) {
+            throw new IOException("image file closed");
+        }
+        return reader.getRootDirectory();
+    }
+
+    public Node findNode(String name) throws IOException {
+        if (reader == null) {
+            throw new IOException("image file closed");
+        }
+        return reader.findNode(name);
+    }
+
+    public byte[] getResource(Node node) throws IOException {
+        if (reader == null) {
+            throw new IOException("image file closed");
+        }
+        return reader.getResource(node);
+    }
+
+    public byte[] getResource(Resource rs) throws IOException {
+        if (reader == null) {
+            throw new IOException("image file closed");
+        }
+        return reader.getResource(rs);
+    }
+
+    public ImageHeader getHeader() {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getHeader();
+    }
+
+    public static void releaseByteBuffer(ByteBuffer buffer) {
+        BasicImageReader.releaseByteBuffer(buffer);
+    }
+
+    public String getName() {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getName() ;
+    }
+
+    public ByteOrder getByteOrder() {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getByteOrder();
+    }
+
+    public Path getImagePath() {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getImagePath();
+    }
+
+    public ImageStringsReader getStrings() {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getStrings();
+    }
+
+    public ImageLocation findLocation(String mn, String rn) {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.findLocation(mn, rn);
+    }
+
+    public ImageLocation findLocation(String name) {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.findLocation(name);
+    }
+
+    public String[] getEntryNames() {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getEntryNames();
+    }
+
+    public long[] getAttributes(int offset) {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getAttributes(offset);
+    }
+
+    public String getString(int offset) {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getString(offset);
+    }
+
+    public byte[] getResource(String name) {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getResource(name);
+    }
+
+    public byte[] getResource(ImageLocation loc) {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getResource(loc);
+    }
+
+    public ByteBuffer getResourceBuffer(ImageLocation loc) {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getResourceBuffer(loc);
+    }
+
+    public InputStream getResourceStream(ImageLocation loc) {
+        Objects.requireNonNull(reader, "image file closed");
+        return reader.getResourceStream(loc);
+    }
+
+    private final static class SharedImageReader extends BasicImageReader {
+        static final int SIZE_OF_OFFSET = Integer.BYTES;
+
+        static final Map<Path, SharedImageReader> OPEN_FILES = new HashMap<>();
+
+        // List of openers for this shared image.
+        final Set<ImageReader> openers;
+
+        // attributes of the .jimage file. jimage file does not contain
+        // attributes for the individual resources (yet). We use attributes
+        // of the jimage file itself (creation, modification, access times).
+        // Iniitalized lazily, see {@link #imageFileAttributes()}.
+        BasicFileAttributes imageFileAttributes;
+
+        // directory management implementation
+        final HashMap<String, Node> nodes;
+        volatile Directory rootDir;
+
+        Directory packagesDir;
+        Directory modulesDir;
+
+        private SharedImageReader(Path imagePath, ByteOrder byteOrder) throws IOException {
+            super(imagePath, byteOrder);
+            this.openers = new HashSet<>();
+            this.nodes = new HashMap<>();
+        }
+
+        public static ImageReader open(Path imagePath, ByteOrder byteOrder) throws IOException {
+            synchronized (OPEN_FILES) {
+                SharedImageReader reader = OPEN_FILES.get(imagePath);
+
+                if (reader == null) {
+                    // Will fail with an IOException if wrong byteOrder.
+                    reader =  new SharedImageReader(imagePath, byteOrder);
+                    OPEN_FILES.put(imagePath, reader);
+                } else if (reader.getByteOrder() != byteOrder) {
+                    throw new IOException("\"" + reader.getName() + "\" is not an image file");
+                }
+
+                ImageReader image = new ImageReader(reader);
+                reader.openers.add(image);
+
+                return image;
+            }
+        }
+
+        public void close(ImageReader image) throws IOException {
+            synchronized (OPEN_FILES) {
+                if (!openers.remove(image)) {
+                    throw new IOException("image file already closed");
+                }
+
+                if (openers.isEmpty()) {
+                    close();
+                    nodes.clear();
+                    rootDir = null;
+
+                    if (!OPEN_FILES.remove(this.getImagePath(), this)) {
+                        throw new IOException("image file not found in open list");
+                    }
+                }
+            }
+        }
+
+        void addOpener(ImageReader reader) {
+            synchronized (OPEN_FILES) {
+                openers.add(reader);
+            }
+        }
+
+        boolean removeOpener(ImageReader reader) {
+            synchronized (OPEN_FILES) {
+                return openers.remove(reader);
             }
         }
-        return false;
-    }
+
+        // directory management interface
+        Directory getRootDirectory() {
+            return buildRootDirectory();
+        }
+
+        /**
+         * Lazily build a node from a name.
+        */
+        synchronized Node buildNode(String name) {
+            Node n;
+            boolean isPackages = name.startsWith("/packages");
+            boolean isModules = !isPackages && name.startsWith("/modules");
+
+            if (!(isModules || isPackages)) {
+                return null;
+            }
+
+            ImageLocation loc = findLocation(name);
+
+            if (loc != null) { // A sub tree node
+                if (isPackages) {
+                    n = handlePackages(name, loc);
+                } else { // modules sub tree
+                    n = handleModulesSubTree(name, loc);
+                }
+            } else { // Asking for a resource? /modules/java.base/java/lang/Object.class
+                if (isModules) {
+                    n = handleResource(name);
+                } else {
+                    // Possibly ask for /packages/java.lang/java.base
+                    // although /packages/java.base not created
+                    n = handleModuleLink(name);
+                }
+            }
+            return n;
+        }
+
+        synchronized Directory buildRootDirectory() {
+            Directory root = rootDir; // volatile read
+            if (root != null) {
+                return root;
+            }
+
+            root = newDirectory(null, "/");
+            root.setIsRootDir();
+
+            // /packages dir
+            packagesDir = newDirectory(root, "/packages");
+            packagesDir.setIsPackagesDir();
+
+            // /modules dir
+            modulesDir = newDirectory(root, "/modules");
+            modulesDir.setIsModulesDir();
+
+            root.setCompleted(true);
+            return rootDir = root;
+        }
+
+        /**
+         * To visit sub tree resources.
+         */
+        interface LocationVisitor {
+            void visit(ImageLocation loc);
+        }
+
+        void visitLocation(ImageLocation loc, LocationVisitor visitor) {
+            byte[] offsets = getResource(loc);
+            ByteBuffer buffer = ByteBuffer.wrap(offsets);
+            buffer.order(getByteOrder());
+            IntBuffer intBuffer = buffer.asIntBuffer();
+            for (int i = 0; i < offsets.length / SIZE_OF_OFFSET; i++) {
+                int offset = intBuffer.get(i);
+                ImageLocation pkgLoc = getLocation(offset);
+                visitor.visit(pkgLoc);
+            }
+        }
+
+        void visitPackageLocation(ImageLocation loc) {
+            // Retrieve package name
+            String pkgName = getBaseExt(loc);
+            // Content is array of offsets in Strings table
+            byte[] stringsOffsets = getResource(loc);
+            ByteBuffer buffer = ByteBuffer.wrap(stringsOffsets);
+            buffer.order(getByteOrder());
+            IntBuffer intBuffer = buffer.asIntBuffer();
+            // For each module, create a link node.
+            for (int i = 0; i < stringsOffsets.length / SIZE_OF_OFFSET; i++) {
+                // skip empty state, useless.
+                intBuffer.get(i);
+                i++;
+                int offset = intBuffer.get(i);
+                String moduleName = getString(offset);
+                Node targetNode = findNode("/modules/" + moduleName);
+                if (targetNode != null) {
+                    String pkgDirName = packagesDir.getName() + "/" + pkgName;
+                    Directory pkgDir = (Directory) nodes.get(pkgDirName);
+                    newLinkNode(pkgDir, pkgDir.getName() + "/" + moduleName, targetNode);
+                }
+            }
+        }
+
+        Node handlePackages(String name, ImageLocation loc) {
+            long size = loc.getUncompressedSize();
+            Node n = null;
+            // Only possiblities are /packages, /packages/package/module
+            if (name.equals("/packages")) {
+                visitLocation(loc, (childloc) -> {
+                    findNode(childloc.getFullName());
+                });
+                packagesDir.setCompleted(true);
+                n = packagesDir;
+            } else {
+                if (size != 0) { // children are offsets to module in StringsTable
+                    String pkgName = getBaseExt(loc);
+                    Directory pkgDir = newDirectory(packagesDir, packagesDir.getName() + "/" + pkgName);
+                    visitPackageLocation(loc);
+                    pkgDir.setCompleted(true);
+                    n = pkgDir;
+                } else { // Link to module
+                    String pkgName = loc.getParent();
+                    String modName = getBaseExt(loc);
+                    Node targetNode = findNode("/modules/" + modName);
+                    if (targetNode != null) {
+                        String pkgDirName = packagesDir.getName() + "/" + pkgName;
+                        Directory pkgDir = (Directory) nodes.get(pkgDirName);
+                        Node linkNode = newLinkNode(pkgDir, pkgDir.getName() + "/" + modName, targetNode);
+                        n = linkNode;
+                    }
+                }
+            }
+            return n;
+        }
 
-    @Override
-    public void close() throws IOException {
-        if (canClose()) {
-            super.close();
-            clearNodes();
-       }
+        // Asking for /packages/package/module although
+        // /packages/<pkg>/ not yet created, need to create it
+        // prior to return the link to module node.
+        Node handleModuleLink(String name) {
+            // eg: unresolved /packages/package/module
+            // Build /packages/package node
+            Node ret = null;
+            String radical = "/packages/";
+            String path = name;
+            if (path.startsWith(radical)) {
+                int start = radical.length();
+                int pkgEnd = path.indexOf('/', start);
+                if (pkgEnd != -1) {
+                    String pkg = path.substring(start, pkgEnd);
+                    String pkgPath = radical + pkg;
+                    Node n = findNode(pkgPath);
+                    // If not found means that this is a symbolic link such as:
+                    // /packages/java.util/java.base/java/util/Vector.class
+                    // and will be done by a retry of the filesystem
+                    for (Node child : n.getChildren()) {
+                        if (child.name.equals(name)) {
+                            ret = child;
+                            break;
+                        }
+                    }
+                }
+            }
+            return ret;
+        }
+
+        Node handleModulesSubTree(String name, ImageLocation loc) {
+            Node n;
+            assert (name.equals(loc.getFullName()));
+            Directory dir = makeDirectories(name);
+            visitLocation(loc, (childloc) -> {
+                String path = childloc.getFullName();
+                if (path.startsWith("/modules")) { // a package
+                    makeDirectories(path);
+                } else { // a resource
+                    makeDirectories(childloc.buildName(true, true, false));
+                    newResource(dir, childloc);
+                }
+            });
+            dir.setCompleted(true);
+            n = dir;
+            return n;
+        }
+
+        Node handleResource(String name) {
+            Node n = null;
+            String locationPath = name.substring("/modules".length());
+            ImageLocation resourceLoc = findLocation(locationPath);
+            if (resourceLoc != null) {
+                Directory dir = makeDirectories(resourceLoc.buildName(true, true, false));
+                Resource res = newResource(dir, resourceLoc);
+                n = res;
+            }
+            return n;
+        }
+
+        String getBaseExt(ImageLocation loc) {
+            String base = loc.getBase();
+            String ext = loc.getExtension();
+            if (ext != null && !ext.isEmpty()) {
+                base = base + "." + ext;
+            }
+            return base;
+        }
+
+        synchronized Node findNode(String name) {
+            buildRootDirectory();
+            Node n = nodes.get(name);
+            if (n == null || !n.isCompleted()) {
+                n = buildNode(name);
+            }
+            return n;
+        }
+
+        /**
+         * Returns the file attributes of the image file.
+         */
+        BasicFileAttributes imageFileAttributes() {
+            BasicFileAttributes attrs = imageFileAttributes;
+            if (attrs == null) {
+                try {
+                    Path file = getImagePath();
+                    attrs = Files.readAttributes(file, BasicFileAttributes.class);
+                } catch (IOException ioe) {
+                    throw new UncheckedIOException(ioe);
+                }
+                imageFileAttributes = attrs;
+            }
+            return attrs;
+        }
+
+        Directory newDirectory(Directory parent, String name) {
+            Directory dir = Directory.create(parent, name, imageFileAttributes());
+            nodes.put(dir.getName(), dir);
+            return dir;
+        }
+
+        Resource newResource(Directory parent, ImageLocation loc) {
+            Resource res = Resource.create(parent, loc, imageFileAttributes());
+            nodes.put(res.getName(), res);
+            return res;
+        }
+
+        LinkNode newLinkNode(Directory dir, String name, Node link) {
+            LinkNode linkNode = LinkNode.create(dir, name, link);
+            nodes.put(linkNode.getName(), linkNode);
+            return linkNode;
+        }
+
+        Directory makeDirectories(String parent) {
+            Directory last = rootDir;
+            for (int offset = parent.indexOf('/', 1);
+                    offset != -1;
+                    offset = parent.indexOf('/', offset + 1)) {
+                String dir = parent.substring(0, offset);
+                last = makeDirectory(dir, last);
+            }
+            return makeDirectory(parent, last);
+
+        }
+
+        Directory makeDirectory(String dir, Directory last) {
+            Directory nextDir = (Directory) nodes.get(dir);
+            if (nextDir == null) {
+                nextDir = newDirectory(last, dir);
+            }
+            return nextDir;
+        }
+
+        byte[] getResource(Node node) throws IOException {
+            if (node.isResource()) {
+                return super.getResource(node.getLocation());
+            }
+            throw new IOException("Not a resource: " + node);
+        }
+
+        byte[] getResource(Resource rs) throws IOException {
+            return super.getResource(rs.getLocation());
+        }
     }
 
     // jimage file does not store directory structure. We build nodes
@@ -389,7 +799,7 @@
 
         @Override
         public Node resolveLink(boolean recursive) {
-            return recursive && (link instanceof LinkNode)? ((LinkNode)link).resolveLink(true) : link;
+            return (recursive && link instanceof LinkNode) ? ((LinkNode)link).resolveLink(true) : link;
         }
 
         @Override
@@ -397,297 +807,4 @@
             return true;
         }
     }
-
-    // directory management interface
-    public Directory getRootDirectory() {
-        return buildRootDirectory();
-    }
-
-    /**
-     * To visit sub tree resources.
-     */
-    interface LocationVisitor {
-
-        void visit(ImageLocation loc);
-    }
-
-    /**
-     * Lazily build a node from a name.
-    */
-    private Node buildNode(String name) {
-        Node n;
-        boolean isPackages = name.startsWith("/packages");
-        boolean isModules = !isPackages && name.startsWith("/modules");
-
-        if (!(isModules || isPackages)) {
-            return null;
-        }
-
-        ImageLocation loc = findLocation(name);
-
-        if (loc != null) { // A sub tree node
-            if (isPackages) {
-                n = handlePackages(name, loc);
-            } else { // modules sub tree
-                n = handleModulesSubTree(name, loc);
-            }
-        } else { // Asking for a resource? /modules/java.base/java/lang/Object.class
-            if (isModules) {
-                n = handleResource(name);
-            } else {
-                // Possibly ask for /packages/java.lang/java.base
-                // although /packages/java.base not created
-                n = handleModuleLink(name);
-            }
-        }
-        return n;
-    }
-
-    private void visitLocation(ImageLocation loc, LocationVisitor visitor) {
-        byte[] offsets = getResource(loc);
-        ByteBuffer buffer = ByteBuffer.wrap(offsets);
-        buffer.order(getByteOrder());
-        IntBuffer intBuffer = buffer.asIntBuffer();
-        for (int i = 0; i < offsets.length / SIZE_OF_OFFSET; i++) {
-            int offset = intBuffer.get(i);
-            ImageLocation pkgLoc = getLocation(offset);
-            visitor.visit(pkgLoc);
-        }
-    }
-
-    private void visitPackageLocation(ImageLocation loc) {
-        // Retrieve package name
-        String pkgName = getBaseExt(loc);
-        // Content is array of offsets in Strings table
-        byte[] stringsOffsets = getResource(loc);
-        ByteBuffer buffer = ByteBuffer.wrap(stringsOffsets);
-        buffer.order(getByteOrder());
-        IntBuffer intBuffer = buffer.asIntBuffer();
-        // For each module, create a link node.
-        for (int i = 0; i < stringsOffsets.length / SIZE_OF_OFFSET; i++) {
-            // skip empty state, useless.
-            intBuffer.get(i);
-            i++;
-            int offset = intBuffer.get(i);
-            String moduleName = getString(offset);
-            Node targetNode = findNode("/modules/" + moduleName);
-            if (targetNode != null) {
-                String pkgDirName = packagesDir.getName() + "/" + pkgName;
-                Directory pkgDir = (Directory) nodes.get(pkgDirName);
-                newLinkNode(pkgDir, pkgDir.getName() + "/" + moduleName, targetNode);
-            }
-        }
-    }
-
-    private Node handlePackages(String name, ImageLocation loc) {
-        long size = loc.getUncompressedSize();
-        Node n = null;
-        // Only possiblities are /packages, /packages/package/module
-        if (name.equals("/packages")) {
-            visitLocation(loc, (childloc) -> {
-                findNode(childloc.getFullName());
-            });
-            packagesDir.setCompleted(true);
-            n = packagesDir;
-        } else {
-            if (size != 0) { // children are offsets to module in StringsTable
-                String pkgName = getBaseExt(loc);
-                Directory pkgDir = newDirectory(packagesDir, packagesDir.getName() + "/" + pkgName);
-                visitPackageLocation(loc);
-                pkgDir.setCompleted(true);
-                n = pkgDir;
-            } else { // Link to module
-                String pkgName = loc.getParent();
-                String modName = getBaseExt(loc);
-                Node targetNode = findNode("/modules/" + modName);
-                if (targetNode != null) {
-                    String pkgDirName = packagesDir.getName() + "/" + pkgName;
-                    Directory pkgDir = (Directory) nodes.get(pkgDirName);
-                    Node linkNode = newLinkNode(pkgDir, pkgDir.getName() + "/" + modName, targetNode);
-                    n = linkNode;
-                }
-            }
-        }
-        return n;
-    }
-
-    // Asking for /packages/package/module although
-    // /packages/<pkg>/ not yet created, need to create it
-    // prior to return the link to module node.
-    private Node handleModuleLink(String name) {
-        // eg: unresolved /packages/package/module
-        // Build /packages/package node
-        Node ret = null;
-        String radical = "/packages/";
-        String path = name;
-        if (path.startsWith(radical)) {
-            int start = radical.length();
-            int pkgEnd = path.indexOf('/', start);
-            if (pkgEnd != -1) {
-                String pkg = path.substring(start, pkgEnd);
-                String pkgPath = radical + pkg;
-                Node n = findNode(pkgPath);
-                // If not found means that this is a symbolic link such as:
-                // /packages/java.util/java.base/java/util/Vector.class
-                // and will be done by a retry of the filesystem
-                for (Node child : n.getChildren()) {
-                    if (child.name.equals(name)) {
-                        ret = child;
-                        break;
-                    }
-                }
-            }
-        }
-        return ret;
-    }
-
-    private Node handleModulesSubTree(String name, ImageLocation loc) {
-        Node n;
-        assert (name.equals(loc.getFullName()));
-        Directory dir = makeDirectories(name);
-        visitLocation(loc, (childloc) -> {
-            String path = childloc.getFullName();
-            if (path.startsWith("/modules")) { // a package
-                makeDirectories(path);
-            } else { // a resource
-                makeDirectories(childloc.buildName(true, true, false));
-                newResource(dir, childloc);
-            }
-        });
-        dir.setCompleted(true);
-        n = dir;
-        return n;
-    }
-
-    private Node handleResource(String name) {
-        Node n = null;
-        String locationPath = name.substring("/modules".length());
-        ImageLocation resourceLoc = findLocation(locationPath);
-        if (resourceLoc != null) {
-            Directory dir = makeDirectories(resourceLoc.buildName(true, true, false));
-            Resource res = newResource(dir, resourceLoc);
-            n = res;
-        }
-        return n;
-    }
-
-    private String getBaseExt(ImageLocation loc) {
-        String base = loc.getBase();
-        String ext = loc.getExtension();
-        if (ext != null && !ext.isEmpty()) {
-            base = base + "." + ext;
-        }
-        return base;
-    }
-
-    public synchronized Node findNode(String name) {
-        buildRootDirectory();
-        Node n = nodes.get(name);
-        if (n == null || !n.isCompleted()) {
-            n = buildNode(name);
-        }
-        return n;
-    }
-
-    private synchronized void clearNodes() {
-        nodes.clear();
-        rootDir = null;
-    }
-
-    /**
-     * Returns the file attributes of the image file.
-     */
-    private BasicFileAttributes imageFileAttributes() {
-        BasicFileAttributes attrs = imageFileAttributes;
-        if (attrs == null) {
-            try {
-                Path file = getImagePath();
-                attrs = Files.readAttributes(file, BasicFileAttributes.class);
-            } catch (IOException ioe) {
-                throw new UncheckedIOException(ioe);
-            }
-            imageFileAttributes = attrs;
-        }
-        return attrs;
-    }
-
-    private Directory buildRootDirectory() {
-        Directory root = rootDir; // volatile read
-        if (root != null) {
-            return root;
-        }
-
-        synchronized (this) {
-            root = rootDir;
-            if (root != null) {
-                return root;
-            }
-
-            // FIXME no time information per resource in jimage file (yet?)
-            // we use file attributes of jimage itself.
-            // root directory
-            root = newDirectory(null, "/");
-            root.setIsRootDir();
-
-            // /packages dir
-            packagesDir = newDirectory(root, "/packages");
-            packagesDir.setIsPackagesDir();
-
-            // /modules dir
-            modulesDir = newDirectory(root, "/modules");
-            modulesDir.setIsModulesDir();
-
-            root.setCompleted(true);
-            return rootDir = root;
-        }
-    }
-
-    private Directory newDirectory(Directory parent, String name) {
-        Directory dir = Directory.create(parent, name, imageFileAttributes());
-        nodes.put(dir.getName(), dir);
-        return dir;
-    }
-
-    private Resource newResource(Directory parent, ImageLocation loc) {
-        Resource res = Resource.create(parent, loc, imageFileAttributes());
-        nodes.put(res.getName(), res);
-        return res;
-    }
-
-    private LinkNode newLinkNode(Directory dir, String name, Node link) {
-        LinkNode linkNode = LinkNode.create(dir, name, link);
-        nodes.put(linkNode.getName(), linkNode);
-        return linkNode;
-    }
-
-    private Directory makeDirectories(String parent) {
-        Directory last = rootDir;
-        for (int offset = parent.indexOf('/', 1);
-                offset != -1;
-                offset = parent.indexOf('/', offset + 1)) {
-            String dir = parent.substring(0, offset);
-            last = makeDirectory(dir, last);
-        }
-        return makeDirectory(parent, last);
-
-    }
-
-    private Directory makeDirectory(String dir, Directory last) {
-        Directory nextDir = (Directory) nodes.get(dir);
-        if (nextDir == null) {
-            nextDir = newDirectory(last, dir);
-        }
-        return nextDir;
-    }
-
-    public byte[] getResource(Node node) throws IOException {
-        if (node.isResource()) {
-            return super.getResource(node.getLocation());
-        }
-        throw new IOException("Not a resource: " + node);
-    }
-
-    public byte[] getResource(Resource rs) throws IOException {
-        return super.getResource(rs.getLocation());
-    }
 }
--- a/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystem.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystem.java	Thu Apr 28 23:08:16 2016 -0700
@@ -299,13 +299,9 @@
     }
 
     // clean up this file system - called from finalize and close
-    void cleanup() throws IOException {
-        if (!isOpen) {
-            return;
-        }
-        synchronized (this) {
+    synchronized void cleanup() throws IOException {
+        if (isOpen) {
             isOpen = false;
-            // close image reader and null out
             image.close();
             image = null;
         }
@@ -461,8 +457,8 @@
     private Node lookup(String path) {
         try {
             return image.findNode(path);
-        } catch (RuntimeException re) {
-            throw new InvalidPathException(path, re.toString());
+        } catch (RuntimeException | IOException ex) {
+            throw new InvalidPathException(path, ex.toString());
         }
     }
 
--- a/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystemProvider.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystemProvider.java	Thu Apr 28 23:08:16 2016 -0700
@@ -101,10 +101,10 @@
     @Override
     public FileSystem newFileSystem(URI uri, Map<String, ?> env)
             throws IOException {
+        Objects.requireNonNull(env);
         checkPermission();
         checkUri(uri);
-
-        if (env != null && env.containsKey("java.home")) {
+        if (env.containsKey("java.home")) {
             return newFileSystem((String)env.get("java.home"), uri, env);
         } else {
             return new JrtFileSystem(this, env);
--- a/jdk/src/java.base/share/classes/jdk/internal/jrtfs/SystemImage.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/jdk/internal/jrtfs/SystemImage.java	Thu Apr 28 23:08:16 2016 -0700
@@ -49,7 +49,7 @@
  */
 abstract class SystemImage {
 
-    abstract Node findNode(String path);
+    abstract Node findNode(String path) throws IOException;
     abstract byte[] getResource(Node node) throws IOException;
     abstract void close() throws IOException;
 
@@ -60,7 +60,7 @@
             image.getRootDirectory();
             return new SystemImage() {
                 @Override
-                Node findNode(String path) {
+                Node findNode(String path) throws IOException {
                     return image.findNode(path);
                 }
                 @Override
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/BootLoader.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/jdk/internal/loader/BootLoader.java	Thu Apr 28 23:08:16 2016 -0700
@@ -30,6 +30,7 @@
 import java.lang.reflect.Layer;
 import java.lang.reflect.Module;
 import java.net.MalformedURLException;
+import java.net.URI;
 import java.net.URL;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -184,9 +185,9 @@
 
         /**
          * Define the {@code Package} with the given name. The specified
-         * location is a jrt URL to a named module in the run-time image, a
-         * file path to a module in an exploded run-time image, or the file
-         * path to an enty on the boot class path (java agent Boot-Class-Path
+         * location is a jrt URL to a named module in the run-time image,
+         * a file URL to a module in an exploded run-time image, or a file
+         * path to an entry on the boot class path (java agent Boot-Class-Path
          * or -Xbootclasspath/a.
          *
          * <p> If the given location is a JAR file containing a manifest,
@@ -194,7 +195,9 @@
          * the manifest, if present.
          *
          * @param name     package name
-         * @param location location where the package is (jrt URL or file path)
+         * @param location location where the package is (jrt URL or file URL
+         *                 for a named module in the run-time or exploded image;
+         *                 a file path for a package from -Xbootclasspath/a)
          */
         static Package definePackage(String name, String location) {
             Module module = findModule(location);
@@ -222,9 +225,9 @@
             if (location.startsWith("jrt:/")) {
                 // named module in runtime image ("jrt:/".length() == 5)
                 mn = location.substring(5, location.length());
-            } else {
+            } else if (location.startsWith("file:/")) {
                 // named module in exploded image
-                Path path = Paths.get(location);
+                Path path = Paths.get(URI.create(location));
                 Path modulesDir = Paths.get(JAVA_HOME, "modules");
                 if (path.startsWith(modulesDir)) {
                     mn = path.getFileName().toString();
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java	Thu Apr 28 23:08:16 2016 -0700
@@ -52,6 +52,7 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.NoSuchElementException;
+import java.util.Properties;
 import java.util.Set;
 import java.util.Stack;
 import java.util.StringTokenizer;
@@ -69,6 +70,7 @@
 import jdk.internal.util.jar.JarIndex;
 import sun.net.util.URLUtil;
 import sun.net.www.ParseUtil;
+import sun.security.action.GetPropertyAction;
 
 /**
  * This class is used to maintain a search path of URLs for loading classes
@@ -78,20 +80,15 @@
  */
 public class URLClassPath {
     private static final String USER_AGENT_JAVA_VERSION = "UA-Java-Version";
-    private static final String JAVA_HOME;
     private static final String JAVA_VERSION;
     private static final boolean DEBUG;
     private static final boolean DISABLE_JAR_CHECKING;
 
     static {
-        JAVA_HOME = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction("java.home"));
-        JAVA_VERSION = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction("java.version"));
-        DEBUG        = (java.security.AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction("sun.misc.URLClassPath.debug")) != null);
-        String p = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction("sun.misc.URLClassPath.disableJarChecking"));
+        Properties props = GetPropertyAction.getProperties();
+        JAVA_VERSION = props.getProperty("java.version");
+        DEBUG = (props.getProperty("sun.misc.URLClassPath.debug") != null);
+        String p = props.getProperty("sun.misc.URLClassPath.disableJarChecking");
         DISABLE_JAR_CHECKING = p != null ? p.equals("true") || p.equals("") : false;
     }
 
--- a/jdk/src/java.base/share/classes/jdk/internal/logger/DefaultLoggerFinder.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/jdk/internal/logger/DefaultLoggerFinder.java	Thu Apr 28 23:08:16 2016 -0700
@@ -33,6 +33,9 @@
 import java.lang.System.LoggerFinder;
 import java.lang.System.Logger;
 import java.lang.ref.ReferenceQueue;
+import java.lang.reflect.Module;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.Collection;
 import java.util.ResourceBundle;
 
@@ -129,41 +132,49 @@
             return w;
         }
 
-
         final static SharedLoggers system = new SharedLoggers();
         final static SharedLoggers application = new SharedLoggers();
     }
 
+    public static boolean isSystem(Module m) {
+        ClassLoader cl = AccessController.doPrivileged(new PrivilegedAction<>() {
+            @Override
+            public ClassLoader run() {
+                return m.getClassLoader();
+            }
+        });
+        return cl == null;
+    }
+
     @Override
-    public final Logger getLogger(String name,  /* Module */ Class<?> caller) {
+    public final Logger getLogger(String name,  Module module) {
         checkPermission();
-        return demandLoggerFor(name, caller);
+        return demandLoggerFor(name, module);
     }
 
     @Override
     public final Logger getLocalizedLogger(String name, ResourceBundle bundle,
-                                           /* Module */  Class<?> caller) {
-        return super.getLocalizedLogger(name, bundle, caller);
+                                           Module module) {
+        return super.getLocalizedLogger(name, bundle, module);
     }
 
-
-
     /**
-     * Returns a {@link Logger logger} suitable for the caller usage.
+     * Returns a {@link Logger logger} suitable for use within the
+     * given {@code module}.
      *
      * @implSpec The default implementation for this method is to return a
      *    simple logger that will print all messages of INFO level and above
      *    to the console. That simple logger is not configurable.
      *
      * @param name The name of the logger.
-     * @param caller The class on behalf of which the logger is created.
+     * @param module The module on behalf of which the logger is created.
      * @return A {@link Logger logger} suitable for the application usage.
      * @throws SecurityException if the calling code does not have the
      * {@code RuntimePermission("loggerFinder")}.
      */
-    protected Logger demandLoggerFor(String name, /* Module */ Class<?> caller) {
+    protected Logger demandLoggerFor(String name, Module module) {
         checkPermission();
-        if (caller.getClassLoader() == null) {
+        if (isSystem(module)) {
             return SharedLoggers.system.get(SimpleConsoleLogger::makeSimpleLogger, name);
         } else {
             return SharedLoggers.application.get(SimpleConsoleLogger::makeSimpleLogger, name);
--- a/jdk/src/java.base/share/classes/jdk/internal/logger/LazyLoggers.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/jdk/internal/logger/LazyLoggers.java	Thu Apr 28 23:08:16 2016 -0700
@@ -31,6 +31,7 @@
 import java.lang.System.LoggerFinder;
 import java.lang.System.Logger;
 import java.lang.ref.WeakReference;
+import java.lang.reflect.Module;
 import java.util.Objects;
 import jdk.internal.misc.VM;
 import sun.util.logging.PlatformLogger;
@@ -59,15 +60,15 @@
          * A factory method to create an SPI logger.
          * Usually, this will be something like LazyLoggers::getSystemLogger.
          */
-        final BiFunction<String, Class<?>, L> loggerSupplier;
+        final BiFunction<String, Module, L> loggerSupplier;
 
 
-        public LazyLoggerFactories(BiFunction<String, Class<?>, L> loggerSupplier) {
+        public LazyLoggerFactories(BiFunction<String, Module, L> loggerSupplier) {
             this(Objects.requireNonNull(loggerSupplier),
                  (Void)null);
         }
 
-        private LazyLoggerFactories(BiFunction<String, Class<?>, L> loggerSupplier,
+        private LazyLoggerFactories(BiFunction<String, Module, L> loggerSupplier,
                           Void unused) {
             this.loggerSupplier = loggerSupplier;
         }
@@ -107,8 +108,8 @@
         // The factories that will be used to create the logger lazyly
         final LazyLoggerFactories<? extends Logger> factories;
 
-        // We need to pass the actual caller when creating the logger.
-        private final WeakReference<Class<?>> callerRef;
+        // We need to pass the actual caller module when creating the logger.
+        private final WeakReference<Module> moduleRef;
 
         // The name of the logger that will be created lazyly
         final String name;
@@ -121,17 +122,17 @@
 
         private LazyLoggerAccessor(String name,
                                    LazyLoggerFactories<? extends Logger> factories,
-                                   Class<?> caller) {
+                                   Module module) {
             this(Objects.requireNonNull(name), Objects.requireNonNull(factories),
-                    Objects.requireNonNull(caller), null);
+                    Objects.requireNonNull(module), null);
         }
 
         private LazyLoggerAccessor(String name,
                                    LazyLoggerFactories<? extends Logger> factories,
-                                   Class<?> caller, Void unused) {
+                                   Module module, Void unused) {
             this.name = name;
             this.factories = factories;
-            this.callerRef = new WeakReference<Class<?>>(caller);
+            this.moduleRef = new WeakReference<>(module);
         }
 
         /**
@@ -270,12 +271,12 @@
 
         // Creates the wrapped logger by invoking the SPI.
         Logger createLogger() {
-            final Class<?> caller = callerRef.get();
-            if (caller == null) {
-                throw new IllegalStateException("The class for which this logger"
+            final Module module = moduleRef.get();
+            if (module == null) {
+                throw new IllegalStateException("The module for which this logger"
                         + " was created has been garbage collected");
             }
-            return this.factories.loggerSupplier.apply(name, caller);
+            return this.factories.loggerSupplier.apply(name, module);
         }
 
         /**
@@ -289,8 +290,8 @@
          * @return A new LazyLoggerAccessor.
          */
         public static LazyLoggerAccessor makeAccessor(String name,
-                LazyLoggerFactories<? extends Logger> factories, Class<?> caller) {
-                return new LazyLoggerAccessor(name, factories, caller);
+                LazyLoggerFactories<? extends Logger> factories, Module module) {
+                return new LazyLoggerAccessor(name, factories, module);
         }
 
     }
@@ -346,11 +347,11 @@
 
     // Avoid using lambda here as lazy loggers could be created early
     // in the bootstrap sequence...
-    private static final BiFunction<String, Class<?>, Logger> loggerSupplier =
+    private static final BiFunction<String, Module, Logger> loggerSupplier =
            new BiFunction<>() {
         @Override
-        public Logger apply(String name, Class<?> caller) {
-            return LazyLoggers.getLoggerFromFinder(name, caller);
+        public Logger apply(String name, Module module) {
+            return LazyLoggers.getLoggerFromFinder(name, module);
         }
     };
 
@@ -367,8 +368,8 @@
     // logger provider until the VM has finished booting.
     //
     private static final class JdkLazyLogger extends LazyLoggerWrapper {
-        JdkLazyLogger(String name, Class<?> caller) {
-            this(LazyLoggerAccessor.makeAccessor(name, factories, caller),
+        JdkLazyLogger(String name, Module module) {
+            this(LazyLoggerAccessor.makeAccessor(name, factories, module),
                  (Void)null);
         }
         private JdkLazyLogger(LazyLoggerAccessor holder, Void unused) {
@@ -380,16 +381,16 @@
      * Gets a logger from the LoggerFinder. Creates the actual concrete
      * logger.
      * @param name    name of the logger
-     * @param caller  class on behalf of which the logger is created
+     * @param module  module on behalf of which the logger is created
      * @return  The logger returned by the LoggerFinder.
      */
-    static Logger getLoggerFromFinder(String name, Class<?> caller) {
+    static Logger getLoggerFromFinder(String name, Module module) {
         final SecurityManager sm = System.getSecurityManager();
         if (sm == null) {
-            return accessLoggerFinder().getLogger(name, caller);
+            return accessLoggerFinder().getLogger(name, module);
         } else {
             return AccessController.doPrivileged((PrivilegedAction<Logger>)
-                    () -> {return accessLoggerFinder().getLogger(name, caller);},
+                    () -> {return accessLoggerFinder().getLogger(name, module);},
                     null, LOGGERFINDER_PERMISSION);
         }
     }
@@ -398,22 +399,22 @@
      * Returns a (possibly lazy) Logger for the caller.
      *
      * @param name the logger name
-     * @param caller The class on behalf of which the logger is created.
-     *               If the caller is not loaded from the Boot ClassLoader,
+     * @param module The module on behalf of which the logger is created.
+     *               If the module is not loaded from the Boot ClassLoader,
      *               the LoggerFinder is accessed and the logger returned
-     *               by {@link LoggerFinder#getLogger(java.lang.String, java.lang.Class)}
+     *               by {@link LoggerFinder#getLogger(java.lang.String, java.lang.reflect.Module)}
      *               is returned to the caller directly.
      *               Otherwise, the logger returned by
-     *               {@link #getLazyLogger(java.lang.String, java.lang.Class)}
+     *               {@link #getLazyLogger(java.lang.String, java.lang.reflect.Module)}
      *               is returned to the caller.
      *
      * @return  a (possibly lazy) Logger instance.
      */
-    public static final Logger getLogger(String name, Class<?> caller) {
-        if (caller.getClassLoader() == null) {
-            return getLazyLogger(name, caller);
+    public static final Logger getLogger(String name, Module module) {
+        if (DefaultLoggerFinder.isSystem(module)) {
+            return getLazyLogger(name, module);
         } else {
-            return getLoggerFromFinder(name, caller);
+            return getLoggerFromFinder(name, module);
         }
     }
 
@@ -423,10 +424,10 @@
      * returned by {@link BootstrapLogger#useLazyLoggers()}.
      *
      * @param name the logger name
-     * @param caller the class on behalf of which the logger is created.
+     * @param module the module on behalf of which the logger is created.
      * @return  a (possibly lazy) Logger instance.
      */
-    public static final Logger getLazyLogger(String name, Class<?> caller) {
+    public static final Logger getLazyLogger(String name, Module module) {
 
         // BootstrapLogger has the logic to determine whether a LazyLogger
         // should be used. Usually, it is worth it only if:
@@ -438,10 +439,10 @@
         // configuration, we're not going to delay the creation of loggers...
         final boolean useLazyLogger = BootstrapLogger.useLazyLoggers();
         if (useLazyLogger) {
-            return new JdkLazyLogger(name, caller);
+            return new JdkLazyLogger(name, module);
         } else {
             // Directly invoke the LoggerFinder.
-            return getLoggerFromFinder(name, caller);
+            return getLoggerFromFinder(name, module);
         }
     }
 
--- a/jdk/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java	Thu Apr 28 23:08:16 2016 -0700
@@ -33,6 +33,7 @@
 import java.util.ServiceConfigurationError;
 import java.util.ServiceLoader;
 import sun.security.util.SecurityConstants;
+import sun.security.action.GetPropertyAction;
 
 /**
  * Helper class used to load the {@link java.lang.System.LoggerFinder}.
@@ -79,9 +80,8 @@
 
     // Get configuration error policy
     private static ErrorPolicy configurationErrorPolicy() {
-        final PrivilegedAction<String> getConfigurationErrorPolicy =
-                () -> System.getProperty("jdk.logger.finder.error");
-        String errorPolicy = AccessController.doPrivileged(getConfigurationErrorPolicy);
+        String errorPolicy =
+                GetPropertyAction.getProperty("jdk.logger.finder.error");
         if (errorPolicy == null || errorPolicy.isEmpty()) {
             return ErrorPolicy.WARNING;
         }
@@ -95,9 +95,8 @@
     // Whether multiple provider should be considered as an error.
     // This is further submitted to the configuration error policy.
     private static boolean ensureSingletonProvider() {
-        final PrivilegedAction<Boolean> ensureSingletonProvider =
-                () -> Boolean.getBoolean("jdk.logger.finder.singleton");
-        return AccessController.doPrivileged(ensureSingletonProvider);
+        return Boolean.parseBoolean(
+                GetPropertyAction.getProperty("jdk.logger.finder.singleton"));
     }
 
     private static Iterator<System.LoggerFinder> findLoggerFinderProviders() {
--- a/jdk/src/java.base/share/classes/jdk/internal/logger/SimpleConsoleLogger.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/jdk/internal/logger/SimpleConsoleLogger.java	Thu Apr 28 23:08:16 2016 -0700
@@ -55,8 +55,8 @@
             PlatformLogger.toPlatformLevel(DEFAULT_LEVEL);
 
     static Level getDefaultLevel() {
-        String levelName = AccessController.doPrivileged(
-                new GetPropertyAction("jdk.system.logger.level", "INFO"));
+        String levelName = GetPropertyAction
+                .getProperty("jdk.system.logger.level", "INFO");
         try {
             return Level.valueOf(levelName);
         } catch (IllegalArgumentException iae) {
@@ -425,8 +425,8 @@
         // Make it easier to wrap Logger...
         static private final String[] skips;
         static {
-            String additionalPkgs = AccessController.doPrivileged(
-                new GetPropertyAction("jdk.logger.packages"));
+            String additionalPkgs =
+                    GetPropertyAction.getProperty("jdk.logger.packages");
             skips = additionalPkgs == null ? new String[0] : additionalPkgs.split(",");
         }
 
@@ -485,7 +485,7 @@
             //    jdk/test/java/lang/invoke/lambda/LogGeneratedClassesTest.java
             // to fail - because that test has a testcase which somehow references
             // PlatformLogger and counts the number of generated lambda classes.
-            String format = AccessController.doPrivileged(new GetPropertyAction(key));
+            String format = GetPropertyAction.getProperty(key);
 
             if (format == null && defaultPropertyGetter != null) {
                 format = defaultPropertyGetter.apply(key);
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java	Thu Apr 28 23:08:16 2016 -0700
@@ -30,4 +30,9 @@
      * Create a new MemberName instance
      */
     Object newMemberName();
+
+    /**
+     * Returns the name for the given MemberName
+     */
+    String getName(Object mname);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaObjectInputStreamAccess.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016, 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 jdk.internal.misc;
+
+import java.io.ObjectInputStream;
+
+/**
+ * The interface to specify methods for accessing {@code ObjectInputStream}
+ * @author sjiang
+ */
+public interface JavaObjectInputStreamAccess {
+    /**
+     * Sets a descriptor validating.
+     * @param ois stream to have the descriptors validated
+     * @param validator validator used to validate a descriptor.
+     */
+    public void setValidator(ObjectInputStream ois, ObjectStreamClassValidator validator);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/ObjectStreamClassValidator.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016, 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 jdk.internal.misc;
+
+import java.io.ObjectStreamClass;
+
+/**
+ * A callback used by {@code ObjectInputStream} to do descriptor validation.
+ *
+ * @author sjiang
+ */
+public interface ObjectStreamClassValidator {
+    /**
+     * This method will be called by ObjectInputStream to
+     * check a descriptor just before creating an object described by this descriptor.
+     * The object will not be created if this method throws a {@code RuntimeException}.
+     * @param descriptor descriptor to be checked.
+     */
+    public void validateDescriptor(ObjectStreamClass descriptor);
+}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, 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,9 @@
 import java.util.jar.JarFile;
 import java.io.Console;
 import java.io.FileDescriptor;
+import java.io.ObjectInputStream;
 import java.security.ProtectionDomain;
 import java.security.AccessController;
-import jdk.internal.misc.Unsafe;
 
 /** A repository of "shared secrets", which are a mechanism for
     calling implementation-private methods in another package without
@@ -63,6 +63,7 @@
     private static JavaAWTAccess javaAWTAccess;
     private static JavaAWTFontAccess javaAWTFontAccess;
     private static JavaBeansAccess javaBeansAccess;
+    private static JavaObjectInputStreamAccess javaObjectInputStreamAccess;
 
     public static JavaUtilJarAccess javaUtilJarAccess() {
         if (javaUtilJarAccess == null) {
@@ -262,4 +263,15 @@
     public static void setJavaUtilResourceBundleAccess(JavaUtilResourceBundleAccess access) {
         javaUtilResourceBundleAccess = access;
     }
+
+    public static JavaObjectInputStreamAccess getJavaObjectInputStreamAccess() {
+        if (javaObjectInputStreamAccess == null) {
+            unsafe.ensureClassInitialized(ObjectInputStream.class);
+        }
+        return javaObjectInputStreamAccess;
+    }
+
+    public static void setJavaObjectInputStreamAccess(JavaObjectInputStreamAccess access) {
+        javaObjectInputStreamAccess = access;
+    }
 }
--- a/jdk/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Opcodes.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Opcodes.java	Thu Apr 28 23:08:16 2016 -0700
@@ -70,6 +70,7 @@
  * @author Eric Bruneton
  * @author Eugene Kuleshov
  */
+@SuppressWarnings("deprecation") // for Integer(int) constructor
 public interface Opcodes {
 
     // ASM API versions
@@ -176,6 +177,8 @@
      */
     int F_SAME1 = 4;
 
+    // For reference comparison purposes, construct new instances
+    // instead of using valueOf() or autoboxing.
     Integer TOP = new Integer(0);
     Integer INTEGER = new Integer(1);
     Integer FLOAT = new Integer(2);
--- a/jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java	Thu Apr 28 23:08:16 2016 -0700
@@ -27,13 +27,12 @@
 
 
 import java.lang.reflect.*;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
 import jdk.internal.HotSpotIntrinsicCandidate;
 import jdk.internal.misc.VM;
+import sun.security.action.GetPropertyAction;
 
 /** Common utility routines used by both java.lang and
     java.lang.reflect */
@@ -344,15 +343,10 @@
 
     private static void printStackTraceIfNeeded(Throwable e) {
         if (!printStackWhenAccessFailsSet && VM.initLevel() >= 1) {
-            // can't use method reference here, might be too early in startup
-            PrivilegedAction<Boolean> pa = new PrivilegedAction<Boolean>() {
-                public Boolean run() {
-                    String s;
-                    s = System.getProperty("sun.reflect.debugModuleAccessChecks");
-                    return (s != null && !s.equalsIgnoreCase("false"));
-                }
-            };
-            printStackWhenAccessFails = AccessController.doPrivileged(pa);
+            String s = GetPropertyAction
+                    .getProperty("sun.reflect.debugModuleAccessChecks");
+            printStackWhenAccessFails =
+                    (s != null && !s.equalsIgnoreCase("false"));
             printStackWhenAccessFailsSet = true;
         }
         if (printStackWhenAccessFails) {
--- a/jdk/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java	Thu Apr 28 23:08:16 2016 -0700
@@ -30,10 +30,11 @@
 import java.lang.reflect.Method;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Modifier;
-import java.security.AccessController;
 import java.security.Permission;
 import java.security.PrivilegedAction;
+import java.util.Properties;
 import sun.reflect.misc.ReflectUtil;
+import sun.security.action.GetPropertyAction;
 
 /** <P> The master factory for all reflective objects, both those in
     java.lang.reflect (Fields, Methods, Constructors) as well as their
@@ -382,41 +383,37 @@
         run, before the system properties are set up. */
     private static void checkInitted() {
         if (initted) return;
-        AccessController.doPrivileged(
-            new PrivilegedAction<>() {
-                public Void run() {
-                    // Tests to ensure the system properties table is fully
-                    // initialized. This is needed because reflection code is
-                    // called very early in the initialization process (before
-                    // command-line arguments have been parsed and therefore
-                    // these user-settable properties installed.) We assume that
-                    // if System.out is non-null then the System class has been
-                    // fully initialized and that the bulk of the startup code
-                    // has been run.
 
-                    if (System.out == null) {
-                        // java.lang.System not yet fully initialized
-                        return null;
-                    }
+        // Tests to ensure the system properties table is fully
+        // initialized. This is needed because reflection code is
+        // called very early in the initialization process (before
+        // command-line arguments have been parsed and therefore
+        // these user-settable properties installed.) We assume that
+        // if System.out is non-null then the System class has been
+        // fully initialized and that the bulk of the startup code
+        // has been run.
+
+        if (System.out == null) {
+            // java.lang.System not yet fully initialized
+            return;
+        }
 
-                    String val = System.getProperty("sun.reflect.noInflation");
-                    if (val != null && val.equals("true")) {
-                        noInflation = true;
-                    }
+        Properties props = GetPropertyAction.getProperties();
+        String val = props.getProperty("sun.reflect.noInflation");
+        if (val != null && val.equals("true")) {
+            noInflation = true;
+        }
 
-                    val = System.getProperty("sun.reflect.inflationThreshold");
-                    if (val != null) {
-                        try {
-                            inflationThreshold = Integer.parseInt(val);
-                        } catch (NumberFormatException e) {
-                            throw new RuntimeException("Unable to parse property sun.reflect.inflationThreshold", e);
-                        }
-                    }
+        val = props.getProperty("sun.reflect.inflationThreshold");
+        if (val != null) {
+            try {
+                inflationThreshold = Integer.parseInt(val);
+            } catch (NumberFormatException e) {
+                throw new RuntimeException("Unable to parse property sun.reflect.inflationThreshold", e);
+            }
+        }
 
-                    initted = true;
-                    return null;
-                }
-            });
+        initted = true;
     }
 
     private static LangReflectAccess langReflectAccess() {
--- a/jdk/src/java.base/share/classes/jdk/net/ExtendedSocketOptions.java	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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 jdk.net;
-
-import java.net.SocketOption;
-
-/**
- * Defines extended socket options, beyond those defined in
- * {@link java.net.StandardSocketOptions}. These options may be platform
- * specific.
- *
- * @since 1.8
- */
-public final class ExtendedSocketOptions {
-
-    private static class ExtSocketOption<T> implements SocketOption<T> {
-        private final String name;
-        private final Class<T> type;
-        ExtSocketOption(String name, Class<T> type) {
-            this.name = name;
-            this.type = type;
-        }
-        @Override public String name() { return name; }
-        @Override public Class<T> type() { return type; }
-        @Override public String toString() { return name; }
-    }
-
-    private ExtendedSocketOptions() {}
-
-    /**
-     * Service level properties. When a security manager is installed,
-     * setting or getting this option requires a {@link NetworkPermission}
-     * {@code ("setOption.SO_FLOW_SLA")} or {@code "getOption.SO_FLOW_SLA"}
-     * respectively.
-     */
-    public static final SocketOption<SocketFlow> SO_FLOW_SLA = new
-        ExtSocketOption<SocketFlow>("SO_FLOW_SLA", SocketFlow.class);
-}
--- a/jdk/src/java.base/share/classes/jdk/net/NetworkPermission.java	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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 jdk.net;
-
-import java.security.BasicPermission;
-
-/**
- * Represents permission to access the extended networking capabilities
- * defined in the jdk.net package. These permissions contain a target
- * name, but no actions list. Callers either possess the permission or not.
- * <p>
- * The following targets are defined:
- *
- * <table border=1 cellpadding=5 summary="permission target name,
- *  what the target allows,and associated risks">
- * <tr>
- *   <th>Permission Target Name</th>
- *   <th>What the Permission Allows</th>
- *   <th>Risks of Allowing this Permission</th>
- * </tr>
- * <tr>
- *   <td>setOption.SO_FLOW_SLA</td>
- *   <td>set the {@link ExtendedSocketOptions#SO_FLOW_SLA SO_FLOW_SLA} option
- *       on any socket that supports it</td>
- *   <td>allows caller to set a higher priority or bandwidth allocation
- *       to sockets it creates, than they might otherwise be allowed.</td>
- * </tr>
- * <tr>
- *   <td>getOption.SO_FLOW_SLA</td>
- *   <td>retrieve the {@link ExtendedSocketOptions#SO_FLOW_SLA SO_FLOW_SLA}
- *       setting from any socket that supports the option</td>
- *   <td>allows caller access to SLA information that it might not
- *       otherwise have</td>
- * </tr></table>
- *
- * @see jdk.net.ExtendedSocketOptions
- *
- * @since 1.8
- */
-
-public final class NetworkPermission extends BasicPermission {
-
-    private static final long serialVersionUID = -2012939586906722291L;
-
-    /**
-     * Creates a NetworkPermission with the given target name.
-     *
-     * @param name the permission target name
-     * @throws NullPointerException if {@code name} is {@code null}.
-     * @throws IllegalArgumentException if {@code name} is empty.
-     */
-    public NetworkPermission(String name)
-    {
-        super(name);
-    }
-
-    /**
-     * Creates a NetworkPermission with the given target name.
-     *
-     * @param name the permission target name
-     * @param actions should be {@code null}. Is ignored if not.
-     * @throws NullPointerException if {@code name} is {@code null}.
-     * @throws IllegalArgumentException if {@code name} is empty.
-     */
-    public NetworkPermission(String name, String actions)
-    {
-        super(name, actions);
-    }
-}
--- a/jdk/src/java.base/share/classes/jdk/net/SocketFlow.java	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,167 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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 jdk.net;
-
-import java.lang.annotation.Native;
-
-/**
- * Represents the service level properties for the platform specific socket
- * option {@link ExtendedSocketOptions#SO_FLOW_SLA}.
- * <p>
- * The priority and bandwidth parameters must be set before
- * setting the socket option.
- * <p>
- * When the {@code SO_FLOW_SLA} option is set then it may not take effect
- * immediately. If the value of the socket option is obtained with
- * {@code getOption()} then the status may be returned as {@code INPROGRESS}
- * until it takes effect. The priority and bandwidth values are only valid when
- * the status is returned as OK.
- * <p>
- * When a security manager is installed, a {@link NetworkPermission}
- * is required to set or get this option.
- *
- * @since 1.8
- */
-public class SocketFlow {
-
-    private static final int UNSET = -1;
-    @Native public static final int NORMAL_PRIORITY = 1;
-    @Native public static final int HIGH_PRIORITY = 2;
-
-    private int priority = NORMAL_PRIORITY;
-
-    private long bandwidth = UNSET;
-
-    private Status status = Status.NO_STATUS;
-
-    private SocketFlow() {}
-
-    /**
-     * Enumeration of the return values from the SO_FLOW_SLA
-     * socket option. Both setting and getting the option return
-     * one of these statuses, which reflect the state of socket's
-     * flow.
-     *
-     * @since 1.8
-     */
-    public enum Status {
-        /**
-         * Set or get socket option has not been called yet. Status
-         * values can only be retrieved after calling set or get.
-         */
-        NO_STATUS,
-        /**
-         * Flow successfully created.
-         */
-        OK,
-        /**
-         * Caller has no permission to create flow.
-         */
-        NO_PERMISSION,
-        /**
-         * Flow can not be created because socket is not connected.
-         */
-        NOT_CONNECTED,
-        /**
-         * Flow creation not supported for this socket.
-         */
-        NOT_SUPPORTED,
-        /**
-         * A flow already exists with identical attributes.
-         */
-        ALREADY_CREATED,
-        /**
-         * A flow is being created.
-         */
-        IN_PROGRESS,
-        /**
-         * Some other unspecified error.
-         */
-        OTHER
-    }
-
-    /**
-     * Creates a new SocketFlow that can be used to set the SO_FLOW_SLA
-     * socket option and create a socket flow.
-     */
-    public static SocketFlow create() {
-        return new SocketFlow();
-    }
-
-    /**
-     * Sets this SocketFlow's priority. Must be either NORMAL_PRIORITY
-     * HIGH_PRIORITY. If not set, a flow's priority is normal.
-     *
-     * @throws IllegalArgumentException if priority is not NORMAL_PRIORITY or
-     *         HIGH_PRIORITY.
-     */
-    public SocketFlow priority(int priority) {
-        if (priority != NORMAL_PRIORITY && priority != HIGH_PRIORITY) {
-            throw new IllegalArgumentException("invalid priority");
-        }
-        this.priority = priority;
-        return this;
-    }
-
-    /**
-     * Sets this SocketFlow's bandwidth. Must be greater than or equal to zero.
-     * A value of zero drops all packets for the socket.
-     *
-     * @throws IllegalArgumentException if bandwidth is less than zero.
-     */
-    public SocketFlow bandwidth(long bandwidth) {
-        if (bandwidth < 0) {
-            throw new IllegalArgumentException("invalid bandwidth");
-        } else {
-            this.bandwidth = bandwidth;
-        }
-        return this;
-    }
-
-    /**
-     * Returns this SocketFlow's priority.
-     */
-    public int priority() {
-        return priority;
-    }
-
-    /**
-     * Returns this SocketFlow's bandwidth.
-     *
-     * @return this SocketFlow's bandwidth, or {@code -1} if status is not OK.
-     */
-    public long bandwidth() {
-        return bandwidth;
-    }
-
-    /**
-     * Returns the Status value of this SocketFlow. NO_STATUS is returned
-     * if the object was not used in a call to set or get the option.
-     */
-    public Status status() {
-        return status;
-    }
-}
--- a/jdk/src/java.base/share/classes/jdk/net/Sockets.java	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,339 +0,0 @@
-/*
- * Copyright (c) 2016, 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 jdk.net;
-
-import java.net.*;
-import java.io.IOException;
-import java.io.FileDescriptor;
-import java.security.PrivilegedAction;
-import java.security.AccessController;
-import java.lang.reflect.Field;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.Collections;
-import sun.net.ExtendedOptionsImpl;
-
-/**
- * Defines static methods to set and get socket options defined by the
- * {@link java.net.SocketOption} interface. All of the standard options defined
- * by {@link java.net.Socket}, {@link java.net.ServerSocket}, and
- * {@link java.net.DatagramSocket} can be set this way, as well as additional
- * or platform specific options supported by each socket type.
- * <p>
- * The {@link #supportedOptions(Class)} method can be called to determine
- * the complete set of options available (per socket type) on the
- * current system.
- * <p>
- * When a security manager is installed, some non-standard socket options
- * may require a security permission before being set or get.
- * The details are specified in {@link ExtendedSocketOptions}. No permission
- * is required for {@link java.net.StandardSocketOptions}.
- *
- * @see java.nio.channels.NetworkChannel
- */
-public class Sockets {
-
-    private static final HashMap<Class<?>,Set<SocketOption<?>>>
-        options = new HashMap<>();
-
-    static {
-        initOptionSets();
-    }
-
-    private Sockets() {}
-
-    /**
-     * Sets the value of a socket option on a {@link java.net.Socket}
-     *
-     * @param s the socket
-     * @param name The socket option
-     * @param value The value of the socket option. May be null for some
-     *              options.
-     *
-     * @throws UnsupportedOperationException if the socket does not support
-     *         the option.
-     *
-     * @throws IllegalArgumentException if the value is not valid for
-     *         the option.
-     *
-     * @throws IOException if an I/O error occurs, or socket is closed.
-     *
-     * @throws SecurityException if a security manager is set and the
-     *         caller does not have any required permission.
-     *
-     * @throws NullPointerException if name is null
-     *
-     * @see java.net.StandardSocketOptions
-     */
-    public static <T> void setOption(Socket s, SocketOption<T> name, T value) throws IOException
-    {
-        s.setOption(name, value);
-    }
-
-    /**
-     * Returns the value of a socket option from a {@link java.net.Socket}
-     *
-     * @param s the socket
-     * @param name The socket option
-     *
-     * @return The value of the socket option.
-     *
-     * @throws UnsupportedOperationException if the socket does not support
-     *         the option.
-     *
-     * @throws IOException if an I/O error occurs
-     *
-     * @throws SecurityException if a security manager is set and the
-     *         caller does not have any required permission.
-     *
-     * @throws NullPointerException if name is null
-     *
-     * @see java.net.StandardSocketOptions
-     */
-    public static <T> T getOption(Socket s, SocketOption<T> name) throws IOException
-    {
-        return s.getOption(name);
-    }
-
-    /**
-     * Sets the value of a socket option on a {@link java.net.ServerSocket}
-     *
-     * @param s the socket
-     * @param name The socket option
-     * @param value The value of the socket option.
-     *
-     * @throws UnsupportedOperationException if the socket does not support
-     *         the option.
-     *
-     * @throws IllegalArgumentException if the value is not valid for
-     *         the option.
-     *
-     * @throws IOException if an I/O error occurs
-     *
-     * @throws NullPointerException if name is null
-     *
-     * @throws SecurityException if a security manager is set and the
-     *         caller does not have any required permission.
-     *
-     * @see java.net.StandardSocketOptions
-     */
-    public static <T> void setOption(ServerSocket s, SocketOption<T> name, T value) throws IOException
-    {
-        s.setOption(name, value);
-    }
-
-    /**
-     * Returns the value of a socket option from a {@link java.net.ServerSocket}
-     *
-     * @param s the socket
-     * @param name The socket option
-     *
-     * @return The value of the socket option.
-     *
-     * @throws UnsupportedOperationException if the socket does not support
-     *         the option.
-     *
-     * @throws IOException if an I/O error occurs
-     *
-     * @throws NullPointerException if name is null
-     *
-     * @throws SecurityException if a security manager is set and the
-     *         caller does not have any required permission.
-     *
-     * @see java.net.StandardSocketOptions
-     */
-    public static <T> T getOption(ServerSocket s, SocketOption<T> name) throws IOException
-    {
-        return s.getOption(name);
-    }
-
-    /**
-     * Sets the value of a socket option on a {@link java.net.DatagramSocket}
-     * or {@link java.net.MulticastSocket}
-     *
-     * @param s the socket
-     * @param name The socket option
-     * @param value The value of the socket option.
-     *
-     * @throws UnsupportedOperationException if the socket does not support
-     *         the option.
-     *
-     * @throws IllegalArgumentException if the value is not valid for
-     *         the option.
-     *
-     * @throws IOException if an I/O error occurs
-     *
-     * @throws NullPointerException if name is null
-     *
-     * @throws SecurityException if a security manager is set and the
-     *         caller does not have any required permission.
-     *
-     * @see java.net.StandardSocketOptions
-     */
-    public static <T> void setOption(DatagramSocket s, SocketOption<T> name, T value) throws IOException
-    {
-        s.setOption(name, value);
-    }
-
-    /**
-     * Returns the value of a socket option from a
-     * {@link java.net.DatagramSocket} or {@link java.net.MulticastSocket}
-     *
-     * @param s the socket
-     * @param name The socket option
-     *
-     * @return The value of the socket option.
-     *
-     * @throws UnsupportedOperationException if the socket does not support
-     *         the option.
-     *
-     * @throws IOException if an I/O error occurs
-     *
-     * @throws NullPointerException if name is null
-     *
-     * @throws SecurityException if a security manager is set and the
-     *         caller does not have any required permission.
-     *
-     * @see java.net.StandardSocketOptions
-     */
-    public static <T> T getOption(DatagramSocket s, SocketOption<T> name) throws IOException
-    {
-        return s.getOption(name);
-    }
-
-    /**
-     * Returns a set of {@link java.net.SocketOption}s supported by the
-     * given socket type. This set may include standard options and also
-     * non standard extended options.
-     *
-     * @param socketType the type of java.net socket
-     *
-     * @throws IllegalArgumentException if socketType is not a valid
-     *         socket type from the java.net package.
-     */
-    public static Set<SocketOption<?>> supportedOptions(Class<?> socketType) {
-        Set<SocketOption<?>> set = options.get(socketType);
-        if (set == null) {
-            throw new IllegalArgumentException("unknown socket type");
-        }
-        return set;
-    }
-
-    private static void checkValueType(Object value, Class<?> type) {
-        if (!type.isAssignableFrom(value.getClass())) {
-            String s = "Found: " + value.getClass().toString() + " Expected: "
-                        + type.toString();
-            throw new IllegalArgumentException(s);
-        }
-    }
-
-    private static volatile boolean checkedReusePort;
-    private static volatile boolean isReusePortAvailable;
-
-    /**
-     * Tells whether SO_REUSEPORT is supported.
-     */
-    static boolean isReusePortAvailable() {
-        if (!checkedReusePort) {
-            isReusePortAvailable = isReusePortAvailable0();
-            checkedReusePort = true;
-        }
-        return isReusePortAvailable;
-    }
-
-    private static void initOptionSets() {
-        boolean flowsupported = ExtendedOptionsImpl.flowSupported();
-        boolean reuseportsupported = isReusePortAvailable();
-        // Socket
-
-        Set<SocketOption<?>> set = new HashSet<>();
-        set.add(StandardSocketOptions.SO_KEEPALIVE);
-        set.add(StandardSocketOptions.SO_SNDBUF);
-        set.add(StandardSocketOptions.SO_RCVBUF);
-        set.add(StandardSocketOptions.SO_REUSEADDR);
-        if (reuseportsupported) {
-            set.add(StandardSocketOptions.SO_REUSEPORT);
-        }
-        set.add(StandardSocketOptions.SO_LINGER);
-        set.add(StandardSocketOptions.IP_TOS);
-        set.add(StandardSocketOptions.TCP_NODELAY);
-        if (flowsupported) {
-            set.add(ExtendedSocketOptions.SO_FLOW_SLA);
-        }
-        set = Collections.unmodifiableSet(set);
-        options.put(Socket.class, set);
-
-        // ServerSocket
-
-        set = new HashSet<>();
-        set.add(StandardSocketOptions.SO_RCVBUF);
-        set.add(StandardSocketOptions.SO_REUSEADDR);
-        if (reuseportsupported) {
-            set.add(StandardSocketOptions.SO_REUSEPORT);
-        }
-        set.add(StandardSocketOptions.IP_TOS);
-        set = Collections.unmodifiableSet(set);
-        options.put(ServerSocket.class, set);
-
-        // DatagramSocket
-
-        set = new HashSet<>();
-        set.add(StandardSocketOptions.SO_SNDBUF);
-        set.add(StandardSocketOptions.SO_RCVBUF);
-        set.add(StandardSocketOptions.SO_REUSEADDR);
-        if (reuseportsupported) {
-            set.add(StandardSocketOptions.SO_REUSEPORT);
-        }
-        set.add(StandardSocketOptions.IP_TOS);
-        if (flowsupported) {
-            set.add(ExtendedSocketOptions.SO_FLOW_SLA);
-        }
-        set = Collections.unmodifiableSet(set);
-        options.put(DatagramSocket.class, set);
-
-        // MulticastSocket
-
-        set = new HashSet<>();
-        set.add(StandardSocketOptions.SO_SNDBUF);
-        set.add(StandardSocketOptions.SO_RCVBUF);
-        set.add(StandardSocketOptions.SO_REUSEADDR);
-        if (reuseportsupported) {
-            set.add(StandardSocketOptions.SO_REUSEPORT);
-        }
-        set.add(StandardSocketOptions.IP_TOS);
-        set.add(StandardSocketOptions.IP_MULTICAST_IF);
-        set.add(StandardSocketOptions.IP_MULTICAST_TTL);
-        set.add(StandardSocketOptions.IP_MULTICAST_LOOP);
-        if (flowsupported) {
-            set.add(ExtendedSocketOptions.SO_FLOW_SLA);
-        }
-        set = Collections.unmodifiableSet(set);
-        options.put(MulticastSocket.class, set);
-    }
-
-    private static native boolean isReusePortAvailable0();
-}
--- a/jdk/src/java.base/share/classes/jdk/net/package-info.java	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.
- */
-
-/**
- * Platform specific socket options for the {@code java.net} and {@code java.nio.channels}
- * socket classes.
- *
- * @since 1.8
- */
-
-package jdk.net;
--- a/jdk/src/java.base/share/classes/module-info.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/module-info.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, 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
@@ -83,8 +83,6 @@
 
     // see JDK-8144062
     exports jdk;
-    // see JDK-8044773
-    exports jdk.net;
 
 
     // the service types defined by the APIs in this module
@@ -168,6 +166,7 @@
         java.sql,
         java.xml,
         jdk.charsets,
+        jdk.net,
         jdk.scripting.nashorn,
         jdk.unsupported,
         jdk.vm.ci;
@@ -194,6 +193,8 @@
         jdk.jvmstat;
     exports sun.net to
         java.httpclient;
+    exports sun.net.ext to
+        jdk.net;
     exports sun.net.dns to
         java.security.jgss,
         jdk.naming.dns;
@@ -300,9 +301,5 @@
 
     provides java.nio.file.spi.FileSystemProvider with
         jdk.internal.jrtfs.JrtFileSystemProvider;
-    provides java.security.Provider with sun.security.provider.Sun;
-    provides java.security.Provider with sun.security.rsa.SunRsaSign;
-    provides java.security.Provider with com.sun.crypto.provider.SunJCE;
-    provides java.security.Provider with com.sun.net.ssl.internal.ssl.Provider;
 }
 
--- a/jdk/src/java.base/share/classes/sun/invoke/util/VerifyAccess.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/invoke/util/VerifyAccess.java	Thu Apr 28 23:08:16 2016 -0700
@@ -231,22 +231,66 @@
      * @param refc the class attempting to make the reference
      */
     public static boolean isTypeVisible(Class<?> type, Class<?> refc) {
-        if (type == refc)  return true;  // easy check
+        if (type == refc) {
+            return true;  // easy check
+        }
         while (type.isArray())  type = type.getComponentType();
-        if (type.isPrimitive() || type == Object.class)  return true;
-        ClassLoader parent = type.getClassLoader();
-        if (parent == null)  return true;
-        ClassLoader child  = refc.getClassLoader();
-        if (child == null)  return false;
-        if (parent == child || loadersAreRelated(parent, child, true))
+        if (type.isPrimitive() || type == Object.class) {
             return true;
-        // Do it the hard way:  Look up the type name from the refc loader.
-        try {
-            Class<?> res = child.loadClass(type.getName());
-            return (type == res);
-        } catch (ClassNotFoundException ex) {
+        }
+        ClassLoader typeLoader = type.getClassLoader();
+        ClassLoader refcLoader = refc.getClassLoader();
+        if (typeLoader == refcLoader) {
+            return true;
+        }
+        if (refcLoader == null && typeLoader != null) {
             return false;
         }
+        if (typeLoader == null && type.getName().startsWith("java.")) {
+            // Note:  The API for actually loading classes, ClassLoader.defineClass,
+            // guarantees that classes with names beginning "java." cannot be aliased,
+            // because class loaders cannot load them directly.
+            return true;
+        }
+
+        // Do it the hard way:  Look up the type name from the refc loader.
+        //
+        // Force the refc loader to report and commit to a particular binding for this type name (type.getName()).
+        //
+        // In principle, this query might force the loader to load some unrelated class,
+        // which would cause this query to fail (and the original caller to give up).
+        // This would be wasted effort, but it is expected to be very rare, occurring
+        // only when an attacker is attempting to create a type alias.
+        // In the normal case, one class loader will simply delegate to the other,
+        // and the same type will be visible through both, with no extra loading.
+        //
+        // It is important to go through Class.forName instead of ClassLoader.loadClass
+        // because Class.forName goes through the JVM system dictionary, which records
+        // the class lookup once for all. This means that even if a not-well-behaved class loader
+        // would "change its mind" about the meaning of the name, the Class.forName request
+        // will use the result cached in the JVM system dictionary. Note that the JVM system dictionary
+        // will record the first successful result. Unsuccessful results are not stored.
+        //
+        // We use doPrivileged in order to allow an unprivileged caller to ask an arbitrary
+        // class loader about the binding of the proposed name (type.getName()).
+        // The looked up type ("res") is compared for equality against the proposed
+        // type ("type") and then is discarded.  Thus, the worst that can happen to
+        // the "child" class loader is that it is bothered to load and report a class
+        // that differs from "type"; this happens once due to JVM system dictionary
+        // memoization.  And the caller never gets to look at the alternate type binding
+        // ("res"), whether it exists or not.
+        final String name = type.getName();
+        Class<?> res = java.security.AccessController.doPrivileged(
+                new java.security.PrivilegedAction<>() {
+                    public Class<?> run() {
+                        try {
+                            return Class.forName(name, false, refcLoader);
+                        } catch (ClassNotFoundException | LinkageError e) {
+                            return null; // Assume the class is not found
+                        }
+                    }
+            });
+        return (type == res);
     }
 
     /**
--- a/jdk/src/java.base/share/classes/sun/net/ExtendedOptionsImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.net;
-
-import java.net.*;
-import jdk.net.*;
-import java.io.IOException;
-import java.io.FileDescriptor;
-import java.security.PrivilegedAction;
-import java.security.AccessController;
-import java.lang.reflect.Field;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.Collections;
-
-/**
- * Contains the native implementation for extended socket options
- * together with some other static utilities
- */
-public class ExtendedOptionsImpl {
-
-    static {
-        AccessController.doPrivileged((PrivilegedAction<Void>)() -> {
-            System.loadLibrary("net");
-            return null;
-        });
-        init();
-    }
-
-    private ExtendedOptionsImpl() {}
-
-    public static void checkSetOptionPermission(SocketOption<?> option) {
-        SecurityManager sm = System.getSecurityManager();
-        if (sm == null) {
-            return;
-        }
-        String check = "setOption." + option.name();
-        sm.checkPermission(new NetworkPermission(check));
-    }
-
-    public static void checkGetOptionPermission(SocketOption<?> option) {
-        SecurityManager sm = System.getSecurityManager();
-        if (sm == null) {
-            return;
-        }
-        String check = "getOption." + option.name();
-        sm.checkPermission(new NetworkPermission(check));
-    }
-
-    public static void checkValueType(Object value, Class<?> type) {
-        if (!type.isAssignableFrom(value.getClass())) {
-            String s = "Found: " + value.getClass().toString() + " Expected: "
-                        + type.toString();
-            throw new IllegalArgumentException(s);
-        }
-    }
-
-    private static native void init();
-
-    /*
-     * Extension native implementations
-     *
-     * SO_FLOW_SLA
-     */
-    public static native void setFlowOption(FileDescriptor fd, SocketFlow f);
-    public static native void getFlowOption(FileDescriptor fd, SocketFlow f);
-    public static native boolean flowSupported();
-}
--- a/jdk/src/java.base/share/classes/sun/net/ResourceManager.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/net/ResourceManager.java	Thu Apr 28 23:08:16 2016 -0700
@@ -53,9 +53,8 @@
     private static final AtomicInteger numSockets;
 
     static {
-        String prop = java.security.AccessController.doPrivileged(
-            new GetPropertyAction("sun.net.maxDatagramSockets")
-        );
+        String prop =
+                GetPropertyAction.getProperty("sun.net.maxDatagramSockets");
         int defmax = DEFAULT_MAX_SOCKETS;
         try {
             if (prop != null) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/net/ext/ExtendedSocketOptions.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.net.ext;
+
+import java.io.FileDescriptor;
+import java.net.SocketException;
+import java.net.SocketOption;
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * Defines the infrastructure to support extended socket options, beyond those
+ * defined in {@link java.net.StandardSocketOptions}.
+ *
+ * Extended socket options are accessed through the jdk.net API, which is in
+ * the jdk.net module.
+ */
+public abstract class ExtendedSocketOptions {
+
+    private final Set<SocketOption<?>> options;
+
+    /** Tells whether or not the option is supported. */
+    public final boolean isOptionSupported(SocketOption<?> option) {
+        return options().contains(option);
+    }
+
+    /** Return the, possibly empty, set of extended socket options available. */
+    public final Set<SocketOption<?>> options() { return options; }
+
+    /** Sets the value of a socket option, for the given socket. */
+    public abstract void setOption(FileDescriptor fd, SocketOption<?> option, Object value)
+            throws SocketException;
+
+    /** Returns the value of a socket option, for the given socket. */
+    public abstract Object getOption(FileDescriptor fd, SocketOption<?> option)
+            throws SocketException;
+
+    protected ExtendedSocketOptions(Set<SocketOption<?>> options) {
+        this.options = options;
+    }
+
+    private static volatile ExtendedSocketOptions instance;
+
+    public static final ExtendedSocketOptions getInstance() { return instance; }
+
+    /** Registers support for extended socket options. Invoked by the jdk.net module. */
+    public static final void register(ExtendedSocketOptions extOptions) {
+        if (instance != null)
+            throw new InternalError("Attempting to reregister extended options");
+
+        instance = extOptions;
+    }
+
+    static {
+        try {
+            // If the class is present, it will be initialized which
+            // triggers registration of the extended socket options.
+            Class<?> c = Class.forName("jdk.net.ExtendedSocketOptions");
+        } catch (ClassNotFoundException e) {
+            // the jdk.net module is not present => no extended socket options
+            instance = new NoExtendedSocketOptions();
+        }
+    }
+
+    static final class NoExtendedSocketOptions extends ExtendedSocketOptions {
+
+        NoExtendedSocketOptions() {
+            super(Collections.<SocketOption<?>>emptySet());
+        }
+
+        @Override
+        public void setOption(FileDescriptor fd, SocketOption<?> option, Object value)
+            throws SocketException
+        {
+            throw new UnsupportedOperationException(
+                    "no extended options: " + option.name());
+        }
+
+        @Override
+        public Object getOption(FileDescriptor fd, SocketOption<?> option)
+            throws SocketException
+        {
+            throw new UnsupportedOperationException(
+                    "no extended options: " + option.name());
+        }
+    }
+}
--- a/jdk/src/java.base/share/classes/sun/net/sdp/SdpSupport.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/net/sdp/SdpSupport.java	Thu Apr 28 23:08:16 2016 -0700
@@ -31,6 +31,7 @@
 
 import jdk.internal.misc.SharedSecrets;
 import jdk.internal.misc.JavaIOFileDescriptorAccess;
+import sun.security.action.GetPropertyAction;
 
 
 /**
@@ -39,8 +40,7 @@
  */
 
 public final class SdpSupport {
-    private static final String os = AccessController
-        .doPrivileged(new sun.security.action.GetPropertyAction("os.name"));
+    private static final String os = GetPropertyAction.getProperty("os.name");
     private static final boolean isSupported = (os.equals("SunOS") || (os.equals("Linux")));
     private static final JavaIOFileDescriptorAccess fdAccess =
         SharedSecrets.getJavaIOFileDescriptorAccess();
--- a/jdk/src/java.base/share/classes/sun/net/smtp/SmtpClient.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/net/smtp/SmtpClient.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,10 +25,10 @@
 
 package sun.net.smtp;
 
-import java.util.StringTokenizer;
 import java.io.*;
 import java.net.*;
 import sun.net.TransferProtocolClient;
+import sun.security.action.GetPropertyAction;
 
 /**
  * This class implements the SMTP client.
@@ -157,8 +157,7 @@
         }
         try {
             String s;
-            mailhost = java.security.AccessController.doPrivileged(
-                    new sun.security.action.GetPropertyAction("mail.host"));
+            mailhost = GetPropertyAction.getProperty("mail.host");
             if (mailhost != null) {
                 openServer(mailhost);
                 return;
@@ -184,8 +183,7 @@
         setConnectTimeout(to);
         try {
             String s;
-            mailhost = java.security.AccessController.doPrivileged(
-                    new sun.security.action.GetPropertyAction("mail.host"));
+            mailhost = GetPropertyAction.getProperty("mail.host");
             if (mailhost != null) {
                 openServer(mailhost);
                 return;
--- a/jdk/src/java.base/share/classes/sun/net/www/MimeLauncher.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/net/www/MimeLauncher.java	Thu Apr 28 23:08:16 2016 -0700
@@ -27,6 +27,7 @@
 import java.net.URL;
 import java.io.*;
 import java.util.StringTokenizer;
+import sun.security.action.GetPropertyAction;
 
 class MimeLauncher extends Thread {
     java.net.URLConnection uc;
@@ -182,8 +183,7 @@
         }
 
         String execPathList;
-        execPathList = java.security.AccessController.doPrivileged(
-                new sun.security.action.GetPropertyAction("exec.path"));
+        execPathList = GetPropertyAction.getProperty("exec.path");
         if (execPathList == null) {
             // exec.path property not set
             return false;
--- a/jdk/src/java.base/share/classes/sun/net/www/http/HttpClient.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/net/www/http/HttpClient.java	Thu Apr 28 23:08:16 2016 -0700
@@ -28,6 +28,7 @@
 import java.io.*;
 import java.net.*;
 import java.util.Locale;
+import java.util.Properties;
 import sun.net.NetworkClient;
 import sun.net.ProgressSource;
 import sun.net.www.MessageHeader;
@@ -37,6 +38,7 @@
 import sun.net.www.protocol.http.HttpURLConnection;
 import sun.util.logging.PlatformLogger;
 import static sun.net.www.protocol.http.HttpURLConnection.TunnelState.*;
+import sun.security.action.GetPropertyAction;
 
 /**
  * @author Herb Jellinek
@@ -143,20 +145,18 @@
     }
 
     static {
-        String keepAlive = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction("http.keepAlive"));
-
-        String retryPost = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction("sun.net.http.retryPost"));
+        Properties props = GetPropertyAction.getProperties();
+        String keepAlive = props.getProperty("http.keepAlive");
+        String retryPost = props.getProperty("sun.net.http.retryPost");
 
         if (keepAlive != null) {
-            keepAliveProp = Boolean.valueOf(keepAlive).booleanValue();
+            keepAliveProp = Boolean.parseBoolean(keepAlive);
         } else {
             keepAliveProp = true;
         }
 
         if (retryPost != null) {
-            retryPostProp = Boolean.valueOf(retryPost).booleanValue();
+            retryPostProp = Boolean.parseBoolean(retryPost);
         } else
             retryPostProp = true;
 
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java	Thu Apr 28 23:08:16 2016 -0700
@@ -46,6 +46,7 @@
 import java.util.StringTokenizer;
 import java.util.Iterator;
 import java.security.Permission;
+import java.util.Properties;
 import sun.net.NetworkClient;
 import sun.net.www.MessageHeader;
 import sun.net.www.MeteredStream;
@@ -277,11 +278,10 @@
 
         if (user == null) {
             user = "anonymous";
-            String vers = java.security.AccessController.doPrivileged(
-                    new GetPropertyAction("java.version"));
-            password = java.security.AccessController.doPrivileged(
-                    new GetPropertyAction("ftp.protocol.user",
-                                          "Java" + vers + "@"));
+            Properties props = GetPropertyAction.getProperties();
+            String vers = props.getProperty("java.version");
+            password = props.getProperty("ftp.protocol.user",
+                    "Java" + vers + "@");
         }
         try {
             ftp = FtpClient.create();
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,9 +25,10 @@
 
 package sun.net.www.protocol.http;
 
-import sun.net.www.*;
 import java.util.Iterator;
 import java.util.HashMap;
+import sun.net.www.*;
+import sun.security.action.GetPropertyAction;
 
 /**
  * This class is used to parse the information in WWW-Authenticate: and Proxy-Authenticate:
@@ -93,8 +94,7 @@
     }
 
     static {
-        authPref = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction("http.auth.preference"));
+        authPref = GetPropertyAction.getProperty("http.auth.preference");
 
         // http.auth.preference can be set to SPNEGO or Kerberos.
         // In fact they means "Negotiate with SPNEGO" and "Negotiate with
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Thu Apr 28 23:08:16 2016 -0700
@@ -52,7 +52,6 @@
 import java.security.PrivilegedExceptionAction;
 import java.security.PrivilegedActionException;
 import java.io.*;
-import java.net.*;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
@@ -78,12 +77,15 @@
 import java.util.TimeZone;
 import java.net.MalformedURLException;
 import java.nio.ByteBuffer;
+import java.util.Properties;
 import static sun.net.www.protocol.http.AuthScheme.BASIC;
 import static sun.net.www.protocol.http.AuthScheme.DIGEST;
 import static sun.net.www.protocol.http.AuthScheme.NTLM;
 import static sun.net.www.protocol.http.AuthScheme.NEGOTIATE;
 import static sun.net.www.protocol.http.AuthScheme.KERBEROS;
 import static sun.net.www.protocol.http.AuthScheme.UNKNOWN;
+import sun.security.action.GetIntegerAction;
+import sun.security.action.GetPropertyAction;
 
 /**
  * A class to represent an HTTP connection to a remote object.
@@ -205,46 +207,38 @@
     };
 
     static {
-        maxRedirects = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetIntegerAction(
-                "http.maxRedirects", defaultmaxRedirects)).intValue();
-        version = java.security.AccessController.doPrivileged(
-                    new sun.security.action.GetPropertyAction("java.version"));
-        String agent = java.security.AccessController.doPrivileged(
-                    new sun.security.action.GetPropertyAction("http.agent"));
+        Properties props = GetPropertyAction.getProperties();
+        maxRedirects = GetIntegerAction.getProperty("http.maxRedirects",
+                        defaultmaxRedirects);
+        version = props.getProperty("java.version");
+        String agent = props.getProperty("http.agent");
         if (agent == null) {
             agent = "Java/"+version;
         } else {
             agent = agent + " Java/"+version;
         }
         userAgent = agent;
-        validateProxy = java.security.AccessController.doPrivileged(
-                new sun.security.action.GetBooleanAction(
-                    "http.auth.digest.validateProxy")).booleanValue();
-        validateServer = java.security.AccessController.doPrivileged(
-                new sun.security.action.GetBooleanAction(
-                    "http.auth.digest.validateServer")).booleanValue();
-
-        enableESBuffer = java.security.AccessController.doPrivileged(
-                new sun.security.action.GetBooleanAction(
-                    "sun.net.http.errorstream.enableBuffering")).booleanValue();
-        timeout4ESBuffer = java.security.AccessController.doPrivileged(
-                new sun.security.action.GetIntegerAction(
-                    "sun.net.http.errorstream.timeout", 300)).intValue();
+        validateProxy = Boolean.parseBoolean(
+                props.getProperty("http.auth.digest.validateProxy"));
+        validateServer = Boolean.parseBoolean(
+                props.getProperty("http.auth.digest.validateServer"));
+
+        enableESBuffer = Boolean.parseBoolean(
+                props.getProperty("sun.net.http.errorstream.enableBuffering"));
+        timeout4ESBuffer = GetIntegerAction
+                .getProperty("sun.net.http.errorstream.timeout", 300);
         if (timeout4ESBuffer <= 0) {
             timeout4ESBuffer = 300; // use the default
         }
 
-        bufSize4ES = java.security.AccessController.doPrivileged(
-                new sun.security.action.GetIntegerAction(
-                    "sun.net.http.errorstream.bufferSize", 4096)).intValue();
+        bufSize4ES = GetIntegerAction
+                .getProperty("sun.net.http.errorstream.bufferSize", 4096);
         if (bufSize4ES <= 0) {
             bufSize4ES = 4096; // use the default
         }
 
-        allowRestrictedHeaders = java.security.AccessController.doPrivileged(
-                new sun.security.action.GetBooleanAction(
-                    "sun.net.http.allowRestrictedHeaders")).booleanValue();
+        allowRestrictedHeaders = Boolean.parseBoolean(
+                props.getProperty("sun.net.http.allowRestrictedHeaders"));
         if (!allowRestrictedHeaders) {
             restrictedHeaderSet = new HashSet<>(restrictedHeaders.length);
             for (int i=0; i < restrictedHeaders.length; i++) {
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java	Thu Apr 28 23:08:16 2016 -0700
@@ -41,7 +41,6 @@
 import java.security.cert.*;
 import java.util.StringTokenizer;
 import java.util.Vector;
-import java.security.AccessController;
 
 import javax.security.auth.x500.X500Principal;
 
@@ -139,8 +138,8 @@
         // If ciphers are assigned, sort them into an array.
         //
         String ciphers [];
-        String cipherString = AccessController.doPrivileged(
-                new GetPropertyAction("https.cipherSuites"));
+        String cipherString =
+                GetPropertyAction.getProperty("https.cipherSuites");
 
         if (cipherString == null || "".equals(cipherString)) {
             ciphers = null;
@@ -163,8 +162,8 @@
         // If protocols are assigned, sort them into an array.
         //
         String protocols [];
-        String protocolString = AccessController.doPrivileged(
-                new GetPropertyAction("https.protocols"));
+        String protocolString =
+                GetPropertyAction.getProperty("https.protocols");
 
         if (protocolString == null || "".equals(protocolString)) {
             protocols = null;
@@ -184,8 +183,7 @@
     }
 
     private String getUserAgent() {
-        String userAgent = java.security.AccessController.doPrivileged(
-                new sun.security.action.GetPropertyAction("https.agent"));
+        String userAgent = GetPropertyAction.getProperty("https.agent");
         if (userAgent == null || userAgent.length() == 0) {
             userAgent = "JSSE";
         }
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/jrt/JavaRuntimeURLConnection.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/jrt/JavaRuntimeURLConnection.java	Thu Apr 28 23:08:16 2016 -0700
@@ -32,10 +32,7 @@
 import java.io.InputStream;
 import java.net.MalformedURLException;
 import java.net.URL;
-import java.security.AccessController;
 import java.security.Permission;
-import java.security.PrivilegedAction;
-import java.util.List;
 
 import jdk.internal.jimage.ImageLocation;
 import jdk.internal.jimage.ImageReader;
@@ -45,6 +42,7 @@
 import jdk.internal.loader.Resource;
 import sun.net.www.ParseUtil;
 import sun.net.www.URLConnection;
+import sun.security.action.GetPropertyAction;
 
 /**
  * URLConnection implementation that can be used to connect to resources
@@ -163,11 +161,7 @@
     public Permission getPermission() throws IOException {
         Permission p = permission;
         if (p == null) {
-            // using lambda expression here leads to recursive initialization
-            PrivilegedAction<String> pa = new PrivilegedAction<String>() {
-                public String run() { return System.getProperty("java.home"); }
-            };
-            String home = AccessController.doPrivileged(pa);
+            String home = GetPropertyAction.getProperty("java.home");
             p = new FilePermission(home + File.separator + "-", "read");
             permission = p;
         }
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/netdoc/Handler.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/netdoc/Handler.java	Thu Apr 28 23:08:16 2016 -0700
@@ -40,6 +40,7 @@
 import java.net.URLStreamHandler;
 import java.io.InputStream;
 import java.io.IOException;
+import sun.security.action.GetPropertyAction;
 
 public class Handler extends URLStreamHandler {
     static URL base;
@@ -54,12 +55,10 @@
         URLConnection uc = null;
         URL ru;
 
-        Boolean tmp = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetBooleanAction("newdoc.localonly"));
-        boolean localonly = tmp.booleanValue();
+        boolean localonly = Boolean.parseBoolean(
+                GetPropertyAction.getProperty("newdoc.localonly"));
 
-        String docurl = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction("doc.url"));
+        String docurl = GetPropertyAction.getProperty("doc.url");
 
         String file = u.getFile();
         if (!localonly) {
--- a/jdk/src/java.base/share/classes/sun/nio/ch/AbstractPollSelectorImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/AbstractPollSelectorImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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,7 +29,6 @@
 import java.nio.channels.*;
 import java.nio.channels.spi.*;
 import java.util.*;
-import sun.misc.*;
 
 
 /**
--- a/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -39,7 +39,7 @@
 import java.util.concurrent.*;
 import java.util.concurrent.locks.*;
 import sun.net.NetHooks;
-import sun.net.ExtendedOptionsImpl;
+import sun.net.ext.ExtendedSocketOptions;
 
 /**
  * Base implementation of AsynchronousSocketChannel
@@ -512,9 +512,9 @@
                 set.add(StandardSocketOptions.SO_REUSEPORT);
             }
             set.add(StandardSocketOptions.TCP_NODELAY);
-            if (ExtendedOptionsImpl.flowSupported()) {
-                set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA);
-            }
+            ExtendedSocketOptions extendedOptions =
+                    ExtendedSocketOptions.getInstance();
+            set.addAll(extendedOptions.options());
             return Collections.unmodifiableSet(set);
         }
     }
--- a/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -33,7 +33,7 @@
 import java.nio.channels.spi.*;
 import java.util.*;
 import sun.net.ResourceManager;
-import sun.net.ExtendedOptionsImpl;
+import sun.net.ext.ExtendedSocketOptions;
 
 /**
  * An implementation of DatagramChannels.
@@ -306,9 +306,9 @@
             set.add(StandardSocketOptions.IP_MULTICAST_IF);
             set.add(StandardSocketOptions.IP_MULTICAST_TTL);
             set.add(StandardSocketOptions.IP_MULTICAST_LOOP);
-            if (ExtendedOptionsImpl.flowSupported()) {
-                set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA);
-            }
+            ExtendedSocketOptions extendedOptions =
+                    ExtendedSocketOptions.getInstance();
+            set.addAll(extendedOptions.options());
             return Collections.unmodifiableSet(set);
         }
     }
--- a/jdk/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1019,9 +1019,8 @@
         if (!propertyChecked) {
             synchronized (FileChannelImpl.class) {
                 if (!propertyChecked) {
-                    String value = AccessController.doPrivileged(
-                        new GetPropertyAction(
-                            "sun.nio.ch.disableSystemWideOverlappingFileLockCheck"));
+                    String value = GetPropertyAction.getProperty(
+                            "sun.nio.ch.disableSystemWideOverlappingFileLockCheck");
                     isSharedFileLockTable = ((value == null) || value.equals("false"));
                     propertyChecked = true;
                 }
--- a/jdk/src/java.base/share/classes/sun/nio/ch/Net.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/Net.java	Thu Apr 28 23:08:16 2016 -0700
@@ -27,13 +27,12 @@
 
 import java.io.*;
 import java.net.*;
-import jdk.net.*;
 import java.nio.channels.*;
 import java.util.*;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-import sun.net.ExtendedOptionsImpl;
-
+import sun.net.ext.ExtendedSocketOptions;
+import sun.security.action.GetPropertyAction;
 
 public class Net {
 
@@ -280,6 +279,9 @@
 
     // -- Socket options
 
+    static final ExtendedSocketOptions extendedOptions =
+            ExtendedSocketOptions.getInstance();
+
     static void setSocketOption(FileDescriptor fd, ProtocolFamily family,
                                 SocketOption<?> name, Object value)
         throws IOException
@@ -290,12 +292,8 @@
         // only simple values supported by this method
         Class<?> type = name.type();
 
-        if (type == SocketFlow.class) {
-            SecurityManager sm = System.getSecurityManager();
-            if (sm != null) {
-                sm.checkPermission(new NetworkPermission("setOption.SO_FLOW_SLA"));
-            }
-            ExtendedOptionsImpl.setFlowOption(fd, (SocketFlow)value);
+        if (extendedOptions.isOptionSupported(name)) {
+            extendedOptions.setOption(fd, name, value);
             return;
         }
 
@@ -352,14 +350,8 @@
     {
         Class<?> type = name.type();
 
-        if (type == SocketFlow.class) {
-            SecurityManager sm = System.getSecurityManager();
-            if (sm != null) {
-                sm.checkPermission(new NetworkPermission("getOption.SO_FLOW_SLA"));
-            }
-            SocketFlow flow = SocketFlow.create();
-            ExtendedOptionsImpl.getFlowOption(fd, flow);
-            return flow;
+        if (extendedOptions.isOptionSupported(name)) {
+            return extendedOptions.getOption(fd, name);
         }
 
         // only simple values supported by this method
@@ -382,13 +374,8 @@
     }
 
     public static boolean isFastTcpLoopbackRequested() {
-        String loopbackProp = java.security.AccessController.doPrivileged(
-            new PrivilegedAction<String>() {
-                @Override
-                public String run() {
-                    return System.getProperty("jdk.net.useFastTcpLoopback");
-                }
-            });
+        String loopbackProp =
+                GetPropertyAction.getProperty("jdk.net.useFastTcpLoopback");
         boolean enable;
         if ("".equals(loopbackProp)) {
             enable = true;
@@ -647,16 +634,9 @@
         int availLevel = isExclusiveBindAvailable();
         if (availLevel >= 0) {
             String exclBindProp =
-                java.security.AccessController.doPrivileged(
-                    new PrivilegedAction<String>() {
-                        @Override
-                        public String run() {
-                            return System.getProperty(
-                                    "sun.net.useExclusiveBind");
-                        }
-                    });
+                    GetPropertyAction.getProperty("sun.net.useExclusiveBind");
             if (exclBindProp != null) {
-                exclusiveBind = exclBindProp.length() == 0 ?
+                exclusiveBind = exclBindProp.isEmpty() ?
                         true : Boolean.parseBoolean(exclBindProp);
             } else if (availLevel == 1) {
                 exclusiveBind = true;
--- a/jdk/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -33,8 +33,7 @@
 import java.nio.channels.spi.*;
 import java.util.*;
 import sun.net.NetHooks;
-import sun.net.ExtendedOptionsImpl;
-
+import sun.net.ext.ExtendedSocketOptions;
 
 /**
  * An implementation of SocketChannels
@@ -242,9 +241,9 @@
             // additional options required by socket adaptor
             set.add(StandardSocketOptions.IP_TOS);
             set.add(ExtendedSocketOption.SO_OOBINLINE);
-            if (ExtendedOptionsImpl.flowSupported()) {
-                set.add(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA);
-            }
+            ExtendedSocketOptions extendedOptions =
+                    ExtendedSocketOptions.getInstance();
+            set.addAll(extendedOptions.options());
             return Collections.unmodifiableSet(set);
         }
     }
--- a/jdk/src/java.base/share/classes/sun/nio/ch/Util.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/Util.java	Thu Apr 28 23:08:16 2016 -0700
@@ -64,13 +64,7 @@
      * for potential future-proofing.
      */
     private static long getMaxCachedBufferSize() {
-        String s = java.security.AccessController.doPrivileged(
-            new PrivilegedAction<String>() {
-                @Override
-                public String run() {
-                    return System.getProperty("jdk.nio.maxCachedBufferSize");
-                }
-            });
+        String s = GetPropertyAction.getProperty("jdk.nio.maxCachedBufferSize");
         if (s != null) {
             try {
                 long m = Long.parseLong(s);
@@ -471,8 +465,7 @@
         if (bugLevel == null) {
             if (!jdk.internal.misc.VM.isBooted())
                 return false;
-            String value = AccessController.doPrivileged(
-                new GetPropertyAction("sun.nio.ch.bugLevel"));
+            String value = GetPropertyAction.getProperty("sun.nio.ch.bugLevel");
             bugLevel = (value != null) ? value : "";
         }
         return bugLevel.equals(bl);
--- a/jdk/src/java.base/share/classes/sun/nio/cs/StandardCharsets.java.template	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/StandardCharsets.java.template	Thu Apr 28 23:08:16 2016 -0700
@@ -34,8 +34,7 @@
 import java.util.Iterator;
 import java.util.Locale;
 import java.util.Map;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
+import sun.security.action.GetPropertyAction;
 
 public class StandardCharsets extends CharsetProvider {
 
@@ -201,15 +200,7 @@
     }
 
     private static String getProperty(String key) {
-        // this method may be called during initialization of
-        // system class loader and thus not using lambda
-        return AccessController.doPrivileged(
-            new PrivilegedAction<String>() {
-                @Override
-                public String run() {
-                    return System.getProperty(key);
-                }
-            });
+        return GetPropertyAction.getProperty(key);
     }
 
 
--- a/jdk/src/java.base/share/classes/sun/nio/fs/Util.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/nio/fs/Util.java	Thu Apr 28 23:08:16 2016 -0700
@@ -28,8 +28,7 @@
 import java.util.*;
 import java.nio.file.*;
 import java.nio.charset.Charset;
-import java.security.*;
-import sun.security.action.*;
+import sun.security.action.GetPropertyAction;
 
 /**
  * Utility methods
@@ -39,7 +38,7 @@
     private Util() { }
 
     private static final Charset jnuEncoding = Charset.forName(
-        AccessController.doPrivileged(new GetPropertyAction("sun.jnu.encoding")));
+        GetPropertyAction.getProperty("sun.jnu.encoding"));
 
     /**
      * Returns {@code Charset} corresponding to the sun.jnu.encoding property
--- a/jdk/src/java.base/share/classes/sun/security/action/GetBooleanSecurityPropertyAction.java	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.action;
-
-import java.security.Security;
-
-/**
- * A convenience class for retrieving the boolean value of a security property
- * as a privileged action.
- *
- * <p>An instance of this class can be used as the argument of
- * <code>AccessController.doPrivileged</code>.
- *
- * <p>The following code retrieves the boolean value of the security
- * property named <code>"prop"</code> as a privileged action:
- *
- * <pre>
- * boolean b = java.security.AccessController.doPrivileged
- *              (new GetBooleanSecurityPropertyAction("prop")).booleanValue();
- * </pre>
- *
- */
-public class GetBooleanSecurityPropertyAction
-        implements java.security.PrivilegedAction<Boolean> {
-    private String theProp;
-
-    /**
-     * Constructor that takes the name of the security property whose boolean
-     * value needs to be determined.
-     *
-     * @param theProp the name of the security property
-     */
-    public GetBooleanSecurityPropertyAction(String theProp) {
-        this.theProp = theProp;
-    }
-
-    /**
-     * Determines the boolean value of the security property whose name was
-     * specified in the constructor.
-     *
-     * @return the <code>Boolean</code> value of the security property.
-     */
-    public Boolean run() {
-        boolean b = false;
-        try {
-            String value = Security.getProperty(theProp);
-            b = (value != null) && value.equalsIgnoreCase("true");
-        } catch (NullPointerException e) {}
-        return b;
-    }
-}
--- a/jdk/src/java.base/share/classes/sun/security/action/GetIntegerAction.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/action/GetIntegerAction.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,6 +25,8 @@
 
 package sun.security.action;
 
+import java.security.AccessController;
+
 /**
  * A convenience class for retrieving the integer value of a system property
  * as a privileged action.
@@ -67,7 +69,7 @@
         implements java.security.PrivilegedAction<Integer> {
     private String theProp;
     private int defaultVal;
-    private boolean defaultSet = false;
+    private boolean defaultSet;
 
     /**
      * Constructor that takes the name of the system property whose integer
@@ -110,4 +112,39 @@
             return defaultVal;
         return value;
     }
+
+    /**
+     * Convenience method to get a property without going through doPrivileged
+     * if no security manager is present. This is unsafe for inclusion in a
+     * public API but allowable here since this class is now encapsulated.
+     *
+     * @param theProp the name of the system property.
+     */
+    public static Integer getProperty(String theProp) {
+        if (System.getSecurityManager() == null) {
+            return Integer.getInteger(theProp);
+        } else {
+            return AccessController.doPrivileged(
+                    new GetIntegerAction(theProp));
+        }
+    }
+
+    /**
+     * Convenience method to get a property without going through doPrivileged
+     * if no security manager is present. This is unsafe for inclusion in a
+     * public API but allowable here since this class is now encapsulated.
+     *
+     * @param theProp the name of the system property.
+     * @param defaultVal the default value.
+     */
+    public static Integer getProperty(String theProp, int defaultVal) {
+        Integer value;
+        if (System.getSecurityManager() == null) {
+            value = Integer.getInteger(theProp);
+        } else {
+            value = AccessController.doPrivileged(
+                    new GetIntegerAction(theProp));
+        }
+        return (value != null) ? value : defaultVal;
+    }
 }
--- a/jdk/src/java.base/share/classes/sun/security/action/GetPropertyAction.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/action/GetPropertyAction.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,6 +25,10 @@
 
 package sun.security.action;
 
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Properties;
+
 /**
  * A convenience class for retrieving the string value of a system
  * property as a privileged action.
@@ -46,8 +50,7 @@
  * @since 1.2
  */
 
-public class GetPropertyAction
-        implements java.security.PrivilegedAction<String> {
+public class GetPropertyAction implements PrivilegedAction<String> {
     private String theProp;
     private String defaultVal;
 
@@ -84,4 +87,57 @@
         String value = System.getProperty(theProp);
         return (value == null) ? defaultVal : value;
     }
+
+    /**
+     * Convenience method to get a property without going through doPrivileged
+     * if no security manager is present. This is unsafe for inclusion in a
+     * public API but allowable here since this class is now encapsulated.
+     *
+     * @param theProp the name of the system property.
+     */
+    public static String getProperty(String theProp) {
+        if (System.getSecurityManager() == null) {
+            return System.getProperty(theProp);
+        } else {
+            return AccessController.doPrivileged(
+                    new GetPropertyAction(theProp));
+        }
+    }
+
+    /**
+     * Convenience method to get a property without going through doPrivileged
+     * if no security manager is present. This is unsafe for inclusion in a
+     * public API but allowable here since this class is now encapsulated.
+     *
+     * @param theProp the name of the system property.
+     * @param defaultVal the default value.
+     */
+    public static String getProperty(String theProp, String defaultVal) {
+        if (System.getSecurityManager() == null) {
+            return System.getProperty(theProp, defaultVal);
+        } else {
+            return AccessController.doPrivileged(
+                    new GetPropertyAction(theProp, defaultVal));
+        }
+    }
+
+    /**
+     * Convenience method to call <code>System.getProperties</code> without
+     * having to go through doPrivileged if no security manager is present.
+     * This is unsafe for inclusion in a public API but allowable here since
+     * this class is now encapsulated.
+     */
+    public static Properties getProperties() {
+        if (System.getSecurityManager() == null) {
+            return System.getProperties();
+        } else {
+            return AccessController.doPrivileged(
+                    new PrivilegedAction<Properties>() {
+                        public Properties run() {
+                            return System.getProperties();
+                        }
+                    }
+            );
+        }
+    }
 }
--- a/jdk/src/java.base/share/classes/sun/security/jca/ProviderConfig.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/jca/ProviderConfig.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -236,9 +236,8 @@
                 if (debug != null) {
                     debug.println("Loading provider " + ProviderConfig.this);
                 }
-                ProviderLoader pl = new ProviderLoader();
                 try {
-                    Provider p = pl.load(provName);
+                    Provider p = ProviderLoader.INSTANCE.load(provName);
                     if (p != null) {
                         if (hasArgument()) {
                             p = p.configure(argument);
@@ -303,9 +302,11 @@
 
     // Inner class for loading security providers listed in java.security file
     private static final class ProviderLoader {
+        static final ProviderLoader INSTANCE = new ProviderLoader();
+
         private final ServiceLoader<Provider> services;
 
-        ProviderLoader() {
+        private ProviderLoader() {
             // VM should already been booted at this point, if not
             // - Only providers in java.base should be loaded, don't use
             //   ServiceLoader
--- a/jdk/src/java.base/share/classes/sun/security/provider/DSA.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/provider/DSA.java	Thu Apr 28 23:08:16 2016 -0700
@@ -106,6 +106,18 @@
         this.p1363Format = p1363Format;
     }
 
+    private static void checkKey(DSAParams params, int digestLen, String mdAlgo)
+        throws InvalidKeyException {
+        // FIPS186-3 states in sec4.2 that a hash function which provides
+        // a lower security strength than the (L, N) pair ordinarily should
+        // not be used.
+        int valueN = params.getQ().bitLength();
+        if (valueN > digestLen) {
+            throw new InvalidKeyException("The security strength of " +
+                mdAlgo + " digest algorithm is not sufficient for this key size");
+        }
+    }
+
     /**
      * Initialize the DSA object with a DSA private key.
      *
@@ -130,6 +142,12 @@
             throw new InvalidKeyException("DSA private key lacks parameters");
         }
 
+        // check key size against hash output size for signing
+        // skip this check for verification to minimize impact on existing apps
+        if (md.getAlgorithm() != "NullDigest20") {
+            checkKey(params, md.getDigestLength()*8, md.getAlgorithm());
+        }
+
         this.params = params;
         this.presetX = priv.getX();
         this.presetY = null;
@@ -160,7 +178,6 @@
         if (params == null) {
             throw new InvalidKeyException("DSA public key lacks parameters");
         }
-
         this.params = params;
         this.presetY = pub.getY();
         this.presetX = null;
@@ -406,20 +423,13 @@
         return t5.mod(q);
     }
 
-    // NOTE: This following impl is defined in FIPS 186-3 AppendixB.2.2.
-    // Original DSS algos such as SHA1withDSA and RawDSA uses a different
-    // algorithm defined in FIPS 186-1 Sec3.2, and thus need to override this.
+    // NOTE: This following impl is defined in FIPS 186-4 AppendixB.2.1.
     protected BigInteger generateK(BigInteger q) {
         SecureRandom random = getSigningRandom();
-        byte[] kValue = new byte[q.bitLength()/8];
+        byte[] kValue = new byte[(q.bitLength() + 7)/8 + 8];
 
-        while (true) {
-            random.nextBytes(kValue);
-            BigInteger k = new BigInteger(1, kValue).mod(q);
-            if (k.signum() > 0 && k.compareTo(q) < 0) {
-                return k;
-            }
-        }
+        random.nextBytes(kValue);
+        return new BigInteger(1, kValue).mod(q.subtract(BigInteger.ONE)).add(BigInteger.ONE);
     }
 
     // Use the application-specified SecureRandom Object if provided.
@@ -504,222 +514,10 @@
         }
     }
 
-    static class LegacyDSA extends DSA {
-        /* The random seed used to generate k */
-        private int[] kSeed;
-        /* The random seed used to generate k (specified by application) */
-        private byte[] kSeedAsByteArray;
-        /*
-         * The random seed used to generate k
-         * (prevent the same Kseed from being used twice in a row
-         */
-        private int[] kSeedLast;
-
-        public LegacyDSA(MessageDigest md) throws NoSuchAlgorithmException {
-            this(md, false);
-        }
-
-        private LegacyDSA(MessageDigest md, boolean p1363Format)
-                throws NoSuchAlgorithmException {
-            super(md, p1363Format);
-        }
-
-        @Deprecated
-        protected void engineSetParameter(String key, Object param) {
-            if (key.equals("KSEED")) {
-                if (param instanceof byte[]) {
-                    kSeed = byteArray2IntArray((byte[])param);
-                    kSeedAsByteArray = (byte[])param;
-                } else {
-                    debug("unrecognized param: " + key);
-                    throw new InvalidParameterException("kSeed not a byte array");
-                }
-            } else {
-                throw new InvalidParameterException("Unsupported parameter");
-            }
-        }
-
-        @Deprecated
-        protected Object engineGetParameter(String key) {
-           if (key.equals("KSEED")) {
-               return kSeedAsByteArray;
-           } else {
-               return null;
-           }
-        }
-
-        /*
-         * Please read bug report 4044247 for an alternative, faster,
-         * NON-FIPS approved method to generate K
-         */
-        @Override
-        protected BigInteger generateK(BigInteger q) {
-            BigInteger k = null;
-
-            // The application specified a kSeed for us to use.
-            // Note: we dis-allow usage of the same Kseed twice in a row
-            if (kSeed != null && !Arrays.equals(kSeed, kSeedLast)) {
-                k = generateKUsingKSeed(kSeed, q);
-                if (k.signum() > 0 && k.compareTo(q) < 0) {
-                    kSeedLast = kSeed.clone();
-                    return k;
-                }
-            }
-
-            // The application did not specify a Kseed for us to use.
-            // We'll generate a new Kseed by getting random bytes from
-            // a SecureRandom object.
-            SecureRandom random = getSigningRandom();
-
-            while (true) {
-                int[] seed = new int[5];
-
-                for (int i = 0; i < 5; i++) seed[i] = random.nextInt();
-
-                k = generateKUsingKSeed(seed, q);
-                if (k.signum() > 0 && k.compareTo(q) < 0) {
-                    kSeedLast = seed;
-                    return k;
-                }
-            }
-        }
-
-        /**
-         * Compute k for the DSA signature as defined in the original DSS,
-         * i.e. FIPS186.
-         *
-         * @param seed the seed for generating k. This seed should be
-         * secure. This is what is referred to as the KSEED in the DSA
-         * specification.
-         *
-         * @param g the g parameter from the DSA key pair.
-         */
-        private BigInteger generateKUsingKSeed(int[] seed, BigInteger q) {
-
-            // check out t in the spec.
-            int[] t = { 0xEFCDAB89, 0x98BADCFE, 0x10325476,
-                        0xC3D2E1F0, 0x67452301 };
-            //
-            int[] tmp = SHA_7(seed, t);
-            byte[] tmpBytes = new byte[tmp.length * 4];
-            for (int i = 0; i < tmp.length; i++) {
-                int k = tmp[i];
-                for (int j = 0; j < 4; j++) {
-                    tmpBytes[(i * 4) + j] = (byte) (k >>> (24 - (j * 8)));
-                }
-            }
-            BigInteger k = new BigInteger(1, tmpBytes).mod(q);
-            return k;
-        }
-
-        // Constants for each round
-        private static final int round1_kt = 0x5a827999;
-        private static final int round2_kt = 0x6ed9eba1;
-        private static final int round3_kt = 0x8f1bbcdc;
-        private static final int round4_kt = 0xca62c1d6;
-
-        /**
-         * Computes set 1 thru 7 of SHA-1 on m1. */
-        static int[] SHA_7(int[] m1, int[] h) {
-
-            int[] W = new int[80];
-            System.arraycopy(m1,0,W,0,m1.length);
-            int temp = 0;
-
-            for (int t = 16; t <= 79; t++){
-                temp = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
-                W[t] = ((temp << 1) | (temp >>>(32 - 1)));
-            }
-
-            int a = h[0],b = h[1],c = h[2], d = h[3], e = h[4];
-            for (int i = 0; i < 20; i++) {
-                temp = ((a<<5) | (a>>>(32-5))) +
-                    ((b&c)|((~b)&d))+ e + W[i] + round1_kt;
-                e = d;
-                d = c;
-                c = ((b<<30) | (b>>>(32-30)));
-                b = a;
-                a = temp;
-            }
-
-            // Round 2
-            for (int i = 20; i < 40; i++) {
-                temp = ((a<<5) | (a>>>(32-5))) +
-                    (b ^ c ^ d) + e + W[i] + round2_kt;
-                e = d;
-                d = c;
-                c = ((b<<30) | (b>>>(32-30)));
-                b = a;
-                a = temp;
-            }
-
-            // Round 3
-            for (int i = 40; i < 60; i++) {
-                temp = ((a<<5) | (a>>>(32-5))) +
-                    ((b&c)|(b&d)|(c&d)) + e + W[i] + round3_kt;
-                e = d;
-                d = c;
-                c = ((b<<30) | (b>>>(32-30)));
-                b = a;
-                a = temp;
-            }
-
-            // Round 4
-            for (int i = 60; i < 80; i++) {
-                temp = ((a<<5) | (a>>>(32-5))) +
-                    (b ^ c ^ d) + e + W[i] + round4_kt;
-                e = d;
-                d = c;
-                c = ((b<<30) | (b>>>(32-30)));
-                b = a;
-                a = temp;
-            }
-            int[] md = new int[5];
-            md[0] = h[0] + a;
-            md[1] = h[1] + b;
-            md[2] = h[2] + c;
-            md[3] = h[3] + d;
-            md[4] = h[4] + e;
-            return md;
-        }
-
-        /*
-         * Utility routine for converting a byte array into an int array
-         */
-        private int[] byteArray2IntArray(byte[] byteArray) {
-
-            int j = 0;
-            byte[] newBA;
-            int mod = byteArray.length % 4;
-
-            // guarantee that the incoming byteArray is a multiple of 4
-            // (pad with 0's)
-            switch (mod) {
-            case 3:     newBA = new byte[byteArray.length + 1]; break;
-            case 2:     newBA = new byte[byteArray.length + 2]; break;
-            case 1:     newBA = new byte[byteArray.length + 3]; break;
-            default:    newBA = new byte[byteArray.length + 0]; break;
-            }
-            System.arraycopy(byteArray, 0, newBA, 0, byteArray.length);
-
-            // copy each set of 4 bytes in the byte array into an integer
-            int[] newSeed = new int[newBA.length / 4];
-            for (int i = 0; i < newBA.length; i += 4) {
-                newSeed[j] = newBA[i + 3] & 0xFF;
-                newSeed[j] |= (newBA[i + 2] << 8) & 0xFF00;
-                newSeed[j] |= (newBA[i + 1] << 16) & 0xFF0000;
-                newSeed[j] |= (newBA[i + 0] << 24) & 0xFF000000;
-                j++;
-            }
-
-            return newSeed;
-        }
-    }
-
     /**
      * Standard SHA1withDSA implementation.
      */
-    public static final class SHA1withDSA extends LegacyDSA {
+    public static final class SHA1withDSA extends DSA {
         public SHA1withDSA() throws NoSuchAlgorithmException {
             super(MessageDigest.getInstance("SHA-1"));
         }
@@ -728,7 +526,7 @@
     /**
      * SHA1withDSA implementation that uses the IEEE P1363 format.
      */
-    public static final class SHA1withDSAinP1363Format extends LegacyDSA {
+    public static final class SHA1withDSAinP1363Format extends DSA {
         public SHA1withDSAinP1363Format() throws NoSuchAlgorithmException {
             super(MessageDigest.getInstance("SHA-1"), true);
         }
@@ -741,7 +539,7 @@
      * not, a SignatureException is thrown when sign()/verify() is called
      * per JCA spec.
      */
-    static class Raw extends LegacyDSA {
+    static class Raw extends DSA {
         // Internal special-purpose MessageDigest impl for RawDSA
         // Only override whatever methods used
         // NOTE: no clone support
--- a/jdk/src/java.base/share/classes/sun/security/provider/DSAKeyFactory.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/provider/DSAKeyFactory.java	Thu Apr 28 23:08:16 2016 -0700
@@ -70,8 +70,7 @@
          * By default this is false.
          * This incompatibility was introduced by 4532506.
          */
-        String prop = AccessController.doPrivileged
-                (new GetPropertyAction(SERIAL_PROP, null));
+        String prop = GetPropertyAction.getProperty(SERIAL_PROP);
         SERIAL_INTEROP = "true".equalsIgnoreCase(prop);
     }
 
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/AlgorithmChecker.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/AlgorithmChecker.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2016, 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,12 +31,10 @@
 import java.util.Collections;
 import java.util.Set;
 import java.util.EnumSet;
-import java.util.HashSet;
 import java.math.BigInteger;
 import java.security.PublicKey;
 import java.security.KeyFactory;
 import java.security.AlgorithmParameters;
-import java.security.NoSuchAlgorithmException;
 import java.security.GeneralSecurityException;
 import java.security.cert.Certificate;
 import java.security.cert.X509CRL;
@@ -48,10 +46,13 @@
 import java.security.cert.CertPathValidatorException;
 import java.security.cert.CertPathValidatorException.BasicReason;
 import java.security.cert.PKIXReason;
-import java.io.IOException;
-import java.security.interfaces.*;
-import java.security.spec.*;
+import java.security.interfaces.DSAParams;
+import java.security.interfaces.DSAPublicKey;
+import java.security.spec.DSAPublicKeySpec;
 
+import sun.security.util.AnchorCertificates;
+import sun.security.util.CertConstraintParameters;
+import sun.security.util.Debug;
 import sun.security.util.DisabledAlgorithmConstraints;
 import sun.security.x509.X509CertImpl;
 import sun.security.x509.X509CRLImpl;
@@ -69,6 +70,7 @@
  * @see PKIXParameters
  */
 public final class AlgorithmChecker extends PKIXCertPathChecker {
+    private static final Debug debug = Debug.getInstance("certpath");
 
     private final AlgorithmConstraints constraints;
     private final PublicKey trustedPubKey;
@@ -88,6 +90,14 @@
         certPathDefaultConstraints = new DisabledAlgorithmConstraints(
             DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
 
+    // If there is no "cacerts" keyword, then disable anchor checking
+    private static final boolean publicCALimits =
+            certPathDefaultConstraints.checkProperty("jdkCA");
+
+    // If anchor checking enabled, this will be true if the trust anchor
+    // has a match in the cacerts file
+    private boolean trustedMatch = false;
+
     /**
      * Create a new <code>AlgorithmChecker</code> with the algorithm
      * constraints specified in security property
@@ -136,6 +146,11 @@
 
         if (anchor.getTrustedCert() != null) {
             this.trustedPubKey = anchor.getTrustedCert().getPublicKey();
+            // Check for anchor certificate restrictions
+            trustedMatch = checkFingerprint(anchor.getTrustedCert());
+            if (trustedMatch && debug != null) {
+                debug.println("trustedMatch = true");
+            }
         } else {
             this.trustedPubKey = anchor.getCAPublicKey();
         }
@@ -144,6 +159,19 @@
         this.constraints = constraints;
     }
 
+    // Check this 'cert' for restrictions in the AnchorCertificates
+    // trusted certificates list
+    private static boolean checkFingerprint(X509Certificate cert) {
+        if (!publicCALimits) {
+            return false;
+        }
+
+        if (debug != null) {
+            debug.println("AlgorithmChecker.contains: " + cert.getSigAlgName());
+        }
+        return AnchorCertificates.contains(cert);
+    }
+
     @Override
     public void init(boolean forward) throws CertPathValidatorException {
         //  Note that this class does not support forward mode.
@@ -181,36 +209,8 @@
             return;
         }
 
-        X509CertImpl x509Cert = null;
-        try {
-            x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
-        } catch (CertificateException ce) {
-            throw new CertPathValidatorException(ce);
-        }
-
-        PublicKey currPubKey = x509Cert.getPublicKey();
-        String currSigAlg = x509Cert.getSigAlgName();
-
-        AlgorithmId algorithmId = null;
-        try {
-            algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
-        } catch (CertificateException ce) {
-            throw new CertPathValidatorException(ce);
-        }
-
-        AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
-
-        // Check the current signature algorithm
-        if (!constraints.permits(
-                SIGNATURE_PRIMITIVE_SET,
-                currSigAlg, currSigAlgParams)) {
-            throw new CertPathValidatorException(
-                "Algorithm constraints check failed: " + currSigAlg,
-                null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
-        }
-
         // check the key usage and key size
-        boolean[] keyUsage = x509Cert.getKeyUsage();
+        boolean[] keyUsage = ((X509Certificate) cert).getKeyUsage();
         if (keyUsage != null && keyUsage.length < 9) {
             throw new CertPathValidatorException(
                 "incorrect KeyUsage extension",
@@ -248,27 +248,67 @@
 
             if (primitives.isEmpty()) {
                 throw new CertPathValidatorException(
-                    "incorrect KeyUsage extension",
+                    "incorrect KeyUsage extension bits",
                     null, null, -1, PKIXReason.INVALID_KEY_USAGE);
             }
         }
 
-        if (!constraints.permits(primitives, currPubKey)) {
-            throw new CertPathValidatorException(
-                "algorithm constraints check failed",
-                null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
+        PublicKey currPubKey = cert.getPublicKey();
+
+        // Check against DisabledAlgorithmConstraints certpath constraints.
+        // permits() will throw exception on failure.
+        certPathDefaultConstraints.permits(primitives,
+                new CertConstraintParameters((X509Certificate)cert,
+                        trustedMatch));
+                // new CertConstraintParameters(x509Cert, trustedMatch));
+        // If there is no previous key, set one and exit
+        if (prevPubKey == null) {
+            prevPubKey = currPubKey;
+            return;
+        }
+
+        X509CertImpl x509Cert;
+        AlgorithmId algorithmId;
+        try {
+            x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
+            algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
+        } catch (CertificateException ce) {
+            throw new CertPathValidatorException(ce);
+        }
+
+        AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
+        String currSigAlg = x509Cert.getSigAlgName();
+
+        // If 'constraints' is not of DisabledAlgorithmConstraints, check all
+        // everything individually
+        if (!(constraints instanceof DisabledAlgorithmConstraints)) {
+            // Check the current signature algorithm
+            if (!constraints.permits(
+                    SIGNATURE_PRIMITIVE_SET,
+                    currSigAlg, currSigAlgParams)) {
+                throw new CertPathValidatorException(
+                        "Algorithm constraints check failed on signature " +
+                                "algorithm: " + currSigAlg, null, null, -1,
+                        BasicReason.ALGORITHM_CONSTRAINED);
+            }
+
+            if (!constraints.permits(primitives, currPubKey)) {
+                throw new CertPathValidatorException(
+                        "Algorithm constraints check failed on keysize: " +
+                                sun.security.util.KeyUtil.getKeySize(currPubKey),
+                        null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
+            }
         }
 
         // Check with previous cert for signature algorithm and public key
         if (prevPubKey != null) {
-            if (currSigAlg != null) {
-                if (!constraints.permits(
-                        SIGNATURE_PRIMITIVE_SET,
-                        currSigAlg, prevPubKey, currSigAlgParams)) {
-                    throw new CertPathValidatorException(
-                        "Algorithm constraints check failed: " + currSigAlg,
-                        null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
-                }
+            if (!constraints.permits(
+                    SIGNATURE_PRIMITIVE_SET,
+                    currSigAlg, prevPubKey, currSigAlgParams)) {
+                throw new CertPathValidatorException(
+                    "Algorithm constraints check failed on " +
+                            "signature algorithm: " + currSigAlg,
+                    null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
             }
 
             // Inherit key parameters from previous key
@@ -282,7 +322,7 @@
                 DSAParams params = ((DSAPublicKey)prevPubKey).getParams();
                 if (params == null) {
                     throw new CertPathValidatorException(
-                                    "Key parameters missing");
+                        "Key parameters missing from public key.");
                 }
 
                 try {
@@ -330,6 +370,11 @@
             // Don't bother to change the trustedPubKey.
             if (anchor.getTrustedCert() != null) {
                 prevPubKey = anchor.getTrustedCert().getPublicKey();
+                // Check for anchor certificate restrictions
+                trustedMatch = checkFingerprint(anchor.getTrustedCert());
+                if (trustedMatch && debug != null) {
+                    debug.println("trustedMatch = true");
+                }
             } else {
                 prevPubKey = anchor.getCAPublicKey();
             }
@@ -370,7 +415,8 @@
         if (!certPathDefaultConstraints.permits(
                 SIGNATURE_PRIMITIVE_SET, sigAlgName, key, sigAlgParams)) {
             throw new CertPathValidatorException(
-                "algorithm check failed: " + sigAlgName + " is disabled",
+                "Algorithm constraints check failed on signature algorithm: " +
+                sigAlgName + " is disabled",
                 null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
         }
     }
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/PKIXMasterCertPathValidator.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/PKIXMasterCertPathValidator.java	Thu Apr 28 23:08:16 2016 -0700
@@ -131,8 +131,8 @@
 
                 } catch (CertPathValidatorException cpve) {
                     throw new CertPathValidatorException(cpve.getMessage(),
-                        cpve.getCause(), cpOriginal, cpSize - (i + 1),
-                        cpve.getReason());
+                        (cpve.getCause() != null) ? cpve.getCause() : cpve,
+                            cpOriginal, cpSize - (i + 1), cpve.getReason());
                 }
             }
 
--- a/jdk/src/java.base/share/classes/sun/security/rsa/RSAKeyFactory.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/rsa/RSAKeyFactory.java	Thu Apr 28 23:08:16 2016 -0700
@@ -84,9 +84,8 @@
     public static final int MAX_RESTRICTED_EXPLEN = 64;
 
     private static final boolean restrictExpLen =
-        "true".equalsIgnoreCase(AccessController.doPrivileged(
-            new GetPropertyAction(
-                "sun.security.rsa.restrictRSAExponent", "true")));
+        "true".equalsIgnoreCase(GetPropertyAction.getProperty(
+                "sun.security.rsa.restrictRSAExponent", "true"));
 
     // instance used for static translateKey();
     private static final RSAKeyFactory INSTANCE = new RSAKeyFactory();
--- a/jdk/src/java.base/share/classes/sun/security/ssl/ClientKeyExchangeService.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/ClientKeyExchangeService.java	Thu Apr 28 23:08:16 2016 -0700
@@ -50,10 +50,7 @@
                 providers = new HashMap<>();
 
         static {
-            final String key = "java.home";
-            String path = AccessController.doPrivileged(
-                    new GetPropertyAction(key), null,
-                    new PropertyPermission(key, "read"));
+            String path = GetPropertyAction.getProperty("java.home");
             ServiceLoader<ClientKeyExchangeService> sc =
                     AccessController.doPrivileged(
                             (PrivilegedAction<ServiceLoader<ClientKeyExchangeService>>)
--- a/jdk/src/java.base/share/classes/sun/security/ssl/Debug.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/Debug.java	Thu Apr 28 23:08:16 2016 -0700
@@ -26,7 +26,6 @@
 package sun.security.ssl;
 
 import java.io.PrintStream;
-import java.security.AccessController;
 import java.util.Locale;
 
 import sun.security.util.HexDumpEncoder;
@@ -46,8 +45,7 @@
     private static String args;
 
     static {
-        args = java.security.AccessController.doPrivileged(
-            new GetPropertyAction("javax.net.debug", ""));
+        args = GetPropertyAction.getProperty("javax.net.debug", "");
         args = args.toLowerCase(Locale.ENGLISH);
         if (args.equals("help")) {
             Help();
@@ -184,8 +182,7 @@
      */
     static boolean getBooleanProperty(String propName, boolean defaultValue) {
         // if set, require value of either true or false
-        String b = AccessController.doPrivileged(
-                new GetPropertyAction(propName));
+        String b = GetPropertyAction.getProperty(propName);
         if (b == null) {
             return defaultValue;
         } else if (b.equalsIgnoreCase("false")) {
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -656,8 +656,7 @@
         // the provider service. Instead, please handle the initialization
         // exception in the caller's constructor.
         static {
-            String property = AccessController.doPrivileged(
-                    new GetPropertyAction(PROPERTY_NAME));
+            String property = GetPropertyAction.getProperty(PROPERTY_NAME);
             if (property != null && property.length() != 0) {
                 // remove double quote marks from beginning/end of the property
                 if (property.length() > 1 && property.charAt(0) == '"' &&
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -209,6 +209,12 @@
     Collection<SNIMatcher>      sniMatchers =
                                     Collections.<SNIMatcher>emptyList();
 
+    // Is the serverNames set to empty with SSLParameters.setServerNames()?
+    private boolean             noSniExtension = false;
+
+    // Is the sniMatchers set to empty with SSLParameters.setSNIMatchers()?
+    private boolean             noSniMatcher = false;
+
     // Configured application protocol values
     String[] applicationProtocols = new String[0];
 
@@ -642,6 +648,11 @@
         }
 
         super.connect(endpoint, timeout);
+
+        if (host == null || host.length() == 0) {
+            useImplicitHost(false);
+        }
+
         doneConnect();
     }
 
@@ -2098,41 +2109,62 @@
         outputRecord.setVersion(protocolVersion);
     }
 
+    //
+    // ONLY used by ClientHandshaker for the server hostname during handshaking
+    //
     synchronized String getHost() {
         // Note that the host may be null or empty for localhost.
         if (host == null || host.length() == 0) {
-            if (!trustNameService) {
-                // If the local name service is not trustworthy, reverse host
-                // name resolution should not be performed for endpoint
-                // identification.  Use the application original specified
-                // hostname or IP address instead.
-                host = getOriginalHostname(getInetAddress());
-            } else {
-                host = getInetAddress().getHostName();
-            }
+            useImplicitHost(true);
         }
 
         return host;
     }
 
     /*
-     * Get the original application specified hostname.
+     * Try to set and use the implicit specified hostname
      */
-    private static String getOriginalHostname(InetAddress inetAddress) {
-        /*
-         * Get the original hostname via jdk.internal.misc.SharedSecrets.
-         */
-        JavaNetInetAddressAccess jna = SharedSecrets.getJavaNetInetAddressAccess();
-        String originalHostname = jna.getOriginalHostName(inetAddress);
+    private synchronized void useImplicitHost(boolean noSniUpdate) {
 
-        /*
-         * If no application specified hostname, use the IP address.
-         */
-        if (originalHostname == null || originalHostname.length() == 0) {
-            originalHostname = inetAddress.getHostAddress();
+        // Note: If the local name service is not trustworthy, reverse
+        // host name resolution should not be performed for endpoint
+        // identification.  Use the application original specified
+        // hostname or IP address instead.
+
+        // Get the original hostname via jdk.internal.misc.SharedSecrets
+        InetAddress inetAddress = getInetAddress();
+        if (inetAddress == null) {      // not connected
+            return;
         }
 
-        return originalHostname;
+        JavaNetInetAddressAccess jna =
+                SharedSecrets.getJavaNetInetAddressAccess();
+        String originalHostname = jna.getOriginalHostName(inetAddress);
+        if ((originalHostname != null) &&
+                (originalHostname.length() != 0)) {
+
+            host = originalHostname;
+            if (!noSniUpdate && serverNames.isEmpty() && !noSniExtension) {
+                serverNames =
+                        Utilities.addToSNIServerNameList(serverNames, host);
+
+                if (!roleIsServer &&
+                        (handshaker != null) && !handshaker.started()) {
+                    handshaker.setSNIServerNames(serverNames);
+                }
+            }
+
+            return;
+        }
+
+        // No explicitly specified hostname, no server name indication.
+        if (!trustNameService) {
+            // The local name service is not trustworthy, use IP address.
+            host = inetAddress.getHostAddress();
+        } else {
+            // Use the underlying reverse host name resolution service.
+            host = getInetAddress().getHostName();
+        }
     }
 
     // ONLY used by HttpsClient to setup the URI specified hostname
@@ -2144,6 +2176,10 @@
         this.host = host;
         this.serverNames =
             Utilities.addToSNIServerNameList(this.serverNames, this.host);
+
+        if (!roleIsServer && (handshaker != null) && !handshaker.started()) {
+            handshaker.setSNIServerNames(serverNames);
+        }
     }
 
     /**
@@ -2533,8 +2569,21 @@
         // the super implementation does not handle the following parameters
         params.setEndpointIdentificationAlgorithm(identificationProtocol);
         params.setAlgorithmConstraints(algorithmConstraints);
-        params.setSNIMatchers(sniMatchers);
-        params.setServerNames(serverNames);
+
+        if (sniMatchers.isEmpty() && !noSniMatcher) {
+            // 'null' indicates none has been set
+            params.setSNIMatchers(null);
+        } else {
+            params.setSNIMatchers(sniMatchers);
+        }
+
+        if (serverNames.isEmpty() && !noSniExtension) {
+            // 'null' indicates none has been set
+            params.setServerNames(null);
+        } else {
+            params.setServerNames(serverNames);
+        }
+
         params.setUseCipherSuitesOrder(preferLocalCipherSuites);
         params.setMaximumPacketSize(maximumPacketSize);
         params.setApplicationProtocols(applicationProtocols);
@@ -2568,11 +2617,13 @@
 
         List<SNIServerName> sniNames = params.getServerNames();
         if (sniNames != null) {
+            noSniExtension = sniNames.isEmpty();
             serverNames = sniNames;
         }
 
         Collection<SNIMatcher> matchers = params.getSNIMatchers();
         if (matchers != null) {
+            noSniMatcher = matchers.isEmpty();
             sniMatchers = matchers;
         }
 
--- a/jdk/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java	Thu Apr 28 23:08:16 2016 -0700
@@ -119,8 +119,8 @@
     private long statusRespTimeout;
 
     static {
-        String property = AccessController.doPrivileged(
-                    new GetPropertyAction("jdk.tls.ephemeralDHKeySize"));
+        String property =
+                GetPropertyAction.getProperty("jdk.tls.ephemeralDHKeySize");
         if (property == null || property.length() == 0) {
             useLegacyEphemeralDHKeys = false;
             useSmartEphemeralDHKeys = false;
--- a/jdk/src/java.base/share/classes/sun/security/ssl/StatusResponseManager.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/StatusResponseManager.java	Thu Apr 28 23:08:16 2016 -0700
@@ -73,8 +73,8 @@
                     DEFAULT_CACHE_LIFETIME));
         cacheLifetime = life > 0 ? life : 0;
 
-        String uriStr = AccessController.doPrivileged(
-                new GetPropertyAction("jdk.tls.stapling.responderURI"));
+        String uriStr =
+                GetPropertyAction.getProperty("jdk.tls.stapling.responderURI");
         URI tmpURI;
         try {
             tmpURI = ((uriStr != null && !uriStr.isEmpty()) ?
--- a/jdk/src/java.base/share/classes/sun/security/util/AbstractAlgorithmConstraints.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/util/AbstractAlgorithmConstraints.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016 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,7 +29,6 @@
 import java.security.AlgorithmConstraints;
 import java.security.PrivilegedAction;
 import java.security.Security;
-import java.util.Map;
 import java.util.Set;
 
 /**
@@ -45,8 +44,7 @@
     }
 
     // Get algorithm constraints from the specified security property.
-    private static void loadAlgorithmsMap(Map<String, String[]> algorithmsMap,
-            String propertyName) {
+    static String[] getAlgorithms(String propertyName) {
         String property = AccessController.doPrivileged(
                 (PrivilegedAction<String>) () -> Security.getProperty(
                         propertyName));
@@ -68,18 +66,7 @@
         if (algorithmsInProperty == null) {
             algorithmsInProperty = new String[0];
         }
-        algorithmsMap.put(propertyName, algorithmsInProperty);
-    }
-
-    static String[] getAlgorithms(Map<String, String[]> algorithmsMap,
-            String propertyName) {
-        synchronized (algorithmsMap) {
-            if (!algorithmsMap.containsKey(propertyName)) {
-                loadAlgorithmsMap(algorithmsMap, propertyName);
-            }
-
-            return algorithmsMap.get(propertyName);
-        }
+        return algorithmsInProperty;
     }
 
     static boolean checkAlgorithm(String[] algorithms, String algorithm,
--- a/jdk/src/java.base/share/classes/sun/security/util/AlgorithmDecomposer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/util/AlgorithmDecomposer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,19 +40,7 @@
     private static final Pattern pattern =
             Pattern.compile("with|and|(?<!padd)in", Pattern.CASE_INSENSITIVE);
 
-    /**
-     * Decompose the standard algorithm name into sub-elements.
-     * <p>
-     * For example, we need to decompose "SHA1WithRSA" into "SHA1" and "RSA"
-     * so that we can check the "SHA1" and "RSA" algorithm constraints
-     * separately.
-     * <p>
-     * Please override the method if need to support more name pattern.
-     */
-    public Set<String> decompose(String algorithm) {
-        if (algorithm == null || algorithm.length() == 0) {
-            return new HashSet<>();
-        }
+    private static Set<String> decomposeImpl(String algorithm) {
 
         // algorithm/mode/padding
         String[] transTockens = transPattern.split(algorithm);
@@ -79,6 +67,24 @@
                 elements.add(token);
             }
         }
+        return elements;
+    }
+
+    /**
+     * Decompose the standard algorithm name into sub-elements.
+     * <p>
+     * For example, we need to decompose "SHA1WithRSA" into "SHA1" and "RSA"
+     * so that we can check the "SHA1" and "RSA" algorithm constraints
+     * separately.
+     * <p>
+     * Please override the method if need to support more name pattern.
+     */
+    public Set<String> decompose(String algorithm) {
+        if (algorithm == null || algorithm.length() == 0) {
+            return new HashSet<>();
+        }
+
+        Set<String> elements = decomposeImpl(algorithm);
 
         // In Java standard algorithm name specification, for different
         // purpose, the SHA-1 and SHA-2 algorithm names are different. For
@@ -130,4 +136,40 @@
         return elements;
     }
 
+    private static void hasLoop(Set<String> elements, String find, String replace) {
+        if (elements.contains(find)) {
+            if (!elements.contains(replace)) {
+                elements.add(replace);
+            }
+            elements.remove(find);
+        }
+    }
+
+    /*
+     * This decomposes a standard name into sub-elements with a consistent
+     * message digest algorithm name to avoid overly complicated checking.
+     */
+    public static Set<String> decomposeOneHash(String algorithm) {
+        if (algorithm == null || algorithm.length() == 0) {
+            return new HashSet<>();
+        }
+
+        Set<String> elements = decomposeImpl(algorithm);
+
+        hasLoop(elements, "SHA-1", "SHA1");
+        hasLoop(elements, "SHA-224", "SHA224");
+        hasLoop(elements, "SHA-256", "SHA256");
+        hasLoop(elements, "SHA-384", "SHA384");
+        hasLoop(elements, "SHA-512", "SHA512");
+
+        return elements;
+    }
+
+    /*
+     * The provided message digest algorithm name will return a consistent
+     * naming scheme.
+     */
+    public static String hashName(String algorithm) {
+        return algorithm.replace("-", "");
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/util/AnchorCertificates.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.security.AccessController;
+import java.security.KeyStore;
+import java.security.PrivilegedAction;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.HashSet;
+
+import sun.security.x509.X509CertImpl;
+
+/**
+ * The purpose of this class is to determine the trust anchor certificates is in
+ * the cacerts file.  This is used for PKIX CertPath checking.
+ */
+public class AnchorCertificates {
+
+    private static final Debug debug = Debug.getInstance("certpath");
+    private static final String HASH = "SHA-256";
+    private static HashSet<String> certs;
+
+    static  {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            @Override
+            public Void run() {
+                File f = new File(System.getProperty("java.home"),
+                        "lib/security/cacerts");
+                KeyStore cacerts;
+                try {
+                    cacerts = KeyStore.getInstance("JKS");
+                    try (FileInputStream fis = new FileInputStream(f)) {
+                        cacerts.load(fis, "changeit".toCharArray());
+                        certs = new HashSet<>();
+                        Enumeration<String> list = cacerts.aliases();
+                        String alias;
+                        while (list.hasMoreElements()) {
+                            alias = list.nextElement();
+                            // Check if this cert is labeled a trust anchor.
+                            if (alias.contains(" [jdk")) {
+                                X509Certificate cert = (X509Certificate) cacerts
+                                        .getCertificate(alias);
+                                certs.add(X509CertImpl.getFingerprint(HASH, cert));
+                            }
+                        }
+                    }
+                } catch (Exception e) {
+                    if (debug != null) {
+                        debug.println("Error parsing cacerts");
+                    }
+                    e.printStackTrace();
+                }
+                return null;
+            }
+        });
+    }
+
+    /**
+     * Checks if a certificate is a trust anchor.
+     *
+     * @param cert the certificate to check
+     * @return true if the certificate is trusted.
+     */
+    public static boolean contains(X509Certificate cert) {
+        String key = X509CertImpl.getFingerprint(HASH, cert);
+        boolean result = certs.contains(key);
+        if (result && debug != null) {
+            debug.println("AnchorCertificate.contains: matched " +
+                    cert.getSubjectDN());
+        }
+        return result;
+    }
+
+    private AnchorCertificates() {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/util/CertConstraintParameters.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+import java.security.cert.X509Certificate;
+
+/**
+ * This class is a wrapper for keeping state and passing objects between PKIX,
+ * AlgorithmChecker, and DisabledAlgorithmConstraints.
+ */
+public class CertConstraintParameters {
+    // A certificate being passed to check against constraints.
+    private final X509Certificate cert;
+
+    // This is true if the trust anchor in the certificate chain matches a cert
+    // in AnchorCertificates
+    private final boolean trustedMatch;
+
+    public CertConstraintParameters(X509Certificate c, boolean match) {
+        cert = c;
+        trustedMatch = match;
+    }
+
+    public CertConstraintParameters(X509Certificate c) {
+        this(c, false);
+    }
+
+    // Returns if the trust anchor has a match if anchor checking is enabled.
+    public boolean isTrustedMatch() {
+        return trustedMatch;
+    }
+
+    public X509Certificate getCertificate() {
+        return cert;
+    }
+}
--- a/jdk/src/java.base/share/classes/sun/security/util/Debug.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/util/Debug.java	Thu Apr 28 23:08:16 2016 -0700
@@ -29,6 +29,7 @@
 import java.util.regex.Pattern;
 import java.util.regex.Matcher;
 import java.util.Locale;
+import sun.security.action.GetPropertyAction;
 
 /**
  * A utility class for debuging.
@@ -42,13 +43,10 @@
     private static String args;
 
     static {
-        args = java.security.AccessController.doPrivileged
-                (new sun.security.action.GetPropertyAction
-                ("java.security.debug"));
+        args = GetPropertyAction.getProperty("java.security.debug");
 
-        String args2 = java.security.AccessController.doPrivileged
-                (new sun.security.action.GetPropertyAction
-                ("java.security.auth.debug"));
+        String args2 =
+                GetPropertyAction.getProperty("java.security.auth.debug");
 
         if (args == null) {
             args = args2;
--- a/jdk/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,12 +28,14 @@
 import java.security.CryptoPrimitive;
 import java.security.AlgorithmParameters;
 import java.security.Key;
+import java.security.cert.CertPathValidatorException;
+import java.security.cert.CertPathValidatorException.BasicReason;
+import java.security.cert.X509Certificate;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Locale;
+import java.util.Map;
 import java.util.Set;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.HashMap;
 import java.util.regex.Pattern;
 import java.util.regex.Matcher;
 
@@ -44,6 +46,7 @@
  * for the syntax of the disabled algorithm string.
  */
 public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
+    private static final Debug debug = Debug.getInstance("certpath");
 
     // the known security property, jdk.certpath.disabledAlgorithms
     public static final String PROPERTY_CERTPATH_DISABLED_ALGS =
@@ -53,13 +56,8 @@
     public static final String PROPERTY_TLS_DISABLED_ALGS =
             "jdk.tls.disabledAlgorithms";
 
-    private static final Map<String, String[]> disabledAlgorithmsMap =
-                                                            new HashMap<>();
-    private static final Map<String, KeySizeConstraints> keySizeConstraintsMap =
-                                                            new HashMap<>();
-
     private final String[] disabledAlgorithms;
-    private final KeySizeConstraints keySizeConstraints;
+    private final Constraints algorithmConstraints;
 
     /**
      * Initialize algorithm constraints with the specified security property.
@@ -74,11 +72,14 @@
     public DisabledAlgorithmConstraints(String propertyName,
             AlgorithmDecomposer decomposer) {
         super(decomposer);
-        disabledAlgorithms = getAlgorithms(disabledAlgorithmsMap, propertyName);
-        keySizeConstraints = getKeySizeConstraints(disabledAlgorithms,
-                propertyName);
+        disabledAlgorithms = getAlgorithms(propertyName);
+        algorithmConstraints = new Constraints(disabledAlgorithms);
     }
 
+    /*
+     * This only checks if the algorithm has been completely disabled.  If
+     * there are keysize or other limit, this method allow the algorithm.
+     */
     @Override
     public final boolean permits(Set<CryptoPrimitive> primitives,
             String algorithm, AlgorithmParameters parameters) {
@@ -91,11 +92,19 @@
         return checkAlgorithm(disabledAlgorithms, algorithm, decomposer);
     }
 
+    /*
+     * Checks if the key algorithm has been disabled or constraints have been
+     * placed on the key.
+     */
     @Override
     public final boolean permits(Set<CryptoPrimitive> primitives, Key key) {
         return checkConstraints(primitives, "", key, null);
     }
 
+    /*
+     * Checks if the key algorithm has been disabled or if constraints have
+     * been placed on the key.
+     */
     @Override
     public final boolean permits(Set<CryptoPrimitive> primitives,
             String algorithm, Key key, AlgorithmParameters parameters) {
@@ -107,7 +116,39 @@
         return checkConstraints(primitives, algorithm, key, parameters);
     }
 
-    // Check algorithm constraints
+    /*
+     * Check if a x509Certificate object is permitted.  Check if all
+     * algorithms are allowed, certificate constraints, and the
+     * public key against key constraints.
+     *
+     * Uses new style permit() which throws exceptions.
+     */
+    public final void permits(Set<CryptoPrimitive> primitives,
+            CertConstraintParameters cp) throws CertPathValidatorException {
+        checkConstraints(primitives, cp);
+    }
+
+    /*
+     * Check if Certificate object is within the constraints.
+     * Uses new style permit() which throws exceptions.
+     */
+    public final void permits(Set<CryptoPrimitive> primitives,
+            X509Certificate cert) throws CertPathValidatorException {
+        checkConstraints(primitives, new CertConstraintParameters(cert));
+    }
+
+    // Check if a string is contained inside the property
+    public boolean checkProperty(String param) {
+        param = param.toLowerCase(Locale.ENGLISH);
+        for (String block : disabledAlgorithms) {
+            if (block.toLowerCase(Locale.ENGLISH).indexOf(param) >= 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    // Check algorithm constraints with key and algorithm
     private boolean checkConstraints(Set<CryptoPrimitive> primitives,
             String algorithm, Key key, AlgorithmParameters parameters) {
 
@@ -116,7 +157,7 @@
             throw new IllegalArgumentException("The key cannot be null");
         }
 
-        // check the target algorithm
+        // check the signature algorithm
         if (algorithm != null && algorithm.length() != 0) {
             if (!permits(primitives, algorithm, parameters)) {
                 return false;
@@ -129,97 +170,203 @@
         }
 
         // check the key constraints
-        if (keySizeConstraints.disables(key)) {
-            return false;
-        }
-
-        return true;
+        return algorithmConstraints.permits(key);
     }
 
-    private static KeySizeConstraints getKeySizeConstraints(
-            String[] disabledAlgorithms, String propertyName) {
-        synchronized (keySizeConstraintsMap) {
-            if(!keySizeConstraintsMap.containsKey(propertyName)) {
-                // map the key constraints
-                KeySizeConstraints keySizeConstraints =
-                        new KeySizeConstraints(disabledAlgorithms);
-                keySizeConstraintsMap.put(propertyName, keySizeConstraints);
-            }
+    /*
+     * Check algorithm constraints with Certificate
+     * Uses new style permit() which throws exceptions.
+     */
+    private void checkConstraints(Set<CryptoPrimitive> primitives,
+            CertConstraintParameters cp) throws CertPathValidatorException {
+
+        X509Certificate cert = cp.getCertificate();
+        String algorithm = cert.getSigAlgName();
 
-            return keySizeConstraintsMap.get(propertyName);
+        // Check signature algorithm is not disabled
+        if (!permits(primitives, algorithm, null)) {
+            throw new CertPathValidatorException(
+                    "Algorithm constraints check failed on disabled "+
+                            "signature algorithm: " + algorithm,
+                    null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
         }
+
+        // Check key algorithm is not disabled
+        if (!permits(primitives, cert.getPublicKey().getAlgorithm(), null)) {
+            throw new CertPathValidatorException(
+                    "Algorithm constraints check failed on disabled "+
+                            "public key algorithm: " + algorithm,
+                    null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
+        }
+
+        // Check the certificate and key constraints
+        algorithmConstraints.permits(cp);
+
     }
 
     /**
-     * key constraints
+     * Key and Certificate Constraints
+     *
+     * The complete disabling of an algorithm is not handled by Constraints or
+     * Constraint classes.  That is addressed with
+     *   permit(Set<CryptoPrimitive>, String, AlgorithmParameters)
+     *
+     * When passing a Key to permit(), the boolean return values follow the
+     * same as the interface class AlgorithmConstraints.permit().  This is to
+     * maintain compatibility:
+     * 'true' means the operation is allowed.
+     * 'false' means it failed the constraints and is disallowed.
+     *
+     * When passing CertConstraintParameters through permit(), an exception
+     * will be thrown on a failure to better identify why the operation was
+     * disallowed.
      */
-    private static class KeySizeConstraints {
-        private static final Pattern pattern = Pattern.compile(
-                "(\\S+)\\s+keySize\\s*(<=|<|==|!=|>|>=)\\s*(\\d+)");
 
-        private Map<String, Set<KeySizeConstraint>> constraintsMap =
-            Collections.synchronizedMap(
-                        new HashMap<String, Set<KeySizeConstraint>>());
+    private static class Constraints {
+        private Map<String, Set<Constraint>> constraintsMap = new HashMap<>();
+        private static final Pattern keySizePattern = Pattern.compile(
+                "keySize\\s*(<=|<|==|!=|>|>=)\\s*(\\d+)");
 
-        public KeySizeConstraints(String[] restrictions) {
-            for (String restriction : restrictions) {
-                if (restriction == null || restriction.isEmpty()) {
+        public Constraints(String[] constraintArray) {
+            for (String constraintEntry : constraintArray) {
+                if (constraintEntry == null || constraintEntry.isEmpty()) {
                     continue;
                 }
 
-                Matcher matcher = pattern.matcher(restriction);
-                if (matcher.matches()) {
-                    String algorithm = matcher.group(1);
+                constraintEntry = constraintEntry.trim();
+                if (debug != null) {
+                    debug.println("Constraints: " + constraintEntry);
+                }
 
-                    KeySizeConstraint.Operator operator =
-                             KeySizeConstraint.Operator.of(matcher.group(2));
-                    int length = Integer.parseInt(matcher.group(3));
+                // Check if constraint is a complete disabling of an
+                // algorithm or has conditions.
+                String algorithm;
+                String policy;
+                int space = constraintEntry.indexOf(' ');
+                if (space > 0) {
+                    algorithm = AlgorithmDecomposer.hashName(
+                            constraintEntry.substring(0, space).
+                                    toUpperCase(Locale.ENGLISH));
+                    policy = constraintEntry.substring(space + 1);
+                } else {
+                    constraintsMap.computeIfAbsent(
+                            constraintEntry.toUpperCase(Locale.ENGLISH),
+                            k -> new HashSet<>());
+                    continue;
+                }
 
-                    algorithm = algorithm.toLowerCase(Locale.ENGLISH);
+                // Convert constraint conditions into Constraint classes
+                Constraint c, lastConstraint = null;
+                // Allow only one jdkCA entry per constraint entry
+                boolean jdkCALimit = false;
+
+                for (String entry : policy.split("&")) {
+                    entry = entry.trim();
 
-                    synchronized (constraintsMap) {
-                        if (!constraintsMap.containsKey(algorithm)) {
-                            constraintsMap.put(algorithm,
-                                new HashSet<KeySizeConstraint>());
+                    Matcher matcher = keySizePattern.matcher(entry);
+                    if (matcher.matches()) {
+                        if (debug != null) {
+                            debug.println("Constraints set to keySize: " +
+                                    entry);
                         }
+                        c = new KeySizeConstraint(algorithm,
+                                KeySizeConstraint.Operator.of(matcher.group(1)),
+                                Integer.parseInt(matcher.group(2)));
 
-                        Set<KeySizeConstraint> constraintSet =
-                            constraintsMap.get(algorithm);
-                        KeySizeConstraint constraint =
-                            new KeySizeConstraint(operator, length);
-                        constraintSet.add(constraint);
+                    } else if (entry.equalsIgnoreCase("jdkCA")) {
+                        if (debug != null) {
+                            debug.println("Constraints set to jdkCA.");
+                        }
+                        if (jdkCALimit) {
+                            throw new IllegalArgumentException("Only one " +
+                                    "jdkCA entry allowed in property. " +
+                                    "Constraint: " + constraintEntry);
+                        }
+                        c = new jdkCAConstraint(algorithm);
+                        jdkCALimit = true;
+                    } else {
+                        throw new IllegalArgumentException("Error in security" +
+                                " property. Constraint unknown: " + entry);
                     }
+
+                    // Link multiple conditions for a single constraint
+                    // into a linked list.
+                    if (lastConstraint == null) {
+                        if (!constraintsMap.containsKey(algorithm)) {
+                            constraintsMap.putIfAbsent(algorithm,
+                                    new HashSet<>());
+                        }
+                        constraintsMap.get(algorithm).add(c);
+                    } else {
+                        lastConstraint.nextConstraint = c;
+                    }
+                    lastConstraint = c;
                 }
             }
         }
 
-        // Does this KeySizeConstraints disable the specified key?
-        public boolean disables(Key key) {
-            String algorithm = key.getAlgorithm().toLowerCase(Locale.ENGLISH);
-            synchronized (constraintsMap) {
-                if (constraintsMap.containsKey(algorithm)) {
-                    Set<KeySizeConstraint> constraintSet =
-                                        constraintsMap.get(algorithm);
-                    for (KeySizeConstraint constraint : constraintSet) {
-                        if (constraint.disables(key)) {
-                            return true;
-                        }
+        // Get applicable constraints based off the signature algorithm
+        private Set<Constraint> getConstraints(String algorithm) {
+            return constraintsMap.get(algorithm);
+        }
+
+        // Check if KeySizeConstraints permit the specified key
+        public boolean permits(Key key) {
+            Set<Constraint> set = getConstraints(key.getAlgorithm());
+            if (set == null) {
+                return true;
+            }
+            for (Constraint constraint : set) {
+                if (!constraint.permits(key)) {
+                    if (debug != null) {
+                        debug.println("keySizeConstraint: failed key " +
+                                "constraint check " + KeyUtil.getKeySize(key));
                     }
+                    return false;
                 }
             }
+            return true;
+        }
 
-            return false;
+        // Check if constraints permit this cert.
+        public void permits(CertConstraintParameters cp)
+                throws CertPathValidatorException {
+            X509Certificate cert = cp.getCertificate();
+
+            if (debug != null) {
+                debug.println("Constraints.permits(): " + cert.getSigAlgName());
+            }
+
+            // Get all signature algorithms to check for constraints
+            Set<String> algorithms =
+                    AlgorithmDecomposer.decomposeOneHash(cert.getSigAlgName());
+            if (algorithms == null || algorithms.isEmpty()) {
+                return;
+            }
+
+            // Attempt to add the public key algorithm to the set
+            algorithms.add(cert.getPublicKey().getAlgorithm());
+
+            // Check all applicable constraints
+            for (String algorithm : algorithms) {
+                Set<Constraint> set = getConstraints(algorithm);
+                if (set == null) {
+                    continue;
+                }
+                for (Constraint constraint : set) {
+                    constraint.permits(cp);
+                }
+            }
         }
     }
 
-    /**
-     * Key size constraint.
-     *
-     * e.g.  "keysize <= 1024"
-     */
-    private static class KeySizeConstraint {
+    // Abstract class for algorithm constraint checking
+    private abstract static class Constraint {
+        String algorithm;
+        Constraint nextConstraint = null;
+
         // operator
-        static enum Operator {
+        enum Operator {
             EQ,         // "=="
             NE,         // "!="
             LT,         // "<"
@@ -243,16 +390,77 @@
                         return GE;
                 }
 
-                throw new IllegalArgumentException(
-                        s + " is not a legal Operator");
+                throw new IllegalArgumentException("Error in security " +
+                        "property. " + s + " is not a legal Operator");
             }
         }
 
+        /**
+         * Check if an algorithm constraint permit this key to be used.
+         * @param key Public key
+         * @return true if constraints do not match
+         */
+        public boolean permits(Key key) {
+            return true;
+        }
+
+        /**
+         * Check if an algorithm constraint is permit this certificate to
+         * be used.
+         * @param cp CertificateParameter containing certificate and state info
+         * @return true if constraints do not match
+         */
+        public abstract void permits(CertConstraintParameters cp)
+                throws CertPathValidatorException;
+    }
+
+    /*
+     * This class contains constraints dealing with the certificate chain
+     * of the certificate.
+     */
+    private static class jdkCAConstraint extends Constraint {
+        jdkCAConstraint(String algo) {
+            algorithm = algo;
+        }
+
+        /*
+         * Check if each constraint fails and check if there is a linked
+         * constraint  Any permitted constraint will exit the linked list
+         * to allow the operation.
+         */
+        public void permits(CertConstraintParameters cp)
+                throws CertPathValidatorException {
+            if (debug != null) {
+                debug.println("jdkCAConstraints.permits(): " + algorithm);
+            }
+
+            // Return false if the chain has a trust anchor in cacerts
+            if (cp.isTrustedMatch()) {
+                if (nextConstraint != null) {
+                    nextConstraint.permits(cp);
+                    return;
+                }
+                throw new CertPathValidatorException(
+                        "Algorithm constraints check failed on certificate " +
+                                "anchor limits",
+                        null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
+            }
+        }
+    }
+
+
+    /*
+     * This class contains constraints dealing with the key size
+     * support limits per algorithm.   e.g.  "keySize <= 1024"
+     */
+    private static class KeySizeConstraint extends Constraint {
+
         private int minSize;            // the minimal available key size
         private int maxSize;            // the maximal available key size
         private int prohibitedSize = -1;    // unavailable key sizes
 
-        public KeySizeConstraint(Operator operator, int length) {
+        public KeySizeConstraint(String algo, Operator operator, int length) {
+            algorithm = algo;
             switch (operator) {
                 case EQ:      // an unavailable key size
                     this.minSize = 0;
@@ -286,21 +494,59 @@
             }
         }
 
-        // Does this key constraint disable the specified key?
-        public boolean disables(Key key) {
-            int size = KeyUtil.getKeySize(key);
+        /*
+         * If we are passed a certificate, extract the public key and use it.
+         *
+         * Check if each constraint fails and check if there is a linked
+         * constraint  Any permitted constraint will exit the linked list
+         * to allow the operation.
+         */
+        public void permits(CertConstraintParameters cp)
+                throws CertPathValidatorException {
+            if (!permitsImpl(cp.getCertificate().getPublicKey())) {
+                if (nextConstraint != null) {
+                    nextConstraint.permits(cp);
+                    return;
+                }
+                throw new CertPathValidatorException(
+                        "Algorithm constraints check failed on keysize limits",
+                        null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
+            }
+        }
+
 
+        // Check if key constraint disable the specified key
+        // Uses old style permit()
+        public boolean permits(Key key) {
+            // If we recursively find a constraint that permits us to use
+            // this key, return true and skip any other constraint checks.
+            if (nextConstraint != null && nextConstraint.permits(key)) {
+                return true;
+            }
+            if (debug != null) {
+                debug.println("KeySizeConstraints.permits(): " + algorithm);
+            }
+
+            return permitsImpl(key);
+        }
+
+        private boolean permitsImpl(Key key) {
+            // Verify this constraint is for this public key algorithm
+            if (algorithm.compareToIgnoreCase(key.getAlgorithm()) != 0) {
+                return true;
+            }
+
+            int size = KeyUtil.getKeySize(key);
             if (size == 0) {
-                return true;    // we don't allow any key of size 0.
+                return false;    // we don't allow any key of size 0.
             } else if (size > 0) {
-                return ((size < minSize) || (size > maxSize) ||
+                return !((size < minSize) || (size > maxSize) ||
                     (prohibitedSize == size));
             }   // Otherwise, the key size is not accessible. Conservatively,
                 // please don't disable such keys.
 
-            return false;
+            return true;
         }
     }
-
 }
 
--- a/jdk/src/java.base/share/classes/sun/security/util/LegacyAlgorithmConstraints.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/util/LegacyAlgorithmConstraints.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,8 +28,6 @@
 import java.security.AlgorithmParameters;
 import java.security.CryptoPrimitive;
 import java.security.Key;
-import java.util.HashMap;
-import java.util.Map;
 import java.util.Set;
 import static sun.security.util.AbstractAlgorithmConstraints.getAlgorithms;
 
@@ -42,15 +40,12 @@
     public static final String PROPERTY_TLS_LEGACY_ALGS =
             "jdk.tls.legacyAlgorithms";
 
-    private static final Map<String, String[]> legacyAlgorithmsMap =
-                                                          new HashMap<>();
-
     private final String[] legacyAlgorithms;
 
     public LegacyAlgorithmConstraints(String propertyName,
             AlgorithmDecomposer decomposer) {
         super(decomposer);
-        legacyAlgorithms = getAlgorithms(legacyAlgorithmsMap, propertyName);
+        legacyAlgorithms = getAlgorithms(propertyName);
     }
 
     @Override
--- a/jdk/src/java.base/share/classes/sun/security/x509/X509CertImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/x509/X509CertImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, 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
@@ -1924,17 +1924,18 @@
 
     public String getFingerprint(String algorithm) {
         return fingerprints.computeIfAbsent(algorithm,
-                x -> getCertificateFingerPrint(x));
+            x -> getFingerprint(x, this));
     }
 
     /**
      * Gets the requested finger print of the certificate. The result
      * only contains 0-9 and A-F. No small case, no colon.
      */
-    private String getCertificateFingerPrint(String mdAlg) {
+    public static String getFingerprint(String algorithm,
+            X509Certificate cert) {
         try {
-            byte[] encCertInfo = getEncoded();
-            MessageDigest md = MessageDigest.getInstance(mdAlg);
+            byte[] encCertInfo = cert.getEncoded();
+            MessageDigest md = MessageDigest.getInstance(algorithm);
             byte[] digest = md.digest(encCertInfo);
             StringBuilder sb = new StringBuilder(digest.length * 2);
             for (int i = 0; i < digest.length; i++) {
--- a/jdk/src/java.base/share/classes/sun/util/calendar/LocalGregorianCalendar.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/util/calendar/LocalGregorianCalendar.java	Thu Apr 28 23:08:16 2016 -0700
@@ -27,6 +27,7 @@
 
 import java.security.AccessController;
 import java.util.TimeZone;
+import sun.security.action.GetPropertyAction;
 
 /**
  *
@@ -142,8 +143,8 @@
         }
 
         // Append an era to the predefined eras if it's given by the property.
-        String prop = AccessController.doPrivileged(
-                new sun.security.action.GetPropertyAction("jdk.calendar.japanese.supplemental.era"));
+        String prop = GetPropertyAction
+                .getProperty("jdk.calendar.japanese.supplemental.era");
         if (prop != null) {
             Era era = parseEraEntry(prop);
             if (era != null) {
--- a/jdk/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java	Thu Apr 28 23:08:16 2016 -0700
@@ -245,11 +245,12 @@
     };
 
     static {
-        String oldmapping = AccessController.doPrivileged(
-            new GetPropertyAction("sun.timezone.ids.oldmapping", "false")).toLowerCase(Locale.ROOT);
+        String oldmapping = GetPropertyAction
+                .getProperty("sun.timezone.ids.oldmapping", "false")
+                .toLowerCase(Locale.ROOT);
         USE_OLDMAPPING = (oldmapping.equals("yes") || oldmapping.equals("true"));
-        AccessController.doPrivileged(new PrivilegedAction<Object>() {
-            public Object run() {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
                 try {
                     String libDir = System.getProperty("java.home") + File.separator + "lib";
                     try (DataInputStream dis = new DataInputStream(
--- a/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,7 +25,6 @@
 
 package sun.util.locale.provider;
 
-import java.security.AccessController;
 import java.text.spi.BreakIteratorProvider;
 import java.text.spi.CollatorProvider;
 import java.text.spi.DateFormatProvider;
@@ -47,6 +46,7 @@
 import java.util.spi.LocaleNameProvider;
 import java.util.spi.LocaleServiceProvider;
 import java.util.spi.TimeZoneNameProvider;
+import sun.security.action.GetPropertyAction;
 import sun.util.spi.CalendarProvider;
 
 /**
@@ -116,8 +116,7 @@
         adapterCache = new ConcurrentHashMap<>();
 
     static {
-        String order = AccessController.doPrivileged(
-                           new sun.security.action.GetPropertyAction("java.locale.providers"));
+        String order = GetPropertyAction.getProperty("java.locale.providers");
         List<Type> typeList = new ArrayList<>();
 
         // Check user specified adapter preference
--- a/jdk/src/java.base/share/classes/sun/util/logging/PlatformLogger.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/util/logging/PlatformLogger.java	Thu Apr 28 23:08:16 2016 -0700
@@ -286,12 +286,15 @@
         }
         if (log == null) {
             log = new PlatformLogger(PlatformLogger.Bridge.convert(
-                    // We pass PlatformLogger.class rather than the actual caller
+                    // We pass PlatformLogger.class.getModule() (java.base)
+                    // rather than the actual module of the caller
                     // because we want PlatformLoggers to be system loggers: we
                     // won't need to resolve any resource bundles anyway.
                     // Note: Many unit tests depend on the fact that
-                    //       PlatformLogger.getLoggerFromFinder is not caller sensitive.
-                    LazyLoggers.getLazyLogger(name, PlatformLogger.class)));
+                    //       PlatformLogger.getLoggerFromFinder is not caller
+                    //       sensitive, and this strategy ensure that the tests
+                    //       still pass.
+                    LazyLoggers.getLazyLogger(name, PlatformLogger.class.getModule())));
             loggers.put(name, new WeakReference<>(log));
         }
         return log;
--- a/jdk/src/java.base/share/conf/security/java.security	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/conf/security/java.security	Thu Apr 28 23:08:16 2016 -0700
@@ -497,13 +497,13 @@
 #       " DisabledAlgorithm { , DisabledAlgorithm } "
 #
 #   DisabledAlgorithm:
-#       AlgorithmName [Constraint]
+#       AlgorithmName [Constraint] { '&' Constraint }
 #
 #   AlgorithmName:
 #       (see below)
 #
 #   Constraint:
-#       KeySizeConstraint
+#       KeySizeConstraint, CertConstraint
 #
 #   KeySizeConstraint:
 #       keySize Operator DecimalInteger
@@ -520,6 +520,9 @@
 #   DecimalDigit: one of
 #       1 2 3 4 5 6 7 8 9 0
 #
+#   CertConstraint
+#       jdkCA
+#
 # The "AlgorithmName" is the standard algorithm name of the disabled
 # algorithm. See "Java Cryptography Architecture Standard Algorithm Name
 # Documentation" for information about Standard Algorithm Names.  Matching
@@ -542,6 +545,29 @@
 # be disabled. Note that the "KeySizeConstraint" only makes sense to key
 # algorithms.
 #
+# "CertConstraint" specifies additional constraints for
+# certificates that contain algorithms that are restricted:
+#
+#   "jdkCA" prohibits the specified algorithm only if the algorithm is used
+#     in a certificate chain that terminates at a marked trust anchor in the
+#     lib/security/cacerts keystore.  All other chains are not affected.
+#     If the jdkCA constraint is not set, then all chains using the
+#     specified algorithm are restricted.  jdkCA may only be used once in
+#     a DisabledAlgorithm expression.
+#     Example:  To apply this constraint to SHA-1 certificates, include
+#     the following:  "SHA1 jdkCA"
+#
+# When an algorithm must satisfy more than one constraint, it must be
+# delimited by an ampersand '&'.  For example, to restrict certificates in a
+# chain that terminate at a distribution provided trust anchor and contain
+# RSA keys that are less than or equal to 1024 bits, add the following
+# constraint:  "RSA keySize <= 1024 & jdkCA".
+#
+# All DisabledAlgorithms expressions are processed in the order defined in the
+# property.  This requires lower keysize constraints to be specified
+# before larger keysize constraints of the same algorithm.  For example:
+# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048".
+#
 # Note: This property is currently used by Oracle's PKIX implementation. It
 # is not guaranteed to be examined and used by other implementations.
 #
--- a/jdk/src/java.base/share/native/include/jvm.h	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/native/include/jvm.h	Thu Apr 28 23:08:16 2016 -0700
@@ -179,7 +179,6 @@
  */
 enum {
   JVM_STACKWALK_FILL_CLASS_REFS_ONLY       = 0x2,
-  JVM_STACKWALK_FILTER_FILL_IN_STACK_TRACE = 0x10,
   JVM_STACKWALK_SHOW_HIDDEN_FRAMES         = 0x20,
   JVM_STACKWALK_FILL_LIVE_STACK_FRAMES     = 0x100
 };
@@ -187,23 +186,15 @@
 JNIEXPORT jobject JNICALL
 JVM_CallStackWalk(JNIEnv *env, jobject stackStream, jlong mode,
                   jint skip_frames, jint frame_count, jint start_index,
-                  jobjectArray classes,
                   jobjectArray frames);
 
 JNIEXPORT jint JNICALL
 JVM_MoreStackWalk(JNIEnv *env, jobject stackStream, jlong mode, jlong anchor,
                   jint frame_count, jint start_index,
-                  jobjectArray classes,
                   jobjectArray frames);
 
 JNIEXPORT void JNICALL
-JVM_FillStackFrames(JNIEnv* env, jclass cls,
-                    jint start_index,
-                    jobjectArray stackFrames,
-                    jint from_index, jint toIndex);
-
-JNIEXPORT void JNICALL
-JVM_SetMethodInfo(JNIEnv* env, jobject frame);
+JVM_ToStackTraceElement(JNIEnv* env, jobject frame, jobject stackElement);
 
 JNIEXPORT jobjectArray JNICALL
 JVM_GetVmArguments(JNIEnv *env);
--- a/jdk/src/java.base/share/native/launcher/defines.h	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/native/launcher/defines.h	Thu Apr 28 23:08:16 2016 -0700
@@ -45,7 +45,11 @@
 
 #ifdef JAVA_ARGS
 #define HAS_JAVA_ARGS JNI_TRUE
-static const char* const_progname = "java";
+#ifdef PROGNAME
+static const char* const_progname = PROGNAME;
+#else
+static char* const_progname = NULL;
+#endif
 static const char* const_jargs[] = JAVA_ARGS;
 /*
  * ApplicationHome is prepended to each of these entries; the resulting
@@ -59,11 +63,7 @@
 #endif /* APP_CLASSPATH */
 #else  /* !JAVA_ARGS */
 #define HAS_JAVA_ARGS JNI_FALSE
-#ifdef PROGNAME
-static const char* const_progname = PROGNAME;
-#else
-static char* const_progname = NULL;
-#endif
+static const char* const_progname = "java";
 static const char** const_jargs = NULL;
 static const char* const_appclasspath[] = { NULL };
 #endif /* JAVA_ARGS */
--- a/jdk/src/java.base/share/native/libjava/StackFrameInfo.c	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/native/libjava/StackFrameInfo.c	Thu Apr 28 23:08:16 2016 -0700
@@ -38,22 +38,10 @@
 
 /*
  * Class:     java_lang_StackFrameInfo
- * Method:    fillInStackFrames
- * Signature: (I[Ljava/lang/Object;[Ljava/lang/Object;II)V
+ * Method:    toStackTraceElement0
+ * Signature: (Ljava/lang/StackTraceElement;)V
  */
-JNIEXPORT void JNICALL Java_java_lang_StackFrameInfo_fillInStackFrames
-  (JNIEnv *env, jclass dummy, jint startIndex,
-   jobjectArray stackFrames, jint fromIndex, jint toIndex) {
-    JVM_FillStackFrames(env, dummy, startIndex,
-                        stackFrames, fromIndex, toIndex);
+JNIEXPORT void JNICALL Java_java_lang_StackFrameInfo_toStackTraceElement0
+  (JNIEnv *env, jobject stackframeinfo, jobject stacktraceinfo) {
+     JVM_ToStackTraceElement(env, stackframeinfo, stacktraceinfo);
 }
-
-/*
- * Class:     java_lang_StackFrameInfo
- * Method:    setMethodInfo
- * Signature: (Ljava/lang/Class;)V
- */
-JNIEXPORT void JNICALL Java_java_lang_StackFrameInfo_setMethodInfo
-  (JNIEnv *env, jobject stackframeinfo) {
-     JVM_SetMethodInfo(env, stackframeinfo);
-}
--- a/jdk/src/java.base/share/native/libjava/StackStreamFactory.c	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/native/libjava/StackStreamFactory.c	Thu Apr 28 23:08:16 2016 -0700
@@ -45,7 +45,6 @@
   (JNIEnv *env, jclass dummy)
 {
    return JVM_STACKWALK_FILL_CLASS_REFS_ONLY == java_lang_StackStreamFactory_FILL_CLASS_REFS_ONLY &&
-          JVM_STACKWALK_FILTER_FILL_IN_STACK_TRACE == java_lang_StackStreamFactory_FILTER_FILL_IN_STACKTRACE &&
           JVM_STACKWALK_SHOW_HIDDEN_FRAMES == java_lang_StackStreamFactory_SHOW_HIDDEN_FRAMES &&
           JVM_STACKWALK_FILL_LIVE_STACK_FRAMES == java_lang_StackStreamFactory_FILL_LIVE_STACK_FRAMES;
 }
@@ -53,26 +52,26 @@
 /*
  * Class:     java_lang_StackStreamFactory_AbstractStackWalker
  * Method:    callStackWalk
- * Signature: (JIII[Ljava/lang/Class;[Ljava/lang/StackWalker/StackFrame;)Ljava/lang/Object;
+ * Signature: (JIII[Ljava/lang/Object;)Ljava/lang/Object;
  */
 JNIEXPORT jobject JNICALL Java_java_lang_StackStreamFactory_00024AbstractStackWalker_callStackWalk
   (JNIEnv *env, jobject stackstream, jlong mode, jint skipFrames, jint batchSize, jint startIndex,
-   jobjectArray classes, jobjectArray frames)
+   jobjectArray frames)
 {
     return JVM_CallStackWalk(env, stackstream, mode, skipFrames, batchSize,
-                             startIndex, classes, frames);
+                             startIndex, frames);
 }
 
 /*
  * Class:     java_lang_StackStreamFactory_AbstractStackWalker
  * Method:    fetchStackFrames
- * Signature: (JJII[Ljava/lang/Class;[Ljava/lang/StackWalker/StackFrame;)I
+ * Signature: (JJII[Ljava/lang/Object;)I
  */
 JNIEXPORT jint JNICALL Java_java_lang_StackStreamFactory_00024AbstractStackWalker_fetchStackFrames
   (JNIEnv *env, jobject stackstream, jlong mode, jlong anchor,
    jint batchSize, jint startIndex,
-   jobjectArray classes, jobjectArray frames)
+   jobjectArray frames)
 {
     return JVM_MoreStackWalk(env, stackstream, mode, anchor, batchSize,
-                             startIndex, classes, frames);
+                             startIndex, frames);
 }
--- a/jdk/src/java.base/share/native/libjimage/jimage.cpp	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/native/libjimage/jimage.cpp	Thu Apr 28 23:08:16 2016 -0700
@@ -207,7 +207,30 @@
         if (!(*visitor)(image, module, "9", parent, base, extension, arg)) {
             break;
         }
-
     }
 }
 
+/*
+ * JIMAGE_ResourcePath- Given an open image file, a location reference, a buffer
+ * and a maximum buffer size, copy the path of the resource into the buffer.
+ * Returns false if not a valid location reference.
+ *
+ * Ex.
+ *   JImageLocationRef location = ...
+ *   char path[JIMAGE_MAX_PATH];
+ *    (*JImageResourcePath)(image, location, path, JIMAGE_MAX_PATH);
+ */
+extern "C" bool JIMAGE_ResourcePath(JImageFile* image, JImageLocationRef locationRef,
+                                    char* path, size_t max) {
+    ImageFileReader* imageFile = (ImageFileReader*) image;
+
+    u4 offset = (u4) locationRef;
+    if (offset >= imageFile->locations_size()) {
+        return false;
+    }
+
+    ImageLocation location(imageFile->get_location_offset_data(offset));
+    imageFile->location_path(location, path, max);
+
+    return true;
+}
--- a/jdk/src/java.base/share/native/libjimage/jimage.hpp	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/share/native/libjimage/jimage.hpp	Thu Apr 28 23:08:16 2016 -0700
@@ -37,11 +37,13 @@
 typedef jlong JImageLocationRef;
 
 // Max path length limit independent of platform.  Windows max path is 1024,
-// other platforms use 4096.  The JCK fails several tests when 1024 is used.
+// other platforms use 4096.
 #define JIMAGE_MAX_PATH 4096
 
 // JImage Error Codes
 
+// Resource was not found
+#define JIMAGE_NOT_FOUND (0)
 // The image file is not prefixed with 0xCAFEDADA
 #define JIMAGE_BAD_MAGIC (-1)
 // The image file does not have a compatible (translatable) version
@@ -184,3 +186,20 @@
 
 typedef void (*JImageResourceIterator_t)(JImageFile* jimage,
         JImageResourceVisitor_t visitor, void* arg);
+
+/*
+ * JIMAGE_ResourcePath- Given an open image file, a location reference, a buffer
+ * and a maximum buffer size, copy the path of the resource into the buffer.
+ * Returns false if not a valid location reference.
+ *
+ * Ex.
+ *   JImageLocationRef location = ...
+ *   char path[JIMAGE_MAX_PATH];
+ *    (*JImageResourcePath)(image, location, path, JIMAGE_MAX_PATH);
+ */
+extern "C" bool JIMAGE_ResourcePath(JImageFile* image, JImageLocationRef locationRef,
+                                    char* path, size_t max);
+
+typedef bool (*JImage_ResourcePath_t)(JImageFile* jimage, JImageLocationRef location,
+        char* buffer, jlong size);
+
--- a/jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisFileSystem.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisFileSystem.java	Thu Apr 28 23:08:16 2016 -0700
@@ -28,7 +28,6 @@
 import java.nio.file.*;
 import java.io.IOException;
 import java.util.*;
-import java.security.AccessController;
 import sun.security.action.GetPropertyAction;
 import static sun.nio.fs.SolarisNativeDispatcher.*;
 
@@ -43,8 +42,7 @@
         super(provider, dir);
 
         // check os.version
-        String osversion = AccessController
-            .doPrivileged(new GetPropertyAction("os.version"));
+        String osversion = GetPropertyAction.getProperty("os.version");
         String[] vers = Util.split(osversion, '.');
         assert vers.length >= 2;
         int majorVersion = Integer.parseInt(vers[0]);
--- a/jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java	Thu Apr 28 23:08:16 2016 -0700
@@ -29,7 +29,6 @@
 import java.nio.file.attribute.*;
 import java.nio.file.spi.FileTypeDetector;
 import java.io.IOException;
-import java.security.AccessController;
 import sun.security.action.GetPropertyAction;
 
 /**
@@ -85,8 +84,8 @@
 
     @Override
     FileTypeDetector getFileTypeDetector() {
-        Path userMimeTypes = Paths.get(AccessController.doPrivileged(
-            new GetPropertyAction("user.home")), ".mime.types");
+        Path userMimeTypes = Paths.get(
+            GetPropertyAction.getProperty("user.home"), ".mime.types");
         Path etcMimeTypes = Paths.get("/etc/mime.types");
 
         return chain(new GioFileTypeDetector(),
--- a/jdk/src/java.base/unix/classes/java/io/UnixFileSystem.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/unix/classes/java/io/UnixFileSystem.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,7 +25,7 @@
 
 package java.io;
 
-import java.security.AccessController;
+import java.util.Properties;
 import sun.security.action.GetPropertyAction;
 
 
@@ -36,12 +36,10 @@
     private final String javaHome;
 
     public UnixFileSystem() {
-        slash = AccessController.doPrivileged(
-            new GetPropertyAction("file.separator")).charAt(0);
-        colon = AccessController.doPrivileged(
-            new GetPropertyAction("path.separator")).charAt(0);
-        javaHome = AccessController.doPrivileged(
-            new GetPropertyAction("java.home"));
+        Properties props = GetPropertyAction.getProperties();
+        slash = props.getProperty("file.separator").charAt(0);
+        colon = props.getProperty("path.separator").charAt(0);
+        javaHome = props.getProperty("java.home");
     }
 
 
--- a/jdk/src/java.base/unix/classes/java/lang/ProcessImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/unix/classes/java/lang/ProcessImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -46,8 +46,10 @@
 import java.security.PrivilegedAction;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
+import java.util.Properties;
 import jdk.internal.misc.JavaIOFileDescriptorAccess;
 import jdk.internal.misc.SharedSecrets;
+import sun.security.action.GetPropertyAction;
 
 /**
  * java.lang.Process subclass in the UNIX environment.
@@ -123,11 +125,9 @@
         }
 
         String helperPath() {
-            return AccessController.doPrivileged(
-                (PrivilegedAction<String>) () ->
-                    helperPath(System.getProperty("java.home"),
-                               System.getProperty("os.arch"))
-            );
+            Properties props = GetPropertyAction.getProperties();
+            return helperPath(props.getProperty("java.home"),
+                              props.getProperty("os.arch"));
         }
 
         LaunchMechanism launchMechanism() {
@@ -159,9 +159,7 @@
         }
 
         static Platform get() {
-            String osName = AccessController.doPrivileged(
-                (PrivilegedAction<String>) () -> System.getProperty("os.name")
-            );
+            String osName = GetPropertyAction.getProperty("os.name");
 
             if (osName.equals("Linux")) { return LINUX; }
             if (osName.contains("OS X")) { return BSD; }
--- a/jdk/src/java.base/unix/classes/java/net/DefaultDatagramSocketImplFactory.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/unix/classes/java/net/DefaultDatagramSocketImplFactory.java	Thu Apr 28 23:08:16 2016 -0700
@@ -24,7 +24,7 @@
  */
 package java.net;
 
-import java.security.AccessController;
+import sun.security.action.GetPropertyAction;
 
 /**
  * This class defines a factory for creating DatagramSocketImpls. It defaults
@@ -40,8 +40,7 @@
     static {
         String prefix = null;
         try {
-            prefix = AccessController.doPrivileged(
-                new sun.security.action.GetPropertyAction("impl.prefix", null));
+            prefix = GetPropertyAction.getProperty("impl.prefix", null);
             if (prefix != null)
                 prefixImplClass = Class.forName("java.net."+prefix+"DatagramSocketImpl");
         } catch (Exception e) {
--- a/jdk/src/java.base/unix/classes/java/net/PlainDatagramSocketImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/unix/classes/java/net/PlainDatagramSocketImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -27,9 +27,7 @@
 import java.io.IOException;
 import java.util.Set;
 import java.util.HashSet;
-import java.util.Collections;
-import jdk.net.*;
-import static sun.net.ExtendedOptionsImpl.*;
+import sun.net.ext.ExtendedSocketOptions;
 
 /*
  * On Unix systems we simply delegate to native methods.
@@ -43,8 +41,11 @@
         init();
     }
 
+    static final ExtendedSocketOptions extendedOptions =
+            ExtendedSocketOptions.getInstance();
+
     protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
-        if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
+        if (!extendedOptions.isOptionSupported(name)) {
             if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
                 super.setOption(name, value);
             } else {
@@ -55,21 +56,16 @@
                }
             }
         } else {
-            if (!flowSupported()) {
-                throw new UnsupportedOperationException("unsupported option");
-            }
             if (isClosed()) {
                 throw new SocketException("Socket closed");
             }
-            checkSetOptionPermission(name);
-            checkValueType(value, SocketFlow.class);
-            setFlowOption(getFileDescriptor(), (SocketFlow)value);
+            extendedOptions.setOption(fd, name, value);
         }
     }
 
     @SuppressWarnings("unchecked")
     protected <T> T getOption(SocketOption<T> name) throws IOException {
-        if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
+        if (!extendedOptions.isOptionSupported(name)) {
             if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
                 return super.getOption(name);
             } else {
@@ -79,31 +75,23 @@
                     throw new UnsupportedOperationException("unsupported option");
                 }
             }
-        }
-        if (!flowSupported()) {
-            throw new UnsupportedOperationException("unsupported option");
+        } else {
+            if (isClosed()) {
+                throw new SocketException("Socket closed");
+            }
+            return (T) extendedOptions.getOption(fd, name);
         }
-        if (isClosed()) {
-            throw new SocketException("Socket closed");
-        }
-        checkGetOptionPermission(name);
-        SocketFlow flow = SocketFlow.create();
-        getFlowOption(getFileDescriptor(), flow);
-        return (T)flow;
     }
 
     protected Set<SocketOption<?>> supportedOptions() {
-        HashSet<SocketOption<?>> options = new HashSet<>(
-            super.supportedOptions());
-
-        if (flowSupported()) {
-            options.add(ExtendedSocketOptions.SO_FLOW_SLA);
-        }
+        HashSet<SocketOption<?>> options = new HashSet<>(super.supportedOptions());
+        options.addAll(extendedOptions.options());
         return options;
     }
 
     protected void socketSetOption(int opt, Object val) throws SocketException {
-        if (opt == SocketOptions.SO_REUSEPORT && !supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
+        if (opt == SocketOptions.SO_REUSEPORT &&
+            !supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
             throw new UnsupportedOperationException("unsupported option");
         }
         try {
--- a/jdk/src/java.base/unix/classes/java/net/PlainSocketImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/unix/classes/java/net/PlainSocketImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -28,10 +28,7 @@
 import java.io.FileDescriptor;
 import java.util.Set;
 import java.util.HashSet;
-import java.util.Collections;
-import jdk.net.*;
-
-import static sun.net.ExtendedOptionsImpl.*;
+import sun.net.ext.ExtendedSocketOptions;
 
 /*
  * On Unix systems we simply delegate to native methods.
@@ -57,8 +54,11 @@
         this.fd = fd;
     }
 
+    static final ExtendedSocketOptions extendedOptions =
+            ExtendedSocketOptions.getInstance();
+
     protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
-        if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
+        if (!extendedOptions.isOptionSupported(name)) {
             if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
                 super.setOption(name, value);
             } else {
@@ -69,21 +69,19 @@
                 }
             }
         } else {
-            if (getSocket() == null || !flowSupported()) {
+            if (getSocket() == null) {
                 throw new UnsupportedOperationException("unsupported option");
             }
             if (isClosedOrPending()) {
                 throw new SocketException("Socket closed");
             }
-            checkSetOptionPermission(name);
-            checkValueType(value, SocketFlow.class);
-            setFlowOption(getFileDescriptor(), (SocketFlow)value);
+            extendedOptions.setOption(fd, name, value);
         }
     }
 
     @SuppressWarnings("unchecked")
     protected <T> T getOption(SocketOption<T> name) throws IOException {
-        if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
+        if (!extendedOptions.isOptionSupported(name)) {
             if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
                 return super.getOption(name);
             } else {
@@ -93,31 +91,28 @@
                     throw new UnsupportedOperationException("unsupported option");
                 }
             }
-        }
-        if (getSocket() == null || !flowSupported()) {
-            throw new UnsupportedOperationException("unsupported option");
+        } else {
+            if (getSocket() == null) {
+                throw new UnsupportedOperationException("unsupported option");
+            }
+            if (isClosedOrPending()) {
+                throw new SocketException("Socket closed");
+            }
+            return (T) extendedOptions.getOption(fd, name);
         }
-        if (isClosedOrPending()) {
-            throw new SocketException("Socket closed");
-        }
-        checkGetOptionPermission(name);
-        SocketFlow flow = SocketFlow.create();
-        getFlowOption(getFileDescriptor(), flow);
-        return (T)flow;
     }
 
     protected Set<SocketOption<?>> supportedOptions() {
-        HashSet<SocketOption<?>> options = new HashSet<>(
-            super.supportedOptions());
-
-        if (getSocket() != null && flowSupported()) {
-            options.add(ExtendedSocketOptions.SO_FLOW_SLA);
+        HashSet<SocketOption<?>> options = new HashSet<>(super.supportedOptions());
+        if (getSocket() != null) {
+            options.addAll(extendedOptions.options());
         }
         return options;
     }
 
     protected void socketSetOption(int opt, boolean b, Object val) throws SocketException {
-        if (opt == SocketOptions.SO_REUSEPORT && !supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
+        if (opt == SocketOptions.SO_REUSEPORT &&
+            !supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
             throw new UnsupportedOperationException("unsupported option");
         }
         try {
--- a/jdk/src/java.base/unix/classes/sun/net/sdp/SdpProvider.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/unix/classes/sun/net/sdp/SdpProvider.java	Thu Apr 28 23:08:16 2016 -0700
@@ -34,7 +34,6 @@
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.PrintStream;
-import java.security.AccessController;
 
 import sun.net.sdp.SdpSupport;
 import sun.security.action.GetPropertyAction;
@@ -57,8 +56,7 @@
 
     public SdpProvider() {
         // if this property is not defined then there is nothing to do.
-        String file = AccessController.doPrivileged(
-            new GetPropertyAction("com.sun.sdp.conf"));
+        String file = GetPropertyAction.getProperty("com.sun.sdp.conf");
         if (file == null) {
             this.enabled = false;
             this.rules = null;
@@ -77,8 +75,7 @@
 
         // check if debugging is enabled
         PrintStream out = null;
-        String logfile = AccessController.doPrivileged(
-            new GetPropertyAction("com.sun.sdp.debug"));
+        String logfile = GetPropertyAction.getProperty("com.sun.sdp.debug");
         if (logfile != null) {
             out = System.out;
             if (logfile.length() > 0) {
--- a/jdk/src/java.base/unix/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/unix/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java	Thu Apr 28 23:08:16 2016 -0700
@@ -39,6 +39,7 @@
 import sun.net.www.protocol.http.AuthenticationInfo;
 import sun.net.www.protocol.http.AuthScheme;
 import sun.net.www.protocol.http.HttpURLConnection;
+import sun.security.action.GetPropertyAction;
 
 /**
  * NTLMAuthentication:
@@ -73,12 +74,9 @@
         NTLMAuthenticationCallback.getNTLMAuthenticationCallback();
 
     private String hostname;
-    private static String defaultDomain; /* Domain to use if not specified by user */
-
-    static {
-        defaultDomain = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction("http.auth.ntlm.domain", ""));
-    };
+    /* Domain to use if not specified by user */
+    private static String defaultDomain =
+            GetPropertyAction.getProperty("http.auth.ntlm.domain", "");
 
     public static boolean supportsTransparentAuth () {
         return false;
@@ -143,8 +141,7 @@
         password = pw.getPassword();
         init0();
         try {
-            String version = java.security.AccessController.doPrivileged(
-                    new sun.security.action.GetPropertyAction("ntlm.version"));
+            String version = GetPropertyAction.getProperty("ntlm.version");
             client = new Client(version, hostname, username, ntdomain, password);
         } catch (NTLMException ne) {
             try {
--- a/jdk/src/java.base/unix/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/unix/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java	Thu Apr 28 23:08:16 2016 -0700
@@ -26,7 +26,6 @@
 package sun.nio.ch;
 
 import java.nio.channels.spi.AsynchronousChannelProvider;
-import java.security.AccessController;
 import sun.security.action.GetPropertyAction;
 
 /**
@@ -60,8 +59,7 @@
      * Returns the default AsynchronousChannelProvider.
      */
     public static AsynchronousChannelProvider create() {
-        String osname = AccessController
-            .doPrivileged(new GetPropertyAction("os.name"));
+        String osname = GetPropertyAction.getProperty("os.name");
         if (osname.equals("SunOS"))
             return createProvider("sun.nio.ch.SolarisAsynchronousChannelProvider");
         if (osname.equals("Linux"))
--- a/jdk/src/java.base/unix/classes/sun/nio/ch/InheritedChannel.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/unix/classes/sun/nio/ch/InheritedChannel.java	Thu Apr 28 23:08:16 2016 -0700
@@ -168,7 +168,7 @@
         Class<?> paramTypes[] = { int.class };
         Constructor<?> ctr = Reflect.lookupConstructor("java.io.FileDescriptor",
                                                        paramTypes);
-        Object args[] = { new Integer(fdVal) };
+        Object args[] = { Integer.valueOf(fdVal) };
         FileDescriptor fd = (FileDescriptor)Reflect.invoke(ctr, args);
 
 
--- a/jdk/src/java.base/unix/classes/sun/nio/ch/PollSelectorImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/unix/classes/sun/nio/ch/PollSelectorImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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,7 +29,6 @@
 import java.nio.channels.*;
 import java.nio.channels.spi.*;
 import java.util.*;
-import sun.misc.*;
 
 
 /**
--- a/jdk/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -31,7 +31,6 @@
 import java.util.concurrent.*;
 import java.io.IOException;
 import java.io.FileDescriptor;
-import java.security.AccessController;
 import sun.net.NetHooks;
 import sun.security.action.GetPropertyAction;
 
@@ -47,8 +46,8 @@
 
     private static final boolean disableSynchronousRead;
     static {
-        String propValue = AccessController.doPrivileged(
-            new GetPropertyAction("sun.nio.ch.disableSynchronousRead", "false"));
+        String propValue = GetPropertyAction
+                .getProperty("sun.nio.ch.disableSynchronousRead", "false");
         disableSynchronousRead = (propValue.length() == 0) ?
             true : Boolean.valueOf(propValue);
     }
--- a/jdk/src/java.base/unix/classes/sun/nio/fs/DefaultFileSystemProvider.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/unix/classes/sun/nio/fs/DefaultFileSystemProvider.java	Thu Apr 28 23:08:16 2016 -0700
@@ -26,7 +26,6 @@
 package sun.nio.fs;
 
 import java.nio.file.spi.FileSystemProvider;
-import java.security.AccessController;
 import sun.security.action.GetPropertyAction;
 
 /**
@@ -55,8 +54,7 @@
      * Returns the default FileSystemProvider.
      */
     public static FileSystemProvider create() {
-        String osname = AccessController
-            .doPrivileged(new GetPropertyAction("os.name"));
+        String osname = GetPropertyAction.getProperty("os.name");
         if (osname.equals("SunOS"))
             return createProvider("sun.nio.fs.SolarisFileSystemProvider");
         if (osname.equals("Linux"))
--- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java	Thu Apr 28 23:08:16 2016 -0700
@@ -31,7 +31,6 @@
 import java.io.IOException;
 import java.util.*;
 import java.util.regex.Pattern;
-import java.security.AccessController;
 import sun.security.action.GetPropertyAction;
 
 /**
@@ -57,8 +56,8 @@
         // if process-wide chdir is allowed or default directory is not the
         // process working directory then paths must be resolved against the
         // default directory.
-        String propValue = AccessController.doPrivileged(
-            new GetPropertyAction("sun.nio.fs.chdirAllowed", "false"));
+        String propValue = GetPropertyAction
+                .getProperty("sun.nio.fs.chdirAllowed", "false");
         boolean chdirAllowed = (propValue.length() == 0) ?
             true : Boolean.valueOf(propValue);
         if (chdirAllowed) {
--- a/jdk/src/java.base/unix/native/libnet/ExtendedOptionsImpl.c	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,344 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <jni.h>
-#include <string.h>
-
-#include "net_util.h"
-#include "jdk_net_SocketFlow.h"
-
-static jclass sf_status_class;          /* Status enum type */
-
-static jfieldID sf_status;
-static jfieldID sf_priority;
-static jfieldID sf_bandwidth;
-
-static jfieldID sf_fd_fdID;             /* FileDescriptor.fd */
-
-/* References to the literal enum values */
-
-static jobject sfs_NOSTATUS;
-static jobject sfs_OK;
-static jobject sfs_NOPERMISSION;
-static jobject sfs_NOTCONNECTED;
-static jobject sfs_NOTSUPPORTED;
-static jobject sfs_ALREADYCREATED;
-static jobject sfs_INPROGRESS;
-static jobject sfs_OTHER;
-
-static jobject getEnumField(JNIEnv *env, char *name);
-static void setStatus(JNIEnv *env, jobject obj, int errval);
-
-/* OS specific code is implemented in these three functions */
-
-static jboolean flowSupported0() ;
-
-/*
- * Class:     sun_net_ExtendedOptionsImpl
- * Method:    init
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_init
-  (JNIEnv *env, jclass UNUSED)
-{
-    static int initialized = 0;
-    jclass c;
-
-    /* Global class references */
-
-    if (initialized) {
-        return;
-    }
-
-    c = (*env)->FindClass(env, "jdk/net/SocketFlow$Status");
-    CHECK_NULL(c);
-    sf_status_class = (*env)->NewGlobalRef(env, c);
-    CHECK_NULL(sf_status_class);
-
-    /* int "fd" field of java.io.FileDescriptor  */
-
-    c = (*env)->FindClass(env, "java/io/FileDescriptor");
-    CHECK_NULL(c);
-    sf_fd_fdID = (*env)->GetFieldID(env, c, "fd", "I");
-    CHECK_NULL(sf_fd_fdID);
-
-
-    /* SocketFlow fields */
-
-    c = (*env)->FindClass(env, "jdk/net/SocketFlow");
-    CHECK_NULL(c);
-
-    /* status */
-
-    sf_status = (*env)->GetFieldID(env, c, "status",
-                                        "Ljdk/net/SocketFlow$Status;");
-    CHECK_NULL(sf_status);
-
-    /* priority */
-
-    sf_priority = (*env)->GetFieldID(env, c, "priority", "I");
-    CHECK_NULL(sf_priority);
-
-    /* bandwidth */
-
-    sf_bandwidth = (*env)->GetFieldID(env, c, "bandwidth", "J");
-    CHECK_NULL(sf_bandwidth);
-
-    /* Initialize the static enum values */
-
-    sfs_NOSTATUS = getEnumField(env, "NO_STATUS");
-    CHECK_NULL(sfs_NOSTATUS);
-    sfs_OK = getEnumField(env, "OK");
-    CHECK_NULL(sfs_OK);
-    sfs_NOPERMISSION = getEnumField(env, "NO_PERMISSION");
-    CHECK_NULL(sfs_NOPERMISSION);
-    sfs_NOTCONNECTED = getEnumField(env, "NOT_CONNECTED");
-    CHECK_NULL(sfs_NOTCONNECTED);
-    sfs_NOTSUPPORTED = getEnumField(env, "NOT_SUPPORTED");
-    CHECK_NULL(sfs_NOTSUPPORTED);
-    sfs_ALREADYCREATED = getEnumField(env, "ALREADY_CREATED");
-    CHECK_NULL(sfs_ALREADYCREATED);
-    sfs_INPROGRESS = getEnumField(env, "IN_PROGRESS");
-    CHECK_NULL(sfs_INPROGRESS);
-    sfs_OTHER = getEnumField(env, "OTHER");
-    CHECK_NULL(sfs_OTHER);
-    initialized = JNI_TRUE;
-}
-
-static jobject getEnumField(JNIEnv *env, char *name)
-{
-    jobject f;
-    jfieldID fID = (*env)->GetStaticFieldID(env, sf_status_class, name,
-        "Ljdk/net/SocketFlow$Status;");
-    CHECK_NULL_RETURN(fID, NULL);
-
-    f = (*env)->GetStaticObjectField(env, sf_status_class, fID);
-    CHECK_NULL_RETURN(f, NULL);
-    f  = (*env)->NewGlobalRef(env, f);
-    CHECK_NULL_RETURN(f, NULL);
-    return f;
-}
-
-/*
- * Retrieve the int file-descriptor from a public socket type object.
- * Gets impl, then the FileDescriptor from the impl, and then the fd
- * from that.
- */
-static int getFD(JNIEnv *env, jobject fileDesc) {
-    return (*env)->GetIntField(env, fileDesc, sf_fd_fdID);
-}
-
-/**
- * Sets the status field of a SocketFlow to one of the
- * canned enum values
- */
-static void setStatus (JNIEnv *env, jobject obj, int errval)
-{
-    switch (errval) {
-      case 0: /* OK */
-        (*env)->SetObjectField(env, obj, sf_status, sfs_OK);
-        break;
-      case EPERM:
-        (*env)->SetObjectField(env, obj, sf_status, sfs_NOPERMISSION);
-        break;
-      case ENOTCONN:
-        (*env)->SetObjectField(env, obj, sf_status, sfs_NOTCONNECTED);
-        break;
-      case EOPNOTSUPP:
-        (*env)->SetObjectField(env, obj, sf_status, sfs_NOTSUPPORTED);
-        break;
-      case EALREADY:
-        (*env)->SetObjectField(env, obj, sf_status, sfs_ALREADYCREATED);
-        break;
-      case EINPROGRESS:
-        (*env)->SetObjectField(env, obj, sf_status, sfs_INPROGRESS);
-        break;
-      default:
-        (*env)->SetObjectField(env, obj, sf_status, sfs_OTHER);
-        break;
-    }
-}
-
-#ifdef __solaris__
-
-/*
- * Class:     sun_net_ExtendedOptionsImpl
- * Method:    setFlowOption
- * Signature: (Ljava/io/FileDescriptor;Ljdk/net/SocketFlow;)V
- */
-JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setFlowOption
-  (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow)
-{
-    int fd = getFD(env, fileDesc);
-
-    if (fd < 0) {
-        NET_ERROR(env, JNU_JAVANETPKG "SocketException", "socket closed");
-        return;
-    } else {
-        sock_flow_props_t props;
-        jlong bandwidth;
-        int rv;
-
-        jint priority = (*env)->GetIntField(env, flow, sf_priority);
-        memset(&props, 0, sizeof(props));
-        props.sfp_version = SOCK_FLOW_PROP_VERSION1;
-
-        if (priority != jdk_net_SocketFlow_UNSET) {
-            props.sfp_mask |= SFP_PRIORITY;
-            props.sfp_priority = priority;
-        }
-        bandwidth = (*env)->GetLongField(env, flow, sf_bandwidth);
-        if (bandwidth > -1)  {
-            props.sfp_mask |= SFP_MAXBW;
-            props.sfp_maxbw = (uint64_t) bandwidth;
-        }
-        rv = setsockopt(fd, SOL_SOCKET, SO_FLOW_SLA, &props, sizeof(props));
-        if (rv < 0) {
-            if (errno == ENOPROTOOPT) {
-                JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
-                        "unsupported socket option");
-            } else if (errno == EACCES || errno == EPERM) {
-                NET_ERROR(env, JNU_JAVANETPKG "SocketException",
-                                "Permission denied");
-            } else {
-                NET_ERROR(env, JNU_JAVANETPKG "SocketException",
-                                "set option SO_FLOW_SLA failed");
-            }
-            return;
-        }
-        setStatus(env, flow, props.sfp_status);
-    }
-}
-
-/*
- * Class:     sun_net_ExtendedOptionsImpl
- * Method:    getFlowOption
- * Signature: (Ljava/io/FileDescriptor;Ljdk/net/SocketFlow;)V
- */
-JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_getFlowOption
-  (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow)
-{
-    int fd = getFD(env, fileDesc);
-
-    if (fd < 0) {
-        NET_ERROR(env, JNU_JAVANETPKG "SocketException", "socket closed");
-        return;
-    } else {
-        sock_flow_props_t props;
-        int status;
-        socklen_t sz = sizeof(props);
-
-        int rv = getsockopt(fd, SOL_SOCKET, SO_FLOW_SLA, &props, &sz);
-        if (rv < 0) {
-            if (errno == ENOPROTOOPT) {
-                JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
-                        "unsupported socket option");
-            } else if (errno == EACCES || errno == EPERM) {
-                NET_ERROR(env, JNU_JAVANETPKG "SocketException",
-                                "Permission denied");
-            } else {
-                NET_ERROR(env, JNU_JAVANETPKG "SocketException",
-                                "set option SO_FLOW_SLA failed");
-            }
-            return;
-        }
-        /* first check status to see if flow exists */
-        status = props.sfp_status;
-        setStatus(env, flow, status);
-        if (status == 0) { /* OK */
-            /* can set the other fields now */
-            if (props.sfp_mask & SFP_PRIORITY) {
-                (*env)->SetIntField(env, flow, sf_priority, props.sfp_priority);
-            }
-            if (props.sfp_mask & SFP_MAXBW) {
-                (*env)->SetLongField(env, flow, sf_bandwidth,
-                                        (jlong)props.sfp_maxbw);
-            }
-        }
-    }
-}
-
-static jboolean flowsupported;
-static jboolean flowsupported_set = JNI_FALSE;
-
-static jboolean flowSupported0()
-{
-    /* Do a simple dummy call, and try to figure out from that */
-    sock_flow_props_t props;
-    int rv, s;
-    if (flowsupported_set) {
-        return flowsupported;
-    }
-    s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
-    if (s < 0) {
-        flowsupported = JNI_FALSE;
-        flowsupported_set = JNI_TRUE;
-        return JNI_FALSE;
-    }
-    memset(&props, 0, sizeof(props));
-    props.sfp_version = SOCK_FLOW_PROP_VERSION1;
-    props.sfp_mask |= SFP_PRIORITY;
-    props.sfp_priority = SFP_PRIO_NORMAL;
-    rv = setsockopt(s, SOL_SOCKET, SO_FLOW_SLA, &props, sizeof(props));
-    if (rv != 0 && errno == ENOPROTOOPT) {
-        rv = JNI_FALSE;
-    } else {
-        rv = JNI_TRUE;
-    }
-    close(s);
-    flowsupported = rv;
-    flowsupported_set = JNI_TRUE;
-    return flowsupported;
-}
-
-#else /* __solaris__ */
-
-/* Non Solaris. Functionality is not supported. So, throw UnsupportedOpExc */
-
-JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setFlowOption
-  (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow)
-{
-    JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
-        "unsupported socket option");
-}
-
-JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_getFlowOption
-  (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow)
-{
-    JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
-        "unsupported socket option");
-}
-
-static jboolean flowSupported0()  {
-    return JNI_FALSE;
-}
-
-#endif /* __solaris__ */
-
-JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_flowSupported
-  (JNIEnv *env, jclass UNUSED)
-{
-    return flowSupported0();
-}
--- a/jdk/src/java.base/unix/native/libnet/net_util_md.h	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/unix/native/libnet/net_util_md.h	Thu Apr 28 23:08:16 2016 -0700
@@ -120,47 +120,6 @@
 
 #ifdef __solaris__
 int net_getParam(char *driver, char *param);
-
-#ifndef SO_FLOW_SLA
-#define SO_FLOW_SLA 0x1018
-
-#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
-#pragma pack(4)
 #endif
 
-/*
- * Used with the setsockopt(SO_FLOW_SLA, ...) call to set
- * per socket service level properties.
- * When the application uses per-socket API, we will enforce the properties
- * on both outbound and inbound packets.
- *
- * For now, only priority and maxbw are supported in SOCK_FLOW_PROP_VERSION1.
- */
-typedef struct sock_flow_props_s {
-        int             sfp_version;
-        uint32_t        sfp_mask;
-        int             sfp_priority;   /* flow priority */
-        uint64_t        sfp_maxbw;      /* bandwidth limit in bps */
-        int             sfp_status;     /* flow create status for getsockopt */
-} sock_flow_props_t;
-
-#define SOCK_FLOW_PROP_VERSION1 1
-
-/* bit mask values for sfp_mask */
-#define SFP_MAXBW       0x00000001      /* Flow Bandwidth Limit */
-#define SFP_PRIORITY    0x00000008      /* Flow priority */
-
-/* possible values for sfp_priority */
-#define SFP_PRIO_NORMAL 1
-#define SFP_PRIO_HIGH   2
-
-#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
-#pragma pack()
-#endif /* _LONG_LONG_ALIGNMENT */
-
-#endif /* SO_FLOW_SLA */
-#endif /* __solaris__ */
-
-JNIEXPORT jboolean JNICALL NET_IsFlowSupported();
-
 #endif /* NET_UTILS_MD_H */
--- a/jdk/src/java.base/windows/classes/java/io/WinNTFileSystem.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/windows/classes/java/io/WinNTFileSystem.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,8 +25,8 @@
 
 package java.io;
 
-import java.security.AccessController;
 import java.util.Locale;
+import java.util.Properties;
 import sun.security.action.GetPropertyAction;
 
 /**
@@ -42,10 +42,9 @@
     private final char semicolon;
 
     public WinNTFileSystem() {
-        slash = AccessController.doPrivileged(
-            new GetPropertyAction("file.separator")).charAt(0);
-        semicolon = AccessController.doPrivileged(
-            new GetPropertyAction("path.separator")).charAt(0);
+        Properties props = GetPropertyAction.getProperties();
+        slash = props.getProperty("file.separator").charAt(0);
+        semicolon = props.getProperty("path.separator").charAt(0);
         altSlash = (this.slash == '\\') ? '/' : '\\';
     }
 
--- a/jdk/src/java.base/windows/classes/java/net/DefaultDatagramSocketImplFactory.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/windows/classes/java/net/DefaultDatagramSocketImplFactory.java	Thu Apr 28 23:08:16 2016 -0700
@@ -24,8 +24,7 @@
  */
 package java.net;
 
-import java.security.AccessController;
-import java.security.PrivilegedAction;
+import java.util.Properties;
 import sun.security.action.GetPropertyAction;
 
 /**
@@ -57,12 +56,11 @@
     static {
         Class<?> prefixImplClassLocal = null;
 
+        Properties props = GetPropertyAction.getProperties();
         preferIPv4Stack = Boolean.parseBoolean(
-                AccessController.doPrivileged(
-                        new GetPropertyAction("java.net.preferIPv4Stack")));
+                props.getProperty("java.net.preferIPv4Stack"));
 
-        String exclBindProp = AccessController.doPrivileged(
-                new GetPropertyAction("sun.net.useExclusiveBind", ""));
+        String exclBindProp = props.getProperty("sun.net.useExclusiveBind", "");
         exclusiveBind = (exclBindProp.isEmpty())
                 ? true
                 : Boolean.parseBoolean(exclBindProp);
@@ -70,8 +68,7 @@
         // impl.prefix
         String prefix = null;
         try {
-            prefix = AccessController.doPrivileged(
-                new GetPropertyAction("impl.prefix", null));
+            prefix = props.getProperty("impl.prefix");
             if (prefix != null)
                 prefixImplClassLocal = Class.forName("java.net."+prefix+"DatagramSocketImpl");
         } catch (Exception e) {
--- a/jdk/src/java.base/windows/classes/java/net/DualStackPlainDatagramSocketImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/windows/classes/java/net/DualStackPlainDatagramSocketImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -220,7 +220,7 @@
             case IP_TOS :
             case SO_RCVBUF :
             case SO_SNDBUF :
-                returnValue = new Integer(value);
+                returnValue = Integer.valueOf(value);
                 break;
             default: /* shouldn't get here */
                 throw new SocketException("Option not supported");
--- a/jdk/src/java.base/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java	Thu Apr 28 23:08:16 2016 -0700
@@ -34,6 +34,7 @@
 import sun.net.www.protocol.http.AuthenticationInfo;
 import sun.net.www.protocol.http.AuthScheme;
 import sun.net.www.protocol.http.HttpURLConnection;
+import sun.security.action.GetPropertyAction;
 
 /**
  * NTLMAuthentication:
@@ -52,9 +53,8 @@
     private static String defaultDomain; /* Domain to use if not specified by user */
 
     static {
-        defaultDomain = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction("http.auth.ntlm.domain",
-                                                      "domain"));
+        defaultDomain = GetPropertyAction.getProperty("http.auth.ntlm.domain",
+                                                      "domain");
     };
 
     private void init0() {
--- a/jdk/src/java.base/windows/classes/sun/nio/ch/FileDispatcherImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/windows/classes/sun/nio/ch/FileDispatcherImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -27,9 +27,9 @@
 
 import java.io.FileDescriptor;
 import java.io.IOException;
-import java.security.PrivilegedAction;
 import jdk.internal.misc.SharedSecrets;
 import jdk.internal.misc.JavaIOFileDescriptorAccess;
+import sun.security.action.GetPropertyAction;
 
 class FileDispatcherImpl extends FileDispatcher {
 
@@ -119,13 +119,8 @@
     }
 
     static boolean isFastFileTransferRequested() {
-        String fileTransferProp = java.security.AccessController.doPrivileged(
-            new PrivilegedAction<String>() {
-                @Override
-                public String run() {
-                    return System.getProperty("jdk.nio.enableFastFileTransfer");
-                }
-            });
+        String fileTransferProp = GetPropertyAction
+                .getProperty("jdk.nio.enableFastFileTransfer");
         boolean enable;
         if ("".equals(fileTransferProp)) {
             enable = true;
--- a/jdk/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -87,13 +87,13 @@
     private static final class FdMap extends HashMap<Integer, MapEntry> {
         static final long serialVersionUID = 0L;
         private MapEntry get(int desc) {
-            return get(new Integer(desc));
+            return get(Integer.valueOf(desc));
         }
         private MapEntry put(SelectionKeyImpl ski) {
-            return put(new Integer(ski.channel.getFDVal()), new MapEntry(ski));
+            return put(Integer.valueOf(ski.channel.getFDVal()), new MapEntry(ski));
         }
         private MapEntry remove(SelectionKeyImpl ski) {
-            Integer fd = new Integer(ski.channel.getFDVal());
+            Integer fd = Integer.valueOf(ski.channel.getFDVal());
             MapEntry x = get(fd);
             if ((x != null) && (x.ski.channel == ski.channel))
                 return remove(fd);
--- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java	Thu Apr 28 23:08:16 2016 -0700
@@ -27,7 +27,6 @@
 
 import java.nio.file.attribute.*;
 import java.util.concurrent.TimeUnit;
-import java.security.AccessController;
 import jdk.internal.misc.Unsafe;
 import sun.security.action.GetPropertyAction;
 
@@ -115,8 +114,8 @@
     // indicates if accurate metadata is required (interesting on NTFS only)
     private static final boolean ensureAccurateMetadata;
     static {
-        String propValue = AccessController.doPrivileged(
-            new GetPropertyAction("sun.nio.fs.ensureAccurateMetadata", "false"));
+        String propValue = GetPropertyAction
+                .getProperty("sun.nio.fs.ensureAccurateMetadata", "false");
         ensureAccurateMetadata = (propValue.length() == 0) ?
             true : Boolean.valueOf(propValue);
     }
--- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsWatchService.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsWatchService.java	Thu Apr 28 23:08:16 2016 -0700
@@ -113,6 +113,10 @@
         // completion key (used to map I/O completion to WatchKey)
         private int completionKey;
 
+        // flag indicates that ReadDirectoryChangesW failed
+        // and overlapped I/O operation wasn't started
+        private boolean errorStartingOverlapped;
+
         WindowsWatchKey(Path dir,
                         AbstractWatchService watcher,
                         FileKey fileKey)
@@ -175,6 +179,14 @@
             return completionKey;
         }
 
+        void setErrorStartingOverlapped(boolean value) {
+            errorStartingOverlapped = value;
+        }
+
+        boolean isErrorStartingOverlapped() {
+            return errorStartingOverlapped;
+        }
+
         // Invalidate the key, assumes that resources have been released
         void invalidate() {
             ((WindowsWatchService)watcher()).poller.releaseResources(this);
@@ -182,6 +194,7 @@
             buffer = null;
             countAddress = 0;
             overlappedAddress = 0;
+            errorStartingOverlapped = false;
         }
 
         @Override
@@ -455,11 +468,13 @@
          * resources.
          */
         private void releaseResources(WindowsWatchKey key) {
-            try {
-                CancelIo(key.handle());
-                GetOverlappedResult(key.handle(), key.overlappedAddress());
-            } catch (WindowsException expected) {
-                // expected as I/O operation has been cancelled
+            if (!key.isErrorStartingOverlapped()) {
+                try {
+                    CancelIo(key.handle());
+                    GetOverlappedResult(key.handle(), key.overlappedAddress());
+                } catch (WindowsException expected) {
+                    // expected as I/O operation has been cancelled
+                }
             }
             CloseHandle(key.handle());
             closeAttachedEvent(key.overlappedAddress());
@@ -628,6 +643,7 @@
                     } catch (WindowsException x) {
                         // no choice but to cancel key
                         criticalError = true;
+                        key.setErrorStartingOverlapped(true);
                     }
                 }
                 if (criticalError) {
--- a/jdk/src/java.base/windows/native/libnet/ExtendedOptionsImpl.c	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <jni.h>
-#include <string.h>
-
-#include "net_util.h"
-
-/*
- * Class:     sun_net_ExtendedOptionsImpl
- * Method:    init
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_init
-  (JNIEnv *env, jclass UNUSED)
-{
-}
-
-/* Non Solaris. Functionality is not supported. So, throw UnsupportedOpExc */
-
-JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_setFlowOption
-  (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow)
-{
-    JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
-        "unsupported socket option");
-}
-
-JNIEXPORT void JNICALL Java_sun_net_ExtendedOptionsImpl_getFlowOption
-  (JNIEnv *env, jclass UNUSED, jobject fileDesc, jobject flow)
-{
-    JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
-        "unsupported socket option");
-}
-
-static jboolean flowSupported0()  {
-    return JNI_FALSE;
-}
-
-JNIEXPORT jboolean JNICALL Java_sun_net_ExtendedOptionsImpl_flowSupported
-  (JNIEnv *env, jclass UNUSED)
-{
-    return JNI_FALSE;
-}
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/_AppMenuBarHandler.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/_AppMenuBarHandler.java	Thu Apr 28 23:08:16 2016 -0700
@@ -83,7 +83,7 @@
 
         // if we have no foreground frames, then we have to "kick" the menubar
         final JFrame pingFrame = new JFrame();
-        pingFrame.getRootPane().putClientProperty("Window.alpha", new Float(0.0f));
+        pingFrame.getRootPane().putClientProperty("Window.alpha", Float.valueOf(0.0f));
         pingFrame.setUndecorated(true);
         pingFrame.setVisible(true);
         pingFrame.toFront();
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaComboBoxPopup.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaComboBoxPopup.java	Thu Apr 28 23:08:16 2016 -0700
@@ -58,7 +58,7 @@
         updateContents(false);
 
         // TODO: CPlatformWindow?
-        putClientProperty(CPlatformWindow.WINDOW_FADE_OUT, new Integer(150));
+        putClientProperty(CPlatformWindow.WINDOW_FADE_OUT, Integer.valueOf(150));
     }
 
     public void updateContents(final boolean remove) {
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaFileSystemModel.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaFileSystemModel.java	Thu Apr 28 23:08:16 2016 -0700
@@ -35,7 +35,6 @@
 import javax.swing.filechooser.FileSystemView;
 import javax.swing.table.AbstractTableModel;
 
-import sun.misc.ManagedLocalsThread;
 /**
  * NavServices-like implementation of a file Table
  *
@@ -393,7 +392,7 @@
             this.currentDirectory = currentDirectory;
             this.fid = fid;
             String name = "Aqua L&F File Loading Thread";
-            this.loadThread = new ManagedLocalsThread(this, name);
+            this.loadThread = new Thread(null, this, name, 0, false);
             this.loadThread.start();
         }
 
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaInternalFrameDockIconUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaInternalFrameDockIconUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,28 +40,28 @@
  * From MacDockIconUI
  *
  * A JRSUI L&F implementation of JInternalFrame.JDesktopIcon
- * @author
- * @version
  */
-public class AquaInternalFrameDockIconUI extends DesktopIconUI implements MouseListener, MouseMotionListener, ComponentListener {
-    private static final String CACHED_FRAME_ICON_KEY = "apple.laf.internal.frameIcon";
+public final class AquaInternalFrameDockIconUI extends DesktopIconUI
+        implements MouseListener, MouseMotionListener {
 
-    protected JInternalFrame.JDesktopIcon fDesktopIcon;
-    protected JInternalFrame fFrame;
-    protected ScaledImageLabel fIconPane;
-    protected DockLabel fDockLabel;
-    protected boolean fTrackingIcon = false;
+    private JInternalFrame.JDesktopIcon fDesktopIcon;
+    private JInternalFrame fFrame;
+    private ScaledImageLabel fIconPane;
+    private DockLabel fDockLabel;
+    private boolean fTrackingIcon;
 
     public static ComponentUI createUI(final JComponent c) {
         return new AquaInternalFrameDockIconUI();
     }
 
+    @Override
     public void installUI(final JComponent c) {
         fDesktopIcon = (JInternalFrame.JDesktopIcon)c;
         installComponents();
         installListeners();
     }
 
+    @Override
     public void uninstallUI(final JComponent c) {
         uninstallComponents();
         uninstallListeners();
@@ -69,55 +69,54 @@
         fFrame = null;
     }
 
-    protected void installComponents() {
+    private void installComponents() {
         fFrame = fDesktopIcon.getInternalFrame();
         fIconPane = new ScaledImageLabel();
         fDesktopIcon.setLayout(new BorderLayout());
         fDesktopIcon.add(fIconPane, BorderLayout.CENTER);
     }
 
-    protected void uninstallComponents() {
+    private void uninstallComponents() {
         fDesktopIcon.setLayout(null);
         fDesktopIcon.remove(fIconPane);
     }
 
-    protected void installListeners() {
+    private void installListeners() {
         fDesktopIcon.addMouseListener(this);
         fDesktopIcon.addMouseMotionListener(this);
-        fFrame.addComponentListener(this);
     }
 
-    protected void uninstallListeners() {
-        fFrame.removeComponentListener(this);
+    private void uninstallListeners() {
         fDesktopIcon.removeMouseMotionListener(this);
         fDesktopIcon.removeMouseListener(this);
     }
 
+    @Override
     public Dimension getMinimumSize(final JComponent c) {
         return new Dimension(32, 32);
     }
 
+    @Override
     public Dimension getMaximumSize(final JComponent c) {
         return new Dimension(128, 128);
     }
 
+    @Override
     public Dimension getPreferredSize(final JComponent c) {
         return new Dimension(64, 64); //$ Dock preferred size
     }
 
-    public Insets getInsets(final JComponent c) {
-        return new Insets(0, 0, 0, 0);
-    }
-
     void updateIcon() {
         fIconPane.updateIcon();
     }
 
+    @Override
     public void mousePressed(final MouseEvent e) {
         fTrackingIcon = fIconPane.mouseInIcon(e);
         if (fTrackingIcon) fIconPane.repaint();
     }
 
+    @Override
     public void mouseReleased(final MouseEvent e) {// only when it's actually in the image
         if (fFrame.isIconifiable() && fFrame.isIcon()) {
             if (fTrackingIcon) {
@@ -137,6 +136,7 @@
         if (fDockLabel != null && !fIconPane.getBounds().contains(e.getX(), e.getY())) fDockLabel.hide();
     }
 
+    @Override
     public void mouseEntered(final MouseEvent e) {
         if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0) return;
         String title = fFrame.getTitle();
@@ -145,41 +145,27 @@
         fDockLabel.show(fDesktopIcon);
     }
 
+    @Override
     public void mouseExited(final MouseEvent e) {
         if (fDockLabel != null && (e.getModifiers() & InputEvent.BUTTON1_MASK) == 0) fDockLabel.hide();
     }
 
+    @Override
     public void mouseClicked(final MouseEvent e) { }
 
+    @Override
     public void mouseDragged(final MouseEvent e) { }
 
+    @Override
     public void mouseMoved(final MouseEvent e) { }
 
-    public void componentHidden(final ComponentEvent e) { }
-
-    public void componentMoved(final ComponentEvent e) { }
-
-    public void componentResized(final ComponentEvent e) {
-        fFrame.putClientProperty(CACHED_FRAME_ICON_KEY, null);
-    }
-
-    public void componentShown(final ComponentEvent e) {
-        fFrame.putClientProperty(CACHED_FRAME_ICON_KEY, null);
-    }
-
     @SuppressWarnings("serial") // Superclass is not serializable across versions
-    class ScaledImageLabel extends JLabel {
+    private final class ScaledImageLabel extends JLabel {
         ScaledImageLabel() {
             super(null, null, CENTER);
         }
 
         void updateIcon() {
-            final Object priorIcon = fFrame.getClientProperty(CACHED_FRAME_ICON_KEY);
-            if (priorIcon instanceof ImageIcon) {
-                setIcon((ImageIcon)priorIcon);
-                return;
-            }
-
             int width = fFrame.getWidth();
             int height = fFrame.getHeight();
 
@@ -196,11 +182,10 @@
 
             final float scale = (float)fDesktopIcon.getWidth() / (float)Math.max(width, height) * 0.89f;
             // Sending in -1 for width xor height causes it to maintain aspect ratio
-            final ImageIcon icon = new ImageIcon(fImage.getScaledInstance((int)(width * scale), -1, Image.SCALE_SMOOTH));
-            fFrame.putClientProperty(CACHED_FRAME_ICON_KEY, icon);
-            setIcon(icon);
+            setIcon(new ImageIcon(fImage.getScaledInstance((int)(width * scale), -1, Image.SCALE_SMOOTH)));
         }
 
+        @Override
         public void paint(final Graphics g) {
             if (getIcon() == null) updateIcon();
 
@@ -222,13 +207,14 @@
             return getBounds().contains(e.getX(), e.getY());
         }
 
+        @Override
         public Dimension getPreferredSize() {
             return new Dimension(64, 64); //$ Dock preferred size
         }
     }
 
     @SuppressWarnings("serial") // Superclass is not serializable across versions
-    class DockLabel extends JLabel {
+    private static final class DockLabel extends JLabel {
         static final int NUB_HEIGHT = 7;
         static final int ROUND_ADDITIONAL_HEIGHT = 8;
         static final int ROUND_ADDITIONAL_WIDTH = 12;
@@ -243,6 +229,7 @@
             setSize(SwingUtilities.computeStringWidth(metrics, getText()) + ROUND_ADDITIONAL_WIDTH * 2, metrics.getAscent() + NUB_HEIGHT + ROUND_ADDITIONAL_HEIGHT);
         }
 
+        @Override
         public void paint(final Graphics g) {
             final int width = getWidth();
             final int height = getHeight();
@@ -303,6 +290,7 @@
             }
         }
 
+        @Override
         @Deprecated
         public void hide() {
             final Container parent = getParent();
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaInternalFramePaneUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaInternalFramePaneUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -91,7 +91,7 @@
     JComponent getDock() {
         if (fDock == null) {
             fDock = new Dock(desktop);
-            desktop.add(fDock, new Integer(399)); // Just below the DRAG_LAYER
+            desktop.add(fDock, Integer.valueOf(399)); // Just below the DRAG_LAYER
         }
         return fDock;
     }
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaLookAndFeel.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaLookAndFeel.java	Thu Apr 28 23:08:16 2016 -0700
@@ -416,7 +416,7 @@
             "Button.select", selected,
             "Button.border",(LazyValue) t -> AquaButtonBorder.getDynamicButtonBorder(),
             "Button.font", controlFont,
-            "Button.textIconGap", new Integer(4),
+            "Button.textIconGap", Integer.valueOf(4),
             "Button.textShiftOffset", zero, // radar 3308129 - aqua doesn't move images when pressed.
             "Button.focusInputMap", controlFocusInputMap,
             "Button.margin", new InsetsUIResource(0, 2, 0, 2),
@@ -635,8 +635,8 @@
             //"Menu.checkIcon", emptyCheckIcon, // A non-drawing GlyphIcon to make the spacing consistent
             "Menu.arrowIcon",(LazyValue) t -> AquaImageFactory.getMenuArrowIcon(),
             "Menu.consumesTabs", Boolean.TRUE,
-            "Menu.menuPopupOffsetY", new Integer(1),
-            "Menu.submenuPopupOffsetY", new Integer(-4),
+            "Menu.menuPopupOffsetY", Integer.valueOf(1),
+            "Menu.submenuPopupOffsetY", Integer.valueOf(-4),
 
             "MenuBar.font", menuFont,
             "MenuBar.background", menuBackgroundColor, // not a menu item, not selected
@@ -694,7 +694,7 @@
             "OptionPane.informationSound", null, // Info and Plain
             "OptionPane.questionSound", null,
             "OptionPane.warningSound", null,
-            "OptionPane.buttonClickThreshhold", new Integer(500),
+            "OptionPane.buttonClickThreshhold", Integer.valueOf(500),
             "OptionPane.yesButtonMnemonic", "",
             "OptionPane.noButtonMnemonic", "",
             "OptionPane.okButtonMnemonic", "",
@@ -717,7 +717,7 @@
             "PasswordField.caretBlinkRate", textCaretBlinkRate,
             "PasswordField.border", textFieldBorder,
             "PasswordField.margin", zeroInsets,
-            "PasswordField.echoChar", new Character((char)0x25CF),
+            "PasswordField.echoChar", Character.valueOf((char)0x25CF),
             "PasswordField.capsLockIconColor", textPasswordFieldCapsLockIconColor,
 
             "PopupMenu.font", menuFont,
@@ -736,7 +736,7 @@
             "ProgressBar.selectionForeground", black,
             "ProgressBar.selectionBackground", white,
             "ProgressBar.border", new BorderUIResource(BorderFactory.createEmptyBorder()),
-            "ProgressBar.repaintInterval", new Integer(20),
+            "ProgressBar.repaintInterval", Integer.valueOf(20),
 
             "RadioButton.background", controlBackgroundColor,
             "RadioButton.foreground", black,
@@ -772,7 +772,7 @@
             "ScrollBar.border", null,
             "ScrollBar.focusInputMap", aquaKeyBindings.getScrollBarInputMap(),
             "ScrollBar.focusInputMap.RightToLeft", aquaKeyBindings.getScrollBarRightToLeftInputMap(),
-            "ScrollBar.width", new Integer(16),
+            "ScrollBar.width", Integer.valueOf(16),
             "ScrollBar.background", white,
             "ScrollBar.foreground", black,
 
@@ -816,7 +816,7 @@
             //"SplitPane.shadow", table.get("controlShadow"),
             "SplitPane.background", panelBackgroundColor,
             "SplitPane.border", scollListBorder,
-            "SplitPane.dividerSize", new Integer(9), //$
+            "SplitPane.dividerSize", Integer.valueOf(9), //$
             "SplitPaneDivider.border", null, // AquaSplitPaneDividerUI draws it
             "SplitPaneDivider.horizontalGradientVariant",(LazyValue) t -> AquaSplitPaneDividerUI.getHorizontalSplitDividerGradientVariant(),
 
@@ -833,7 +833,7 @@
             //"TabbedPane.darkShadow", table.get("controlDkShadow"),
             //"TabbedPane.focus", table.get("controlText"),
             "TabbedPane.opaque", useOpaqueComponents,
-            "TabbedPane.textIconGap", new Integer(4),
+            "TabbedPane.textIconGap", Integer.valueOf(4),
             "TabbedPane.tabInsets", new InsetsUIResource(0, 10, 3, 10), // Label within tab (top, left, bottom, right)
             //"TabbedPane.rightTabInsets", new InsetsUIResource(0, 10, 3, 10), // Label within tab (top, left, bottom, right)
             "TabbedPane.leftTabInsets", new InsetsUIResource(0, 10, 3, 10), // Label within tab
@@ -973,9 +973,9 @@
             "Tree.selectionBorderColor", selectionBackground, // match the background so it looks like we don't draw anything
             "Tree.editorBorderSelectionColor", null, // The EditTextFrame provides its own border
             // "Tree.editorBorder", textFieldBorder, // If you still have Sun bug 4376328 in DefaultTreeCellEditor, it has to have the same insets as TextField.border
-            "Tree.leftChildIndent", new Integer(7),//$
-            "Tree.rightChildIndent", new Integer(13),//$
-            "Tree.rowHeight", new Integer(19),// iconHeight + 3, to match finder - a zero would have the renderer decide, except that leaves the icons touching
+            "Tree.leftChildIndent", Integer.valueOf(7),//$
+            "Tree.rightChildIndent", Integer.valueOf(13),//$
+            "Tree.rowHeight", Integer.valueOf(19),// iconHeight + 3, to match finder - a zero would have the renderer decide, except that leaves the icons touching
             "Tree.scrollsOnExpand", Boolean.FALSE,
             "Tree.openIcon",(LazyValue) t -> AquaImageFactory.getTreeOpenFolderIcon(), // Open folder icon
             "Tree.closedIcon",(LazyValue) t -> AquaImageFactory.getTreeFolderIcon(), // Closed folder icon
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaTabbedPaneCopyFromBasicUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaTabbedPaneCopyFromBasicUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -521,7 +521,7 @@
         }
         // [2165820] Mac OS X change: mnemonics need to be triggered with ctrl-option, not just option.
         mnemonicInputMap.put(KeyStroke.getKeyStroke(mnemonic, Event.ALT_MASK | Event.CTRL_MASK), "setSelectedIndex");
-        mnemonicToIndexMap.put(new Integer(mnemonic), new Integer(index));
+        mnemonicToIndexMap.put(Integer.valueOf(mnemonic), Integer.valueOf(index));
     }
 
     /**
@@ -2084,7 +2084,7 @@
                     if (mnemonic >= 'a' && mnemonic <= 'z') {
                         mnemonic -= ('a' - 'A');
                     }
-                    final Integer index = ui.mnemonicToIndexMap.get(new Integer(mnemonic));
+                    final Integer index = ui.mnemonicToIndexMap.get(Integer.valueOf(mnemonic));
                     if (index != null && pane.isEnabledAt(index.intValue())) {
                         pane.setSelectedIndex(index.intValue());
                     }
@@ -2183,50 +2183,21 @@
         }
 
         protected int preferredTabAreaHeight(final int tabPlacement, final int width) {
-            final FontMetrics metrics = getFontMetrics();
             final int tabCount = tabPane.getTabCount();
             int total = 0;
             if (tabCount > 0) {
-                int rows = 1;
-                int x = 0;
-
                 final int maxTabHeight = calculateMaxTabHeight(tabPlacement);
-
-                for (int i = 0; i < tabCount; i++) {
-                    final int tabWidth = calculateTabWidth(tabPlacement, i, metrics);
-
-                    if (x != 0 && x + tabWidth > width) {
-                        rows++;
-                        x = 0;
-                    }
-                    x += tabWidth;
-                }
-                total = calculateTabAreaHeight(tabPlacement, rows, maxTabHeight);
+                total = calculateTabAreaHeight(tabPlacement, 1, maxTabHeight);
             }
             return total;
         }
 
         protected int preferredTabAreaWidth(final int tabPlacement, final int height) {
-            final FontMetrics metrics = getFontMetrics();
             final int tabCount = tabPane.getTabCount();
             int total = 0;
             if (tabCount > 0) {
-                int columns = 1;
-                int y = 0;
-                final int fontHeight = metrics.getHeight();
-
                 maxTabWidth = calculateMaxTabWidth(tabPlacement);
-
-                for (int i = 0; i < tabCount; i++) {
-                    final int tabHeight = calculateTabHeight(tabPlacement, i, fontHeight);
-
-                    if (y != 0 && y + tabHeight > height) {
-                        columns++;
-                        y = 0;
-                    }
-                    y += tabHeight;
-                }
-                total = calculateTabAreaWidth(tabPlacement, columns, maxTabWidth);
+                total = calculateTabAreaWidth(tabPlacement, 1, maxTabWidth);
             }
             return total;
         }
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaUtilControlSize.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaUtilControlSize.java	Thu Apr 28 23:08:16 2016 -0700
@@ -268,7 +268,7 @@
 
         public SizeVariant alterFontSize(final float newSize) {
             final float oldSize = fontSize == null ? 0.0f : fontSize.floatValue();
-            fontSize = new Float(newSize + oldSize);
+            fontSize = newSize + oldSize;
             return this;
         }
 
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/ScreenPopupFactory.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/ScreenPopupFactory.java	Thu Apr 28 23:08:16 2016 -0700
@@ -32,8 +32,8 @@
 import sun.swing.SwingAccessor;
 
 class ScreenPopupFactory extends PopupFactory {
-    static final Float TRANSLUCENT = new Float(248f/255f);
-    static final Float OPAQUE = new Float(1.0f);
+    static final Float TRANSLUCENT = 248f/255f;
+    static final Float OPAQUE = 1.0f;
 
     boolean fIsActive = true;
 
--- a/jdk/src/java.desktop/macosx/classes/sun/font/CFontManager.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/font/CFontManager.java	Thu Apr 28 23:08:16 2016 -0700
@@ -42,7 +42,6 @@
 import sun.awt.HeadlessToolkit;
 import sun.awt.util.ThreadGroupUtils;
 import sun.lwawt.macosx.*;
-import sun.misc.ManagedLocalsThread;
 
 public final class CFontManager extends SunFontManager {
     private static Hashtable<String, Font2D> genericFonts = new Hashtable<String, Font2D>();
--- a/jdk/src/java.desktop/macosx/classes/sun/font/CStrike.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/font/CStrike.java	Thu Apr 28 23:08:16 2016 -0700
@@ -386,7 +386,7 @@
             if (generalCache == null) {
                 return 0L;
             }
-            final Long value = generalCache.get(new Integer(index));
+            final Long value = generalCache.get(Integer.valueOf(index));
             if (value == null) {
                 return 0L;
             }
@@ -415,7 +415,7 @@
                 generalCache = new HashMap<Integer, Long>();
             }
 
-            generalCache.put(new Integer(index), Long.valueOf(value));
+            generalCache.put(Integer.valueOf(index), Long.valueOf(value));
         }
 
         public synchronized void dispose() {
@@ -526,7 +526,7 @@
             }
 
             if (generalCache == null) return 0;
-            final Float value = generalCache.get(new Integer(index));
+            final Float value = generalCache.get(Integer.valueOf(index));
             if (value == null) return 0;
             return value.floatValue();
         }
@@ -553,7 +553,7 @@
                 generalCache = new HashMap<Integer, Float>();
             }
 
-            generalCache.put(new Integer(index), new Float(value));
+            generalCache.put(Integer.valueOf(index), Float.valueOf(value));
         }
 
         private static class SparseBitShiftingTwoLayerArray {
--- a/jdk/src/java.desktop/macosx/classes/sun/java2d/IntegerNIORaster.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/java2d/IntegerNIORaster.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,7 +40,7 @@
                                                ") cannot be <= 0");
         }
         // This is cribbed from java.awt.image.Raster.
-        DataBuffer db = new DataBufferNIOInt(w * h);
+        DataBufferNIOInt db = new DataBufferNIOInt(w * h);
         if (location == null) {
             location = new Point(0, 0);
         }
@@ -48,13 +48,11 @@
         return new IntegerNIORaster(sppsm, db, location);
     }
 
-    public IntegerNIORaster(SampleModel sampleModel, DataBuffer dataBuffer, Point origin) {
+    public IntegerNIORaster(SampleModel sampleModel, DataBufferNIOInt dataBuffer, Point origin) {
         // This is all cribbed from sun.awt.image.IntegerInterleavedRaster & sun.awt.image.IntegerComponentRaster
         super(sampleModel, dataBuffer, new Rectangle(origin.x, origin.y, sampleModel.getWidth(), sampleModel.getHeight()), origin, null);
-        if (!(dataBuffer instanceof DataBufferNIOInt)) {
-           throw new RasterFormatException("IntegerNIORasters must have DataBufferNIOInt DataBuffers");
-        }
-        this.data = ((DataBufferNIOInt)dataBuffer).getBuffer();
+
+        this.data = dataBuffer.getBuffer();
     }
 
     public WritableRaster createCompatibleWritableRaster() {
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWComponentPeer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWComponentPeer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -903,7 +903,7 @@
     @Override
     public boolean requestFocus(Component lightweightChild, boolean temporary,
                                 boolean focusedWindowChangeAllowed, long time,
-                                CausedFocusEvent.Cause cause)
+                                FocusEvent.Cause cause)
     {
         if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
             focusLog.finest("lightweightChild=" + lightweightChild + ", temporary=" + temporary +
@@ -1278,7 +1278,7 @@
         assert (e.getSource() == target);
 
         if (!target.isFocusOwner() && LWKeyboardFocusManagerPeer.shouldFocusOnClick(target)) {
-            LWKeyboardFocusManagerPeer.requestFocusFor(target, CausedFocusEvent.Cause.MOUSE_EVENT);
+            LWKeyboardFocusManagerPeer.requestFocusFor(target, FocusEvent.Cause.MOUSE_EVENT);
         }
     }
 
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWLightweightFramePeer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWLightweightFramePeer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, 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 java.awt.Rectangle;
 import java.awt.Window;
 import java.awt.dnd.DropTarget;
+import java.awt.event.FocusEvent;
 
-import sun.awt.CausedFocusEvent;
 import sun.awt.LightweightFrame;
 import sun.swing.JLightweightFrame;
 import sun.swing.SwingAccessor;
@@ -60,7 +60,7 @@
     }
 
     @Override
-    public boolean requestWindowFocus(CausedFocusEvent.Cause cause) {
+    public boolean requestWindowFocus(FocusEvent.Cause cause) {
         if (!focusAllowedFor()) {
             return false;
         }
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java	Thu Apr 28 23:08:16 2016 -0700
@@ -35,7 +35,6 @@
 import java.util.*;
 
 import sun.awt.*;
-import sun.misc.ManagedLocalsThread;
 import sun.print.*;
 import sun.awt.util.ThreadGroupUtils;
 
@@ -77,13 +76,14 @@
                 shutdown();
                 waitForRunState(STATE_CLEANUP);
             };
-            Thread shutdown = new ManagedLocalsThread(
-                    ThreadGroupUtils.getRootThreadGroup(), shutdownRunnable);
+            Thread shutdown = new Thread(
+                    ThreadGroupUtils.getRootThreadGroup(), shutdownRunnable,
+                    "AWT-Shutdown", 0, false);
             shutdown.setContextClassLoader(null);
             Runtime.getRuntime().addShutdownHook(shutdown);
             String name = "AWT-LW";
-            Thread toolkitThread = new ManagedLocalsThread(
-                    ThreadGroupUtils.getRootThreadGroup(), this, name);
+            Thread toolkitThread = new Thread(
+                   ThreadGroupUtils.getRootThreadGroup(), this, name, 0, false);
             toolkitThread.setDaemon(true);
             toolkitThread.setPriority(Thread.NORM_PRIORITY + 1);
             toolkitThread.start();
@@ -404,6 +404,10 @@
     public final PrintJob getPrintJob(Frame frame, String doctitle,
                                       JobAttributes jobAttributes,
                                       PageAttributes pageAttributes) {
+        if (frame == null) {
+            throw new NullPointerException("frame must not be null");
+        }
+
         if (GraphicsEnvironment.isHeadless()) {
             throw new IllegalArgumentException();
         }
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWWindowPeer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWWindowPeer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -256,14 +256,14 @@
                 if (!getTarget().isAutoRequestFocus()) {
                     return;
                 } else {
-                    requestWindowFocus(CausedFocusEvent.Cause.ACTIVATION);
+                    requestWindowFocus(FocusEvent.Cause.ACTIVATION);
                 }
             // Focus the owner in case this window is focused.
             } else if (kfmPeer.getCurrentFocusedWindow() == getTarget()) {
                 // Transfer focus to the owner.
                 LWWindowPeer owner = getOwnerFrameDialog(LWWindowPeer.this);
                 if (owner != null) {
-                    owner.requestWindowFocus(CausedFocusEvent.Cause.ACTIVATION);
+                    owner.requestWindowFocus(FocusEvent.Cause.ACTIVATION);
                 }
             }
         }
@@ -295,7 +295,7 @@
         if (f == null) {
             f = DEFAULT_FONT;
         }
-        return platformWindow.transformGraphics(new SunGraphics2D(getSurfaceData(), fg, bg, f));
+        return new SunGraphics2D(getSurfaceData(), fg, bg, f);
     }
 
     @Override
@@ -848,7 +848,7 @@
                 // 2. An active but not focused owner frame/dialog is clicked.
                 // The mouse event then will trigger a focus request "in window" to the component, so the window
                 // should gain focus before.
-                requestWindowFocus(CausedFocusEvent.Cause.MOUSE_EVENT);
+                requestWindowFocus(FocusEvent.Cause.MOUSE_EVENT);
 
                 mouseDownTarget[targetIdx] = targetPeer;
             } else if (id == MouseEvent.MOUSE_DRAGGED) {
@@ -1199,7 +1199,7 @@
      * Requests platform to set native focus on a frame/dialog.
      * In case of a simple window, triggers appropriate java focus change.
      */
-    public boolean requestWindowFocus(CausedFocusEvent.Cause cause) {
+    public boolean requestWindowFocus(FocusEvent.Cause cause) {
         if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
             focusLog.fine("requesting native focus to " + this);
         }
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/PlatformWindow.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/PlatformWindow.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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,8 @@
 package sun.lwawt;
 
 import java.awt.*;
+import java.awt.event.FocusEvent;
 
-import sun.awt.CausedFocusEvent;
 import sun.java2d.SurfaceData;
 
 // TODO Is it worth to generify this interface, like that:
@@ -114,7 +114,7 @@
 
     public void updateFocusableWindowState();
 
-    public boolean rejectFocusRequest(CausedFocusEvent.Cause cause);
+    public boolean rejectFocusRequest(FocusEvent.Cause cause);
 
     public boolean requestWindowFocus();
 
@@ -130,12 +130,6 @@
      */
     public void setSizeConstraints(int minW, int minH, int maxW, int maxH);
 
-    /**
-     * Transforms the given Graphics object according to the native
-     * implementation traits (insets, etc.).
-     */
-    public Graphics transformGraphics(Graphics g);
-
     /*
      * Installs the images for particular window.
      */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/AccessibilityEventMonitor.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.lwawt.macosx;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleState;
+import javax.accessibility.AccessibleStateSet;
+import javax.swing.event.EventListenerList;
+
+/**
+ * <P>{@code AccessibilityEventMonitor} implements a PropertyChange listener
+ * on every UI object that implements interface {@code Accessible} in the Java
+ * Virtual Machine.  The events captured by these listeners are made available
+ * through listeners supported by {@code AccessibilityEventMonitor}.
+ * With this, all the individual events on each of the UI object
+ * instances are funneled into one set of PropertyChange listeners.
+ *
+ * This code is a subset of com.sun.java.accessibility.util.AccessibilityEventMonitor
+ * which resides in module jdk.accessibility.  Due to modularization the code in
+ * this package, java.desktop, can not be dependent on code in jdk.accessibility.
+ */
+
+class AccessibilityEventMonitor {
+
+    /**
+     * The current list of registered {@link java.beans.PropertyChangeListener
+     * PropertyChangeListener} classes.
+     *
+     * @see #addPropertyChangeListener
+     */
+    private static final EventListenerList listenerList =
+        new EventListenerList();
+
+
+    /**
+     * The actual listener that is installed on the component instances.
+     * This listener calls the other registered listeners when an event
+     * occurs.  By doing things this way, the actual number of listeners
+     * installed on a component instance is drastically reduced.
+     */
+    private static final AccessibilityEventListener accessibilityListener =
+        new AccessibilityEventListener();
+
+    /**
+     * Adds the specified listener to receive all PropertyChange events on
+     * each UI object instance in the Java Virtual Machine as they occur.
+     * <P>Note: This listener is automatically added to all component
+     * instances created after this method is called.  In addition, it
+     * is only added to UI object instances that support this listener type.
+     *
+     * @param l the listener to add
+     * @param a  the Accessible object to add the PropertyChangeListener to
+     */
+
+    static void addPropertyChangeListener(PropertyChangeListener l, Accessible a) {
+        if (listenerList.getListenerCount(PropertyChangeListener.class) == 0) {
+            accessibilityListener.installListeners(a);
+        }
+        listenerList.add(PropertyChangeListener.class, l);
+    }
+
+    /**
+     * AccessibilityEventListener is the class that does all the work for
+     * AccessibilityEventMonitor.  It is not intended for use by any other
+     * class except AccessibilityEventMonitor.
+     */
+
+    private static class AccessibilityEventListener implements PropertyChangeListener {
+
+        /**
+         * Installs PropertyChange listeners to the Accessible object, and its
+         * children (so long as the object isn't of TRANSIENT state).
+         *
+         * @param a the Accessible object to add listeners to
+         */
+        private void installListeners(Accessible a) {
+            installListeners(a.getAccessibleContext());
+        }
+
+        /**
+         * Installs PropertyChange listeners to the AccessibleContext object,
+         * and its * children (so long as the object isn't of TRANSIENT state).
+         *
+         * @param ac the AccessibleContext to add listeners to
+         */
+        private void installListeners(AccessibleContext ac) {
+
+            if (ac != null) {
+                AccessibleStateSet states = ac.getAccessibleStateSet();
+                if (!states.contains(AccessibleState.TRANSIENT)) {
+                    ac.addPropertyChangeListener(this);
+                    /*
+                     * Don't add listeners to transient children. Components
+                     * with transient children should return an AccessibleStateSet
+                     * containing AccessibleState.MANAGES_DESCENDANTS. Components
+                     * may not explicitly return the MANAGES_DESCENDANTS state.
+                     * In this case, don't add listeners to the children of
+                     * lists, tables and trees.
+                     */
+                    AccessibleStateSet set = ac.getAccessibleStateSet();
+                    if (set.contains(AccessibleState.MANAGES_DESCENDANTS)) {
+                        return;
+                    }
+                    AccessibleRole role = ac.getAccessibleRole();
+                    if ( role == AccessibleRole.LIST ||
+                         role == AccessibleRole.TREE ) {
+                        return;
+                    }
+                    if (role == AccessibleRole.TABLE) {
+                        // handle Oracle tables containing tables
+                        Accessible child = ac.getAccessibleChild(0);
+                        if (child != null) {
+                            AccessibleContext ac2 = child.getAccessibleContext();
+                            if (ac2 != null) {
+                                role = ac2.getAccessibleRole();
+                                if (role != null && role != AccessibleRole.TABLE) {
+                                    return;
+                                }
+                            }
+                        }
+                    }
+                    int count = ac.getAccessibleChildrenCount();
+                    for (int i = 0; i < count; i++) {
+                        Accessible child = ac.getAccessibleChild(i);
+                        if (child != null) {
+                            installListeners(child);
+                        }
+                    }
+                }
+            }
+        }
+
+        /**
+         * Removes PropertyChange listeners for the given Accessible object,
+         * its children (so long as the object isn't of TRANSIENT state).
+         *
+         * @param a the Accessible object to remove listeners from
+         */
+        private void removeListeners(Accessible a) {
+            removeListeners(a.getAccessibleContext());
+        }
+
+        /**
+         * Removes PropertyChange listeners for the given AccessibleContext
+         * object, its children (so long as the object isn't of TRANSIENT
+         * state).
+         *
+         * @param a the Accessible object to remove listeners from
+         */
+        private void removeListeners(AccessibleContext ac) {
+
+            if (ac != null) {
+                // Listeners are not added to transient components.
+                AccessibleStateSet states = ac.getAccessibleStateSet();
+                if (!states.contains(AccessibleState.TRANSIENT)) {
+                    ac.removePropertyChangeListener(this);
+                    /*
+                     * Listeners are not added to transient children. Components
+                     * with transient children should return an AccessibleStateSet
+                     * containing AccessibleState.MANAGES_DESCENDANTS. Components
+                     * may not explicitly return the MANAGES_DESCENDANTS state.
+                     * In this case, don't remove listeners from the children of
+                     * lists, tables and trees.
+                     */
+                    if (states.contains(AccessibleState.MANAGES_DESCENDANTS)) {
+                        return;
+                    }
+                    AccessibleRole role = ac.getAccessibleRole();
+                    if ( role == AccessibleRole.LIST ||
+                         role == AccessibleRole.TABLE ||
+                         role == AccessibleRole.TREE ) {
+                        return;
+                    }
+                    int count = ac.getAccessibleChildrenCount();
+                    for (int i = 0; i < count; i++) {
+                        Accessible child = ac.getAccessibleChild(i);
+                        if (child != null) {
+                            removeListeners(child);
+                        }
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void propertyChange(PropertyChangeEvent e) {
+            // propogate the event
+            Object[] listeners =
+                AccessibilityEventMonitor.listenerList.getListenerList();
+            for (int i = listeners.length-2; i>=0; i-=2) {
+                if (listeners[i]==PropertyChangeListener.class) {
+                    ((PropertyChangeListener)listeners[i+1]).propertyChange(e);
+                }
+            }
+
+            // handle childbirth/death
+            String name = e.getPropertyName();
+            if (name.compareTo(AccessibleContext.ACCESSIBLE_CHILD_PROPERTY) == 0) {
+                Object oldValue = e.getOldValue();
+                Object newValue = e.getNewValue();
+
+                if ((oldValue == null) ^ (newValue == null)) { // one null, not both
+                    if (oldValue != null) {
+                        // this Accessible is a child that's going away
+                        if (oldValue instanceof Accessible) {
+                            Accessible a = (Accessible) oldValue;
+                            removeListeners(a.getAccessibleContext());
+                        } else if (oldValue instanceof AccessibleContext) {
+                            removeListeners((AccessibleContext) oldValue);
+                        }
+                    } else if (newValue != null) {
+                        // this Accessible is a child was just born
+                        if (newValue instanceof Accessible) {
+                            Accessible a = (Accessible) newValue;
+                            installListeners(a.getAccessibleContext());
+                        } else if (newValue instanceof AccessibleContext) {
+                            installListeners((AccessibleContext) newValue);
+                        }
+                    }
+                } else {
+                    System.out.println("ERROR in usage of PropertyChangeEvents for: " + e.toString());
+                }
+            }
+        }
+    }
+}
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessible.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessible.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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,20 +26,18 @@
 package sun.lwawt.macosx;
 
 import java.awt.Component;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
 import java.lang.reflect.Field;
 
 import javax.accessibility.Accessible;
 import javax.accessibility.AccessibleContext;
 import javax.swing.JProgressBar;
 import javax.swing.JSlider;
-import javax.swing.event.CaretEvent;
-import javax.swing.event.CaretListener;
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.ChangeListener;
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.DocumentListener;
-import javax.swing.text.JTextComponent;
 
+import sun.lwawt.macosx.CFRetainedResource;
 
 class CAccessible extends CFRetainedResource implements Accessible {
     static Field getNativeAXResourceField() {
@@ -99,13 +97,10 @@
         return accessible.getAccessibleContext();
     }
 
-    // currently only supports text components
     public void addNotificationListeners(Component c) {
-        if (c instanceof JTextComponent) {
-            JTextComponent tc = (JTextComponent) c;
-            AXTextChangeNotifier listener = new AXTextChangeNotifier();
-            tc.getDocument().addDocumentListener(listener);
-            tc.addCaretListener(listener);
+        AXTextChangeNotifier listener = new AXTextChangeNotifier();
+        if (c instanceof Accessible) {
+            AccessibilityEventMonitor.addPropertyChangeListener(listener, (Accessible)c);
         }
         if (c instanceof JProgressBar) {
             JProgressBar pb = (JProgressBar) c;
@@ -117,29 +112,23 @@
     }
 
 
-    private class AXTextChangeNotifier implements DocumentListener, CaretListener {
-        @Override
-        public void changedUpdate(DocumentEvent e) {
-            if (ptr != 0) valueChanged(ptr);
-        }
+    private class AXTextChangeNotifier implements PropertyChangeListener {
 
         @Override
-        public void insertUpdate(DocumentEvent e) {
-            if (ptr != 0) valueChanged(ptr);
-        }
-
-        @Override
-        public void removeUpdate(DocumentEvent e) {
-            if (ptr != 0) valueChanged(ptr);
-        }
-
-        @Override
-        public void caretUpdate(CaretEvent e) {
-            if (ptr != 0) selectionChanged(ptr);
+        public void propertyChange(PropertyChangeEvent e) {
+            String name = e.getPropertyName();
+            if ( ptr != 0 ) {
+                if (name.compareTo(AccessibleContext.ACCESSIBLE_CARET_PROPERTY) == 0) {
+                    selectionChanged(ptr);
+                } else if (name.compareTo(AccessibleContext.ACCESSIBLE_TEXT_PROPERTY) == 0 ) {
+                    valueChanged(ptr);
+                }
+            }
         }
     }
 
     private class AXProgressChangeNotifier implements ChangeListener {
+        @Override
         public void stateChanged(ChangeEvent e) {
             if (ptr != 0) valueChanged(ptr);
         }
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -44,7 +44,6 @@
 import sun.lwawt.LWComponentPeer;
 import sun.lwawt.LWWindowPeer;
 import sun.lwawt.PlatformWindow;
-import sun.misc.ManagedLocalsThread;
 
 
 public final class CDragSourceContextPeer extends SunDragSourceContextPeer {
@@ -181,7 +180,7 @@
                     }
                 }
             };
-            new ManagedLocalsThread(dragRunnable).start();
+            new Thread(null, dragRunnable, "Drag", 0, false).start();
         } catch (Exception e) {
             final long nativeDragSource = getNativeContext();
             setNativeContext(0);
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFileDialog.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFileDialog.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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 @@
 package sun.lwawt.macosx;
 
 import java.awt.*;
+import java.awt.event.FocusEvent.Cause;
 import java.awt.peer.*;
 import java.awt.BufferCapabilities.FlipContents;
 import java.awt.event.*;
@@ -34,10 +35,8 @@
 import java.util.List;
 import java.io.*;
 
-import sun.awt.CausedFocusEvent.Cause;
 import sun.awt.AWTAccessor;
 import sun.java2d.pipe.Region;
-import sun.misc.ManagedLocalsThread;
 import sun.security.action.GetBooleanAction;
 
 class CFileDialog implements FileDialogPeer {
@@ -120,7 +119,7 @@
         if (visible) {
             // Java2 Dialog class requires peer to run code in a separate thread
             // and handles keeping the call modal
-            new ManagedLocalsThread(new Task()).start();
+            new Thread(null, new Task(), "FileDialog", 0, false).start();
         }
         // We hide ourself before "show" returns - setVisible(false)
         // doesn't apply
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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,11 +26,11 @@
 package sun.lwawt.macosx;
 
 import java.awt.*;
-import sun.awt.CausedFocusEvent;
+import java.awt.event.FocusEvent;
+
 import sun.java2d.SurfaceData;
 import sun.java2d.opengl.CGLLayer;
 import sun.lwawt.LWWindowPeer;
-import sun.lwawt.LWWindowPeer.PeerType;
 import sun.lwawt.PlatformWindow;
 import sun.util.logging.PlatformLogger;
 
@@ -39,7 +39,8 @@
  */
 public class CPlatformEmbeddedFrame implements PlatformWindow {
 
-    private static final PlatformLogger focusLogger = PlatformLogger.getLogger("sun.lwawt.macosx.focus.CPlatformEmbeddedFrame");
+    private static final PlatformLogger focusLogger = PlatformLogger.getLogger(
+            "sun.lwawt.macosx.focus.CPlatformEmbeddedFrame");
 
     private CGLLayer windowLayer;
     private LWWindowPeer peer;
@@ -133,9 +134,9 @@
     public void updateFocusableWindowState() {}
 
     @Override
-    public boolean rejectFocusRequest(CausedFocusEvent.Cause cause) {
+    public boolean rejectFocusRequest(FocusEvent.Cause cause) {
         // Cross-app activation requests are not allowed.
-        if (cause != CausedFocusEvent.Cause.MOUSE_EVENT &&
+        if (cause != FocusEvent.Cause.MOUSE_EVENT &&
             !target.isParentWindowActive())
         {
             focusLogger.fine("the embedder is inactive, so the request is rejected");
@@ -161,11 +162,6 @@
     public void setSizeConstraints(int minW, int minH, int maxW, int maxH) {}
 
     @Override
-    public Graphics transformGraphics(Graphics g) {
-        return g;
-    }
-
-    @Override
     public void updateIconImages() {}
 
     @Override
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformLWWindow.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformLWWindow.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,6 @@
 
 import java.awt.Font;
 import java.awt.FontMetrics;
-import java.awt.Graphics;
 import java.awt.GraphicsDevice;
 import java.awt.GraphicsEnvironment;
 import java.awt.Insets;
@@ -37,7 +36,7 @@
 import java.awt.Window;
 import sun.awt.CGraphicsDevice;
 import sun.awt.CGraphicsEnvironment;
-import sun.awt.CausedFocusEvent;
+import java.awt.event.FocusEvent;
 import sun.awt.LightweightFrame;
 import sun.java2d.SurfaceData;
 import sun.lwawt.LWLightweightFramePeer;
@@ -134,7 +133,7 @@
     }
 
     @Override
-    public boolean rejectFocusRequest(CausedFocusEvent.Cause cause) {
+    public boolean rejectFocusRequest(FocusEvent.Cause cause) {
         return false;
     }
 
@@ -153,11 +152,6 @@
     }
 
     @Override
-    public Graphics transformGraphics(Graphics g) {
-        return null;
-    }
-
-    @Override
     public void setAlwaysOnTop(boolean isAlwaysOnTop) {
     }
 
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -706,9 +706,9 @@
     }
 
     @Override
-    public boolean rejectFocusRequest(CausedFocusEvent.Cause cause) {
+    public boolean rejectFocusRequest(FocusEvent.Cause cause) {
         // Cross-app activation requests are not allowed.
-        if (cause != CausedFocusEvent.Cause.MOUSE_EVENT &&
+        if (cause != FocusEvent.Cause.MOUSE_EVENT &&
             !((LWCToolkit)Toolkit.getDefaultToolkit()).isApplicationActive())
         {
             focusLogger.fine("the app is inactive, so the request is rejected");
@@ -741,12 +741,6 @@
     }
 
     @Override
-    public Graphics transformGraphics(Graphics g) {
-        // is this where we can inject a transform for HiDPI?
-        return g;
-    }
-
-    @Override
     public void setAlwaysOnTop(boolean isAlwaysOnTop) {
         setStyleBits(ALWAYS_ON_TOP, isAlwaysOnTop);
     }
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterDialogPeer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterDialogPeer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -29,7 +29,6 @@
 import java.awt.dnd.*;
 
 import sun.lwawt.*;
-import sun.misc.ManagedLocalsThread;
 
 public class CPrinterDialogPeer extends LWWindowPeer {
     static {
@@ -59,7 +58,7 @@
                 printerDialog.setRetVal(printerDialog.showDialog());
                 printerDialog.setVisible(false);
             };
-            new ManagedLocalsThread(task).start();
+            new Thread(null, task, "PrintDialog", 0, false).start();
         }
     }
 
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java	Thu Apr 28 23:08:16 2016 -0700
@@ -36,6 +36,7 @@
 import javax.print.*;
 import javax.print.attribute.PrintRequestAttributeSet;
 import javax.print.attribute.HashPrintRequestAttributeSet;
+import javax.print.attribute.standard.Copies;
 import javax.print.attribute.standard.Media;
 import javax.print.attribute.standard.MediaPrintableArea;
 import javax.print.attribute.standard.MediaSize;
@@ -43,7 +44,6 @@
 import javax.print.attribute.standard.PageRanges;
 
 import sun.java2d.*;
-import sun.misc.ManagedLocalsThread;
 import sun.print.*;
 
 public final class CPrinterJob extends RasterPrinterJob {
@@ -194,10 +194,37 @@
                 // setPageRange will set firstPage and lastPage as called in getFirstPage
                 // and getLastPage
                 setPageRange(range[0][0] - 1, range[0][1] - 1);
+            } else {
+                // if rangeSelect is SunPageSelection.ALL
+                // then setPageRange appropriately
+                setPageRange(-1, -1);
             }
         }
     }
 
+    private void setPageRangeAttribute(int from, int to, boolean isRangeSet) {
+        if (attributes != null) {
+            // since native Print use zero-based page indices,
+            // we need to store in 1-based format in attributes set
+            // but setPageRange again uses zero-based indices so it should be
+            // 1 less than pageRanges attribute
+            if (isRangeSet) {
+                attributes.add(new PageRanges(from+1, to+1));
+                attributes.add(SunPageSelection.RANGE);
+                setPageRange(from, to);
+            } else {
+                attributes.add(SunPageSelection.ALL);
+            }
+        }
+    }
+
+    private void setCopiesAttribute(int copies) {
+        if (attributes != null) {
+            attributes.add(new Copies(copies));
+            super.setCopies(copies);
+        }
+    }
+
     volatile boolean onEventThread;
 
     @Override
@@ -691,9 +718,15 @@
                 if (pageFormat != null) {
                     Printable printable = pageable.getPrintable(pageIndex);
                     if (printable != null) {
-                        BufferedImage bimg = new BufferedImage((int)Math.round(pageFormat.getWidth()), (int)Math.round(pageFormat.getHeight()), BufferedImage.TYPE_INT_ARGB_PRE);
-                        PeekGraphics peekGraphics = createPeekGraphics(bimg.createGraphics(), printerJob);
-                        Rectangle2D pageFormatArea = getPageFormatArea(pageFormat);
+                        BufferedImage bimg =
+                              new BufferedImage(
+                                  (int)Math.round(pageFormat.getWidth()),
+                                  (int)Math.round(pageFormat.getHeight()),
+                                  BufferedImage.TYPE_INT_ARGB_PRE);
+                        PeekGraphics peekGraphics =
+                         createPeekGraphics(bimg.createGraphics(), printerJob);
+                        Rectangle2D pageFormatArea =
+                             getPageFormatArea(pageFormat);
                         initPrinterGraphics(peekGraphics, pageFormatArea);
 
                         // Do the assignment here!
@@ -741,7 +774,8 @@
 
     // upcall from native
     private static void detachPrintLoop(final long target, final long arg) {
-        new ManagedLocalsThread(() -> _safePrintLoop(target, arg)).start();
+        new Thread(null, () -> _safePrintLoop(target, arg),
+                   "PrintLoop", 0, false).start();
     }
     private static native void _safePrintLoop(long target, long arg);
 
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CTrayIcon.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CTrayIcon.java	Thu Apr 28 23:08:16 2016 -0700
@@ -98,15 +98,26 @@
     private native long nativeCreate();
 
     //invocation from the AWTTrayIcon.m
-    public long getPopupMenuModel(){
-        if(popup == null) {
-            PopupMenu popupMenu = target.getPopupMenu();
-            if (popupMenu != null) {
-                popup = popupMenu;
+    public long getPopupMenuModel() {
+        PopupMenu newPopup = target.getPopupMenu();
+
+        if (popup == newPopup) {
+            if (popup == null) {
+                return 0L;
+            }
+        } else {
+            if (newPopup != null) {
+                if (popup != null) {
+                    popup.removeNotify();
+                    popup = newPopup;
+                } else {
+                    popup = newPopup;
+                }
             } else {
                 return 0L;
             }
         }
+
         return checkAndCreatePopupPeer().getModel();
     }
 
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CViewEmbeddedFrame.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CViewEmbeddedFrame.java	Thu Apr 28 23:08:16 2016 -0700
@@ -87,23 +87,22 @@
         }
     }
 
-    /*
+    /**
      * Initializes the embedded frame bounds and validates a component.
-     * Designed to be called from the main thread
-     * This method should be called once from the initialization of the SWT_AWT Bridge
+     * Designed to be called from the main thread. This method should be called
+     * once from the initialization of the SWT_AWT Bridge.
      */
-    public void validateWithBounds(final int x, final int y, final int width, final int height) {
+    public void validateWithBounds(final int x, final int y, final int width,
+                                   final int height) {
         try {
-            final LWWindowPeer peer = AWTAccessor.getComponentAccessor()
-                                                 .getPeer(this);
-            LWCToolkit.invokeAndWait(new Runnable() {
-                @Override
-                public void run() {
-                    peer.setBoundsPrivate(0, 0, width, height);
-                    validate();
-                    setVisible(true);
-                }
+            LWCToolkit.invokeAndWait(() -> {
+                final LWWindowPeer peer = AWTAccessor.getComponentAccessor()
+                                                     .getPeer(this);
+                peer.setBoundsPrivate(0, 0, width, height);
+                validate();
+                setVisible(true);
             }, this);
-        } catch (InvocationTargetException ex) {}
+        } catch (InvocationTargetException ex) {
+        }
     }
 }
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CViewPlatformEmbeddedFrame.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CViewPlatformEmbeddedFrame.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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,13 +27,12 @@
 
 import java.awt.Font;
 import java.awt.FontMetrics;
-import java.awt.Graphics;
 import java.awt.GraphicsDevice;
 import java.awt.Insets;
 import java.awt.MenuBar;
 import java.awt.Point;
 import java.awt.Window;
-import sun.awt.CausedFocusEvent.Cause;
+import java.awt.event.FocusEvent.Cause;
 import sun.java2d.SurfaceData;
 import sun.lwawt.LWWindowPeer;
 import sun.lwawt.PlatformWindow;
@@ -171,11 +170,6 @@
     }
 
     @Override
-    public Graphics transformGraphics(Graphics g) {
-        return g;
-    }
-
-    @Override
     public void updateIconImages() {
     }
 
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CWarningWindow.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CWarningWindow.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, 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
@@ -364,8 +364,8 @@
             return null;
         }
 
-        return transformGraphics(new SunGraphics2D(sd, SystemColor.windowText,
-                SystemColor.window, ownerWindow.getFont()));
+        return new SunGraphics2D(sd, SystemColor.windowText, SystemColor.window,
+                                 ownerWindow.getFont());
     }
 
 
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java	Thu Apr 28 23:08:16 2016 -0700
@@ -378,9 +378,9 @@
 
         // These DnD properties must be set, otherwise Swing ends up spewing NPEs
         // all over the place. The values came straight off of MToolkit.
-        desktopProperties.put("DnD.Autoscroll.initialDelay", new Integer(50));
-        desktopProperties.put("DnD.Autoscroll.interval", new Integer(50));
-        desktopProperties.put("DnD.Autoscroll.cursorHysteresis", new Integer(5));
+        desktopProperties.put("DnD.Autoscroll.initialDelay", Integer.valueOf(50));
+        desktopProperties.put("DnD.Autoscroll.interval", Integer.valueOf(50));
+        desktopProperties.put("DnD.Autoscroll.cursorHysteresis", Integer.valueOf(5));
 
         desktopProperties.put("DnD.isDragImageSupported", Boolean.TRUE);
 
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CPrinterJob.m	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CPrinterJob.m	Thu Apr 28 23:08:16 2016 -0700
@@ -312,9 +312,9 @@
 static void nsPrintInfoToJavaPrinterJob(JNIEnv* env, NSPrintInfo* src, jobject dstPrinterJob, jobject dstPageable)
 {
     static JNF_MEMBER_CACHE(jm_setService, sjc_CPrinterJob, "setPrinterServiceFromNative", "(Ljava/lang/String;)V");
-    static JNF_MEMBER_CACHE(jm_setCopies, sjc_CPrinterJob, "setCopies", "(I)V");
+    static JNF_MEMBER_CACHE(jm_setCopiesAttribute, sjc_CPrinterJob, "setCopiesAttribute", "(I)V");
     static JNF_MEMBER_CACHE(jm_setCollated, sjc_CPrinterJob, "setCollated", "(Z)V");
-    static JNF_MEMBER_CACHE(jm_setPageRange, sjc_CPrinterJob, "setPageRange", "(II)V");
+    static JNF_MEMBER_CACHE(jm_setPageRangeAttribute, sjc_CPrinterJob, "setPageRangeAttribute", "(IIZ)V");
 
     // get the selected printer's name, and set the appropriate PrintService on the Java side
     NSString *name = [[src printer] name];
@@ -327,7 +327,7 @@
     NSNumber* nsCopies = [printingDictionary objectForKey:NSPrintCopies];
     if ([nsCopies respondsToSelector:@selector(integerValue)])
     {
-        JNFCallVoidMethod(env, dstPrinterJob, jm_setCopies, [nsCopies integerValue]); // AWT_THREADING Safe (known object)
+        JNFCallVoidMethod(env, dstPrinterJob, jm_setCopiesAttribute, [nsCopies integerValue]); // AWT_THREADING Safe (known object)
     }
 
     NSNumber* nsCollated = [printingDictionary objectForKey:NSPrintMustCollate];
@@ -340,6 +340,7 @@
     if ([nsPrintAllPages respondsToSelector:@selector(boolValue)])
     {
         jint jFirstPage = 0, jLastPage = java_awt_print_Pageable_UNKNOWN_NUMBER_OF_PAGES;
+        jboolean isRangeSet = false;
         if (![nsPrintAllPages boolValue])
         {
             NSNumber* nsFirstPage = [printingDictionary objectForKey:NSPrintFirstPage];
@@ -353,9 +354,12 @@
             {
                 jLastPage = [nsLastPage integerValue] - 1;
             }
-        }
+            isRangeSet = true;
+        } 
+        JNFCallVoidMethod(env, dstPrinterJob, jm_setPageRangeAttribute, 
+                          jFirstPage, jLastPage, isRangeSet); 
+            // AWT_THREADING Safe (known object)
 
-        JNFCallVoidMethod(env, dstPrinterJob, jm_setPageRange, jFirstPage, jLastPage); // AWT_THREADING Safe (known object)
     }
 }
 
@@ -368,6 +372,8 @@
     static JNF_MEMBER_CACHE(jm_isCollated, sjc_CPrinterJob, "isCollated", "()Z");
     static JNF_MEMBER_CACHE(jm_getFromPage, sjc_CPrinterJob, "getFromPageAttrib", "()I");
     static JNF_MEMBER_CACHE(jm_getToPage, sjc_CPrinterJob, "getToPageAttrib", "()I");
+    static JNF_MEMBER_CACHE(jm_getMinPage, sjc_CPrinterJob, "getMinPageAttrib", "()I");
+    static JNF_MEMBER_CACHE(jm_getMaxPage, sjc_CPrinterJob, "getMaxPageAttrib", "()I");
     static JNF_MEMBER_CACHE(jm_getSelectAttrib, sjc_CPrinterJob, "getSelectAttrib", "()I");
     static JNF_MEMBER_CACHE(jm_getNumberOfPages, jc_Pageable, "getNumberOfPages", "()I");
     static JNF_MEMBER_CACHE(jm_getPageFormat, sjc_CPrinterJob, "getPageFormatFromAttributes", "()Ljava/awt/print/PageFormat;");
@@ -379,31 +385,33 @@
 
     jboolean collated = JNFCallBooleanMethod(env, srcPrinterJob, jm_isCollated); // AWT_THREADING Safe (known object)
     [printingDictionary setObject:[NSNumber numberWithBool:collated ? YES : NO] forKey:NSPrintMustCollate];
-    jint jNumPages = JNFCallIntMethod(env, srcPageable, jm_getNumberOfPages); // AWT_THREADING Safe (!appKit)
-    if (jNumPages != java_awt_print_Pageable_UNKNOWN_NUMBER_OF_PAGES)
-    {
-        jint selectID = JNFCallIntMethod(env, srcPrinterJob, jm_getSelectAttrib);
-        if (selectID ==0) {
-            [printingDictionary setObject:[NSNumber numberWithBool:YES] forKey:NSPrintAllPages];
-        } else if (selectID == 2) {
-            // In Mac 10.7,  Print ALL is deselected if PrintSelection is YES whether
-            // NSPrintAllPages is YES or NO
-            [printingDictionary setObject:[NSNumber numberWithBool:NO] forKey:NSPrintAllPages];
-            [printingDictionary setObject:[NSNumber numberWithBool:YES] forKey:NSPrintSelectionOnly];
-        } else {
+    jint selectID = JNFCallIntMethod(env, srcPrinterJob, jm_getSelectAttrib);
+    jint fromPage = JNFCallIntMethod(env, srcPrinterJob, jm_getFromPage);
+    jint toPage = JNFCallIntMethod(env, srcPrinterJob, jm_getToPage);
+    if (selectID ==0) {
+        [printingDictionary setObject:[NSNumber numberWithBool:YES] forKey:NSPrintAllPages];
+    } else if (selectID == 2) {
+        // In Mac 10.7,  Print ALL is deselected if PrintSelection is YES whether
+        // NSPrintAllPages is YES or NO
+        [printingDictionary setObject:[NSNumber numberWithBool:NO] forKey:NSPrintAllPages];
+        [printingDictionary setObject:[NSNumber numberWithBool:YES] forKey:NSPrintSelectionOnly];
+    } else {
+        jint minPage = JNFCallIntMethod(env, srcPrinterJob, jm_getMinPage);
+        jint maxPage = JNFCallIntMethod(env, srcPrinterJob, jm_getMaxPage);
+
+        // for PD_SELECTION or PD_NOSELECTION, check from/to page
+        // to determine which radio button to select
+        if (fromPage > minPage || toPage < maxPage) {
             [printingDictionary setObject:[NSNumber numberWithBool:NO] forKey:NSPrintAllPages];
+        } else {
+            [printingDictionary setObject:[NSNumber numberWithBool:YES] forKey:NSPrintAllPages];
         }
+    }
 
-        jint fromPage = JNFCallIntMethod(env, srcPrinterJob, jm_getFromPage);
-        jint toPage = JNFCallIntMethod(env, srcPrinterJob, jm_getToPage);
-        // setting fromPage and toPage will not be shown in the dialog if printing All pages
-        [printingDictionary setObject:[NSNumber numberWithInteger:fromPage] forKey:NSPrintFirstPage];
-        [printingDictionary setObject:[NSNumber numberWithInteger:toPage] forKey:NSPrintLastPage];
-    }
-    else
-    {
-        [printingDictionary setObject:[NSNumber numberWithBool:YES] forKey:NSPrintAllPages];
-    }
+    // setting fromPage and toPage will not be shown in the dialog if printing All pages
+    [printingDictionary setObject:[NSNumber numberWithInteger:fromPage] forKey:NSPrintFirstPage];
+    [printingDictionary setObject:[NSNumber numberWithInteger:toPage] forKey:NSPrintLastPage];
+
     jobject page = JNFCallObjectMethod(env, srcPrinterJob, jm_getPageFormat); 
     if (page != NULL) {
         javaPageFormatToNSPrintInfo(env, NULL, page, dst);
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CTrayIcon.m	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CTrayIcon.m	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,18 +39,21 @@
  * If the image of the specified size won't fit into the status bar,
  * then scale it down proprtionally. Otherwise, leave it as is.
  */
-static NSSize ScaledImageSizeForStatusBar(NSSize imageSize) {
+static NSSize ScaledImageSizeForStatusBar(NSSize imageSize, BOOL autosize) {
     NSRect imageRect = NSMakeRect(0.0, 0.0, imageSize.width, imageSize.height);
 
     // There is a black line at the bottom of the status bar
     // that we don't want to cover with image pixels.
-    CGFloat desiredHeight = [[NSStatusBar systemStatusBar] thickness] - 1.0;
-    CGFloat scaleFactor = MIN(1.0, desiredHeight/imageSize.height);
-
-    imageRect.size.width *= scaleFactor;
-    imageRect.size.height *= scaleFactor;
+    CGFloat desiredSize = [[NSStatusBar systemStatusBar] thickness] - 1.0;
+    if (autosize) {
+        imageRect.size.width = desiredSize;
+        imageRect.size.height = desiredSize;
+    } else {
+        CGFloat scaleFactor = MIN(1.0, desiredSize/imageSize.height);
+        imageRect.size.width *= scaleFactor;
+        imageRect.size.height *= scaleFactor;
+    }
     imageRect = NSIntegralRect(imageRect);
-
     return imageRect.size;
 }
 
@@ -101,9 +104,9 @@
     return peer;
 }
 
-- (void) setImage:(NSImage *) imagePtr sizing:(BOOL)autosize{
+- (void) setImage:(NSImage *) imagePtr sizing:(BOOL)autosize {
     NSSize imageSize = [imagePtr size];
-    NSSize scaledSize = ScaledImageSizeForStatusBar(imageSize);
+    NSSize scaledSize = ScaledImageSizeForStatusBar(imageSize, autosize);
     if (imageSize.width != scaledSize.width ||
         imageSize.height != scaledSize.height) {
         [imagePtr setSize: scaledSize];
--- a/jdk/src/java.desktop/share/classes/com/sun/beans/decoder/NewElementHandler.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/com/sun/beans/decoder/NewElementHandler.java	Thu Apr 28 23:08:16 2016 -0700
@@ -42,7 +42,7 @@
  * &lt;new class="java.lang.Long"&gt;
  *     &lt;string&gt;10&lt;/string&gt;
  * &lt;/new&gt;</pre>
- * is equivalent to {@code new Long("10")} in Java code.
+ * is equivalent to {@code Long.valueOf("10")} in Java code.
  * <p>The following attributes are supported:
  * <dl>
  * <dt>class
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPMetadata.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPMetadata.java	Thu Apr 28 23:08:16 2016 -0700
@@ -128,7 +128,7 @@
         addChildNode(root, "BMPVersion", bmpVersion);
         addChildNode(root, "Width", width);
         addChildNode(root, "Height", height);
-        addChildNode(root, "BitsPerPixel", new Short(bitsPerPixel));
+        addChildNode(root, "BitsPerPixel", Short.valueOf(bitsPerPixel));
         addChildNode(root, "Compression", compression);
         addChildNode(root, "ImageSize", imageSize);
 
@@ -172,12 +172,12 @@
                 red = palette[j++] & 0xff;
                 green = palette[j++] & 0xff;
                 blue = palette[j++] & 0xff;
-                addChildNode(entry, "Red", new Byte((byte)red));
-                addChildNode(entry, "Green", new Byte((byte)green));
-                addChildNode(entry, "Blue", new Byte((byte)blue));
+                addChildNode(entry, "Red", Byte.valueOf((byte)red));
+                addChildNode(entry, "Green", Byte.valueOf((byte)green));
+                addChildNode(entry, "Blue", Byte.valueOf((byte)blue));
                 if (numComps == 4)
                     addChildNode(entry, "Alpha",
-                                 new Byte((byte)(palette[j++] & 0xff)));
+                                 Byte.valueOf((byte)(palette[j++] & 0xff)));
             }
         }
 
@@ -284,9 +284,9 @@
 
     private void addXYZPoints(IIOMetadataNode root, String name, double x, double y, double z) {
         IIOMetadataNode node = addChildNode(root, name, null);
-        addChildNode(node, "X", new Double(x));
-        addChildNode(node, "Y", new Double(y));
-        addChildNode(node, "Z", new Double(z));
+        addChildNode(node, "X", Double.valueOf(x));
+        addChildNode(node, "Y", Double.valueOf(y));
+        addChildNode(node, "Z", Double.valueOf(z));
     }
 
     private IIOMetadataNode addChildNode(IIOMetadataNode root,
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/stream/StreamCloser.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/stream/StreamCloser.java	Thu Apr 28 23:08:16 2016 -0700
@@ -26,7 +26,6 @@
 package com.sun.imageio.stream;
 
 import sun.awt.util.ThreadGroupUtils;
-import sun.misc.ManagedLocalsThread;
 
 import java.io.IOException;
 import java.security.AccessController;
@@ -92,8 +91,8 @@
                      * Make its parent the top-level thread group.
                      */
                     ThreadGroup tg = ThreadGroupUtils.getRootThreadGroup();
-                    streamCloser = new ManagedLocalsThread(tg,
-                                                           streamCloserRunnable);
+                    streamCloser = new Thread(tg, streamCloserRunnable,
+                                              "StreamCloser", 0, false);
                     /* Set context class loader to null in order to avoid
                      * keeping a strong reference to an application classloader.
                      */
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKEngine.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKEngine.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -158,8 +158,8 @@
             int widgetType, int state, int shadowType, String detail,
             int x, int y, int width, int height, int synthState, int dir);
     private native void native_paint_slider(
-            int widgetType, int state, int shadowType, String detail,
-            int x, int y, int width, int height, int orientation);
+            int widgetType, int state, int shadowType, String detail, int x,
+            int y, int width, int height, int orientation, boolean hasFocus);
     private native void native_paint_vline(
             int widgetType, int state, String detail,
             int x, int y, int width, int height);
@@ -491,6 +491,14 @@
         int gtkState =
             GTKLookAndFeel.synthStateToGTKStateType(state).ordinal();
         int synthState = context.getComponentState();
+        Container parent = context.getComponent().getParent();
+        if(GTKLookAndFeel.is3()) {
+            if (parent != null && parent.getParent() instanceof JComboBox) {
+                if (parent.getParent().hasFocus()) {
+                    synthState |= SynthConstants.FOCUSED;
+                }
+            }
+        }
         int dir = getTextDirection(context);
         int widget = getWidgetType(context.getComponent(), id).ordinal();
         native_paint_shadow(widget, gtkState, shadowType.ordinal(), detail,
@@ -498,13 +506,13 @@
     }
 
     public void paintSlider(Graphics g, SynthContext context,
-            Region id, int state, ShadowType shadowType, String detail,
-            int x, int y, int w, int h, Orientation orientation) {
+            Region id, int state, ShadowType shadowType, String detail, int x,
+            int y, int w, int h, Orientation orientation, boolean hasFocus) {
 
         state = GTKLookAndFeel.synthStateToGTKStateType(state).ordinal();
         int widget = getWidgetType(context.getComponent(), id).ordinal();
         native_paint_slider(widget, state, shadowType.ordinal(), detail,
-                            x - x0, y - y0, w, h, orientation.ordinal());
+                         x - x0, y - y0, w, h, orientation.ordinal(), hasFocus);
     }
 
     public void paintVline(Graphics g, SynthContext context,
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, 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
@@ -54,7 +54,8 @@
  */
 @SuppressWarnings("serial") // Superclass not serializable
 public class GTKLookAndFeel extends SynthLookAndFeel {
-    private static final boolean IS_22;
+    private static boolean IS_22;
+    private static boolean IS_3;
 
     /**
      * Whether or not text is drawn antialiased.  This keys off the
@@ -107,17 +108,6 @@
     private static String gtkThemeName = "Default";
 
     static {
-        // Backup for specifying the version, this isn't currently documented.
-        // If you pass in anything but 2.2 you got the 2.0 colors/look.
-        String version = AccessController.doPrivileged(
-               new GetPropertyAction("swing.gtk.version"));
-        if (version != null) {
-            IS_22 = version.equals("2.2");
-        }
-        else {
-            IS_22 = true;
-        }
-
         String language = Locale.getDefault().getLanguage();
         boolean cjkLocale =
             (Locale.CHINESE.getLanguage().equals(language) ||
@@ -158,6 +148,10 @@
         return IS_22;
     }
 
+    static boolean is3() {
+        return IS_3;
+    }
+
     /**
      * Maps a swing constant to a GTK constant.
      */
@@ -385,7 +379,7 @@
         }
         Insets zeroInsets = new InsetsUIResource(0, 0, 0, 0);
 
-        Double defaultCaretAspectRatio = new Double(0.025);
+        Double defaultCaretAspectRatio = Double.valueOf(0.025);
         Color caretColor = table.getColor("caretColor");
         Color controlText = table.getColor("controlText");
 
@@ -1460,6 +1454,19 @@
             throw new InternalError("Unable to load native GTK libraries");
         }
 
+        if (UNIXToolkit.getGtkVersion() == UNIXToolkit.GtkVersions.GTK2) {
+            String version = AccessController.doPrivileged(
+                    new GetPropertyAction("jdk.gtk.version"));
+            if (version != null) {
+                IS_22 = version.equals("2.2");
+            } else {
+                IS_22 = true;
+            }
+        } else if (UNIXToolkit.getGtkVersion() ==
+                                UNIXToolkit.GtkVersions.GTK3) {
+            IS_3 = true;
+        }
+
         super.initialize();
         inInitialize = true;
         loadStyles();
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, 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
@@ -576,12 +576,11 @@
                     ShadowType.OUT, "menu", x, y, w, h);
 
             GTKStyle style = (GTKStyle)context.getStyle();
-            int xThickness = style.getXThickness();
-            int yThickness = style.getYThickness();
+            Insets insets = style.getInsets(context, null);
             ENGINE.paintBackground(g, context, id, gtkState,
-                    style.getGTKColor(context, gtkState, GTKColorType.BACKGROUND),
-                    x + xThickness, y + yThickness,
-                    w - xThickness - xThickness, h - yThickness - yThickness);
+                style.getGTKColor(context, gtkState, GTKColorType.BACKGROUND),
+                x + insets.left, y + insets.top, w - insets.left - insets.right,
+                h - insets.top - insets.bottom);
             ENGINE.finishPainting();
         }
     }
@@ -640,6 +639,34 @@
         int state = context.getComponentState();
         JComponent c = context.getComponent();
 
+        GTKStyle style = (GTKStyle) context.getStyle();
+        String detail;
+        // wide-separators are painted using box not line
+        if (style.getClassSpecificBoolValue(context,
+                                          "wide-separators", false)) {
+            Insets insets = c.getInsets();
+            x += insets.left;
+            y += insets.top;
+            if (orientation == JSeparator.HORIZONTAL) {
+                w -= (insets.left + insets.right);
+                detail = "hseparator";
+            } else {
+                h -= (insets.top + insets.bottom);
+                detail = "vseparator";
+            }
+            synchronized (UNIXToolkit.GTK_LOCK) {
+                if (! ENGINE.paintCachedImage(g, x, y, w, h, id, state,
+                            detail, orientation)) {
+                    ENGINE.startPainting(g, x, y, w, h, id, state,
+                            detail, orientation);
+                    ENGINE.paintBox(g, context, id, state,
+                            ShadowType.ETCHED_OUT, detail, x, y, w, h);
+                    ENGINE.finishPainting();
+                }
+            }
+            return;
+        }
+
         /*
          * Note: In theory, the style's x/y thickness values would determine
          * the width of the separator content.  In practice, however, some
@@ -650,7 +677,6 @@
          * the w/h values below too much, so that the full thickness of the
          * rendered line will be captured by our image caching code.
          */
-        String detail;
         if (c instanceof JToolBar.Separator) {
             /*
              * GTK renders toolbar separators differently in that an
@@ -678,7 +704,6 @@
             float pct = 0.2f;
             JToolBar.Separator sep = (JToolBar.Separator)c;
             Dimension size = sep.getSeparatorSize();
-            GTKStyle style = (GTKStyle)context.getStyle();
             if (orientation == JSeparator.HORIZONTAL) {
                 x += (int)(w * pct);
                 w -= (int)(w * pct * 2);
@@ -743,6 +768,15 @@
         // The ubuntulooks engine paints slider troughs differently depending
         // on the current slider value and its component orientation.
         JSlider slider = (JSlider)context.getComponent();
+        if (GTKLookAndFeel.is3()) {
+            if (slider.getOrientation() == JSlider.VERTICAL) {
+                y += 1;
+                h -= 2;
+            } else {
+                x += 1;
+                w -= 2;
+            }
+        }
         double value = slider.getValue();
         double min = slider.getMinimum();
         double max = slider.getMaximum();
@@ -776,15 +810,19 @@
         Region id = context.getRegion();
         int gtkState = GTKLookAndFeel.synthStateToGTKState(
                 id, context.getComponentState());
+        boolean hasFocus = GTKLookAndFeel.is3() &&
+                ((context.getComponentState() & SynthConstants.FOCUSED) != 0);
         synchronized (UNIXToolkit.GTK_LOCK) {
-            if (! ENGINE.paintCachedImage(g, x, y, w, h, id, gtkState, dir)) {
+            if (! ENGINE.paintCachedImage(g, x, y, w, h, id, gtkState, dir,
+                                                                    hasFocus)) {
                 Orientation orientation = (dir == JSlider.HORIZONTAL ?
                     Orientation.HORIZONTAL : Orientation.VERTICAL);
                 String detail = (dir == JSlider.HORIZONTAL ?
                     "hscale" : "vscale");
                 ENGINE.startPainting(g, x, y, w, h, id, gtkState, dir);
                 ENGINE.paintSlider(g, context, id, gtkState,
-                        ShadowType.OUT, detail, x, y, w, h, orientation);
+                        ShadowType.OUT, detail, x, y, w, h, orientation,
+                                                                     hasFocus);
                 ENGINE.finishPainting();
             }
         }
@@ -963,15 +1001,21 @@
             int yThickness = style.getYThickness();
 
             ENGINE.startPainting(g, x, y, w, h, id, state);
+            if (GTKLookAndFeel.is3()) {
+                ENGINE.paintBackground(g, context, id, gtkState, null,
+                                                                    x, y, w, h);
+            }
             ENGINE.paintShadow(g, context, id, gtkState,
                                ShadowType.IN, "entry", x, y, w, h);
-            ENGINE.paintFlatBox(g, context, id,
-                                gtkState, ShadowType.NONE, "entry_bg",
-                                x + xThickness,
-                                y + yThickness,
-                                w - (2 * xThickness),
-                                h - (2 * yThickness),
-                                ColorType.TEXT_BACKGROUND);
+            if (!GTKLookAndFeel.is3()) {
+                ENGINE.paintFlatBox(g, context, id,
+                        gtkState, ShadowType.NONE, "entry_bg",
+                        x + xThickness,
+                        y + yThickness,
+                        w - (2 * xThickness),
+                        h - (2 * yThickness),
+                        ColorType.TEXT_BACKGROUND);
+            }
 
             if (focusSize > 0 && (state & SynthConstants.FOCUSED) != 0) {
                 if (!interiorFocus) {
@@ -982,14 +1026,14 @@
                 } else {
                     if (containerParent instanceof JComboBox) {
                         x += (focusSize + 2);
-                        y += (focusSize + 1);
-                        w -= (2 * focusSize + 1);
-                        h -= (2 * focusSize + 2);
+                        y += focusSize + (GTKLookAndFeel.is3() ? 3 : 1);
+                        w -= 2 * focusSize + (GTKLookAndFeel.is3() ? 4 : 1);
+                        h -= 2 * focusSize + (GTKLookAndFeel.is3() ? 6 : 2);
                     } else {
-                        x += focusSize;
-                        y += focusSize;
-                        w -= 2 * focusSize;
-                        h -= 2 * focusSize;
+                        x += focusSize + (GTKLookAndFeel.is3() ? 2 : 0);
+                        y += focusSize + (GTKLookAndFeel.is3() ? 2 :0 );
+                        w -= 2 * focusSize + (GTKLookAndFeel.is3() ? 4 : 0);
+                        h -= 2 * focusSize + (GTKLookAndFeel.is3() ? 4 : 0);
                     }
                 }
                 ENGINE.paintFocus(g, context, id, gtkState,
@@ -1138,8 +1182,8 @@
                 Orientation orientation = (dir == JScrollBar.HORIZONTAL ?
                     Orientation.HORIZONTAL : Orientation.VERTICAL);
                 ENGINE.setRangeValue(context, id, value, min, max, visible);
-                ENGINE.paintSlider(g, context, id, gtkState,
-                        ShadowType.OUT, "slider", x, y, w, h, orientation);
+                ENGINE.paintSlider(g, context, id, gtkState, ShadowType.OUT,
+                                      "slider", x, y, w, h, orientation, false);
                 ENGINE.finishPainting();
             }
         }
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKStyle.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKStyle.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, 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
@@ -715,29 +715,33 @@
         if (region == Region.COMBO_BOX ||
               region == Region.DESKTOP_PANE ||
               region == Region.DESKTOP_ICON ||
-              region == Region.EDITOR_PANE ||
-              region == Region.FORMATTED_TEXT_FIELD ||
               region == Region.INTERNAL_FRAME ||
               region == Region.LIST ||
               region == Region.MENU_BAR ||
               region == Region.PANEL ||
-              region == Region.PASSWORD_FIELD ||
               region == Region.POPUP_MENU ||
               region == Region.PROGRESS_BAR ||
               region == Region.ROOT_PANE ||
               region == Region.SCROLL_PANE ||
-              region == Region.SPINNER ||
               region == Region.SPLIT_PANE_DIVIDER ||
               region == Region.TABLE ||
               region == Region.TEXT_AREA ||
-              region == Region.TEXT_FIELD ||
-              region == Region.TEXT_PANE ||
               region == Region.TOOL_BAR_DRAG_WINDOW ||
               region == Region.TOOL_TIP ||
               region == Region.TREE ||
               region == Region.VIEWPORT) {
             return true;
         }
+        if (!GTKLookAndFeel.is3()) {
+            if (region == Region.EDITOR_PANE ||
+                  region == Region.FORMATTED_TEXT_FIELD ||
+                  region == Region.PASSWORD_FIELD ||
+                  region == Region.SPINNER ||
+                  region == Region.TEXT_FIELD ||
+                  region == Region.TEXT_PANE) {
+                return true;
+            }
+        }
         Component c = context.getComponent();
         String name = c.getName();
         if (name == "ComboBox.renderer" || name == "ComboBox.listRenderer") {
@@ -776,6 +780,15 @@
         }
         else if (key == "Separator.thickness") {
             JSeparator sep = (JSeparator)context.getComponent();
+            if (getClassSpecificBoolValue(context, "wide-separators", false)) {
+                if (sep.getOrientation() == JSeparator.HORIZONTAL) {
+                    return getClassSpecificIntValue(context,
+                            "separator-height", 0);
+                } else {
+                    return getClassSpecificIntValue(context,
+                            "separator-width", 0);
+                }
+            }
             if (sep.getOrientation() == JSeparator.HORIZONTAL) {
                 return getYThickness();
             } else {
@@ -783,6 +796,12 @@
             }
         }
         else if (key == "ToolBar.separatorSize") {
+            if (getClassSpecificBoolValue(context, "wide-separators", false)) {
+                return new DimensionUIResource(
+                    getClassSpecificIntValue(context, "separator-width", 2),
+                    getClassSpecificIntValue(context, "separator-height", 2)
+                );
+            }
             int size = getClassSpecificIntValue(WidgetType.TOOL_BAR,
                                                 "space-size", 12);
             return new DimensionUIResource(size, size);
@@ -833,6 +852,8 @@
             int focusPad =
                 getClassSpecificIntValue(context, "focus-padding", 1);
             return indicatorSpacing + focusSize + focusPad;
+        } else if (GTKLookAndFeel.is3() && "ComboBox.forceOpaque".equals(key)) {
+            return true;
         }
 
         // Is it a stock icon ?
@@ -1112,6 +1133,7 @@
     static {
         CLASS_SPECIFIC_MAP = new HashMap<String,String>();
         CLASS_SPECIFIC_MAP.put("Slider.thumbHeight", "slider-width");
+        CLASS_SPECIFIC_MAP.put("Slider.thumbWidth", "slider-length");
         CLASS_SPECIFIC_MAP.put("Slider.trackBorder", "trough-border");
         CLASS_SPECIFIC_MAP.put("SplitPane.size", "handle-size");
         CLASS_SPECIFIC_MAP.put("Tree.expanderSize", "expander-size");
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/Metacity.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/Metacity.java	Thu Apr 28 23:08:16 2016 -0700
@@ -185,7 +185,7 @@
                                                getIntAttr(child, "bottom", 0),
                                                getIntAttr(child, "right", 0));
                         } else if ("aspect_ratio".equals(name)) {
-                            value = new Float(getFloatAttr(child, "value", 1.0F));
+                            value = Float.valueOf(getFloatAttr(child, "value", 1.0F));
                         } else {
                             logError(themeName, "Unknown Metacity frame geometry value type: "+name);
                         }
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/AnimationController.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/AnimationController.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,6 @@
 
 
 
-import sun.swing.UIClientPropertyKey;
 import com.sun.java.swing.plaf.windows.TMSchema.State;
 import static com.sun.java.swing.plaf.windows.TMSchema.State.*;
 import com.sun.java.swing.plaf.windows.TMSchema.Part;
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java	Thu Apr 28 23:08:16 2016 -0700
@@ -64,7 +64,6 @@
 import sun.awt.OSInfo;
 import sun.awt.shell.ShellFolder;
 import sun.font.FontUtilities;
-import sun.misc.ManagedLocalsThread;
 import sun.security.action.GetPropertyAction;
 
 import sun.swing.DefaultLayoutStyle;
@@ -2053,7 +2052,7 @@
             if (audioRunnable != null) {
                 // Runnable appears to block until completed playing, hence
                 // start up another thread to handle playing.
-                new ManagedLocalsThread(audioRunnable).start();
+                new Thread(null, audioRunnable, "Audio", 0, false).start();
             }
         }
     }
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AudioFloatConverter.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AudioFloatConverter.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, 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
@@ -22,6 +22,7 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+
 package com.sun.media.sound;
 
 import java.nio.ByteBuffer;
@@ -319,8 +320,10 @@
                 float[] out_buff, int out_offset, int out_len) {
             int ix = in_offset;
             int ox = out_offset;
-            for (int i = 0; i < out_len; i++)
-                out_buff[ox++] = in_buff[ix++] * (1.0f / 127.0f);
+            for (int i = 0; i < out_len; i++) {
+                byte x = in_buff[ix++];
+                out_buff[ox++] = x > 0 ? x / 127.0f : x / 128.0f;
+            }
             return out_buff;
         }
 
@@ -328,8 +331,10 @@
                 byte[] out_buff, int out_offset) {
             int ix = in_offset;
             int ox = out_offset;
-            for (int i = 0; i < in_len; i++)
-                out_buff[ox++] = (byte) (in_buff[ix++] * 127.0f);
+            for (int i = 0; i < in_len; i++) {
+                final float x = in_buff[ix++];
+                out_buff[ox++] = (byte) (x > 0 ? x * 127 : x * 128);
+            }
             return out_buff;
         }
     }
@@ -340,9 +345,10 @@
                 float[] out_buff, int out_offset, int out_len) {
             int ix = in_offset;
             int ox = out_offset;
-            for (int i = 0; i < out_len; i++)
-                out_buff[ox++] = ((in_buff[ix++] & 0xFF) - 127)
-                        * (1.0f / 127.0f);
+            for (int i = 0; i < out_len; i++) {
+                byte x = (byte) (in_buff[ix++] - 128);
+                out_buff[ox++] = x > 0 ? x / 127.0f : x / 128.0f;
+            }
             return out_buff;
         }
 
@@ -350,8 +356,10 @@
                 byte[] out_buff, int out_offset) {
             int ix = in_offset;
             int ox = out_offset;
-            for (int i = 0; i < in_len; i++)
-                out_buff[ox++] = (byte) (127 + in_buff[ix++] * 127.0f);
+            for (int i = 0; i < in_len; i++) {
+                float x = in_buff[ix++];
+                out_buff[ox++] = (byte) (128 + (x > 0 ? x * 127 : x * 128));
+            }
             return out_buff;
         }
     }
@@ -369,10 +377,9 @@
             int ix = in_offset;
             int len = out_offset + out_len;
             for (int ox = out_offset; ox < len; ox++) {
-                out_buff[ox] = ((short) ((in_buff[ix++] & 0xFF) |
-                           (in_buff[ix++] << 8))) * (1.0f / 32767.0f);
+                short x = (short) (in_buff[ix++] & 0xFF | (in_buff[ix++] << 8));
+                out_buff[ox] = x > 0 ? x / 32767.0f : x / 32768.0f;
             }
-
             return out_buff;
         }
 
@@ -381,7 +388,8 @@
             int ox = out_offset;
             int len = in_offset + in_len;
             for (int ix = in_offset; ix < len; ix++) {
-                int x = (int) (in_buff[ix] * 32767.0);
+                float f = in_buff[ix];
+                short x = (short) (f > 0 ? f * 32767 : f * 32768);
                 out_buff[ox++] = (byte) x;
                 out_buff[ox++] = (byte) (x >>> 8);
             }
@@ -396,8 +404,8 @@
             int ix = in_offset;
             int ox = out_offset;
             for (int i = 0; i < out_len; i++) {
-                out_buff[ox++] = ((short) ((in_buff[ix++] << 8) |
-                        (in_buff[ix++] & 0xFF))) * (1.0f / 32767.0f);
+                short x = (short) ((in_buff[ix++] << 8) | (in_buff[ix++] & 0xFF));
+                out_buff[ox++] = x > 0 ? x / 32767.0f : x / 32768.0f;
             }
             return out_buff;
         }
@@ -407,7 +415,8 @@
             int ix = in_offset;
             int ox = out_offset;
             for (int i = 0; i < in_len; i++) {
-                int x = (int) (in_buff[ix++] * 32767.0);
+                float f = in_buff[ix++];
+                short x = (short) (f > 0 ? f * 32767.0f : f * 32768.0f);
                 out_buff[ox++] = (byte) (x >>> 8);
                 out_buff[ox++] = (byte) x;
             }
@@ -423,7 +432,8 @@
             int ox = out_offset;
             for (int i = 0; i < out_len; i++) {
                 int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8);
-                out_buff[ox++] = (x - 32767) * (1.0f / 32767.0f);
+                x -= 32768;
+                out_buff[ox++] = x > 0 ? x / 32767.0f : x / 32768.0f;
             }
             return out_buff;
         }
@@ -433,7 +443,8 @@
             int ix = in_offset;
             int ox = out_offset;
             for (int i = 0; i < in_len; i++) {
-                int x = 32767 + (int) (in_buff[ix++] * 32767.0);
+                float f = in_buff[ix++];
+                int x = 32768 + (int) (f > 0 ? f * 32767 : f * 32768);
                 out_buff[ox++] = (byte) x;
                 out_buff[ox++] = (byte) (x >>> 8);
             }
@@ -449,7 +460,8 @@
             int ox = out_offset;
             for (int i = 0; i < out_len; i++) {
                 int x = ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
-                out_buff[ox++] = (x - 32767) * (1.0f / 32767.0f);
+                x -= 32768;
+                out_buff[ox++] = x > 0 ? x / 32767.0f : x / 32768.0f;
             }
             return out_buff;
         }
@@ -459,7 +471,8 @@
             int ix = in_offset;
             int ox = out_offset;
             for (int i = 0; i < in_len; i++) {
-                int x = 32767 + (int) (in_buff[ix++] * 32767.0);
+                float f = in_buff[ix++];
+                int x = 32768 + (int) (f > 0 ? f * 32767 : f * 32768);
                 out_buff[ox++] = (byte) (x >>> 8);
                 out_buff[ox++] = (byte) x;
             }
@@ -484,7 +497,7 @@
                         | ((in_buff[ix++] & 0xFF) << 16);
                 if (x > 0x7FFFFF)
                     x -= 0x1000000;
-                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
+                out_buff[ox++] = x > 0 ? x / 8388607.0f : x / 8388608.0f;
             }
             return out_buff;
         }
@@ -494,7 +507,8 @@
             int ix = in_offset;
             int ox = out_offset;
             for (int i = 0; i < in_len; i++) {
-                int x = (int) (in_buff[ix++] * (float)0x7FFFFF);
+                float f = in_buff[ix++];
+                int x = (int) (f > 0 ? f * 8388607.0f : f * 8388608.0f);
                 if (x < 0)
                     x += 0x1000000;
                 out_buff[ox++] = (byte) x;
@@ -516,7 +530,7 @@
                         | ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
                 if (x > 0x7FFFFF)
                     x -= 0x1000000;
-                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
+                out_buff[ox++] = x > 0 ? x / 8388607.0f : x / 8388608.0f;
             }
             return out_buff;
         }
@@ -526,7 +540,8 @@
             int ix = in_offset;
             int ox = out_offset;
             for (int i = 0; i < in_len; i++) {
-                int x = (int) (in_buff[ix++] * (float)0x7FFFFF);
+                float f = in_buff[ix++];
+                int x = (int) (f > 0 ? f * 8388607.0f : f * 8388608.0f);
                 if (x < 0)
                     x += 0x1000000;
                 out_buff[ox++] = (byte) (x >>> 16);
@@ -546,8 +561,8 @@
             for (int i = 0; i < out_len; i++) {
                 int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)
                         | ((in_buff[ix++] & 0xFF) << 16);
-                x -= 0x7FFFFF;
-                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
+                x -= 0x800000;
+                out_buff[ox++] = x > 0 ? x / 8388607.0f : x / 8388608.0f;
             }
             return out_buff;
         }
@@ -557,8 +572,9 @@
             int ix = in_offset;
             int ox = out_offset;
             for (int i = 0; i < in_len; i++) {
-                int x = (int) (in_buff[ix++] * (float)0x7FFFFF);
-                x += 0x7FFFFF;
+                float f = in_buff[ix++];
+                int x = (int) (f > 0 ? f * 8388607.0f : f * 8388608.0f);
+                x += 0x800000;
                 out_buff[ox++] = (byte) x;
                 out_buff[ox++] = (byte) (x >>> 8);
                 out_buff[ox++] = (byte) (x >>> 16);
@@ -576,8 +592,8 @@
             for (int i = 0; i < out_len; i++) {
                 int x = ((in_buff[ix++] & 0xFF) << 16)
                         | ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
-                x -= 0x7FFFFF;
-                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
+                x -= 0x800000;
+                out_buff[ox++] = x > 0 ? x / 8388607.0f : x / 8388608.0f;
             }
             return out_buff;
         }
@@ -587,8 +603,9 @@
             int ix = in_offset;
             int ox = out_offset;
             for (int i = 0; i < in_len; i++) {
-                int x = (int) (in_buff[ix++] * (float)0x7FFFFF);
-                x += 0x7FFFFF;
+                float f = in_buff[ix++];
+                int x = (int) (f > 0 ? f * 8388607.0f : f * 8388608.0f);
+                x += 8388608;
                 out_buff[ox++] = (byte) (x >>> 16);
                 out_buff[ox++] = (byte) (x >>> 8);
                 out_buff[ox++] = (byte) x;
@@ -673,7 +690,7 @@
                 int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8) |
                         ((in_buff[ix++] & 0xFF) << 16) |
                         ((in_buff[ix++] & 0xFF) << 24);
-                x -= 0x7FFFFFFF;
+                x -= 0x80000000;
                 out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
             }
             return out_buff;
@@ -685,7 +702,7 @@
             int ox = out_offset;
             for (int i = 0; i < in_len; i++) {
                 int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
-                x += 0x7FFFFFFF;
+                x += 0x80000000;
                 out_buff[ox++] = (byte) x;
                 out_buff[ox++] = (byte) (x >>> 8);
                 out_buff[ox++] = (byte) (x >>> 16);
@@ -706,7 +723,7 @@
                 int x = ((in_buff[ix++] & 0xFF) << 24) |
                         ((in_buff[ix++] & 0xFF) << 16) |
                         ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
-                x -= 0x7FFFFFFF;
+                x -= 0x80000000;
                 out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
             }
             return out_buff;
@@ -718,7 +735,7 @@
             int ox = out_offset;
             for (int i = 0; i < in_len; i++) {
                 int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
-                x += 0x7FFFFFFF;
+                x += 0x80000000;
                 out_buff[ox++] = (byte) (x >>> 24);
                 out_buff[ox++] = (byte) (x >>> 16);
                 out_buff[ox++] = (byte) (x >>> 8);
@@ -737,7 +754,7 @@
     // PCM 32+ bit, signed, little-endian
     private static class AudioFloatConversion32xSL extends AudioFloatConverter {
 
-        final int xbytes;
+        private final int xbytes;
 
         AudioFloatConversion32xSL(int xbytes) {
             this.xbytes = xbytes;
@@ -778,7 +795,7 @@
     // PCM 32+ bit, signed, big-endian
     private static class AudioFloatConversion32xSB extends AudioFloatConverter {
 
-        final int xbytes;
+        private final int xbytes;
 
         AudioFloatConversion32xSB(int xbytes) {
             this.xbytes = xbytes;
@@ -820,7 +837,7 @@
     // PCM 32+ bit, unsigned, little-endian
     private static class AudioFloatConversion32xUL extends AudioFloatConverter {
 
-        final int xbytes;
+        private final int xbytes;
 
         AudioFloatConversion32xUL(int xbytes) {
             this.xbytes = xbytes;
@@ -835,7 +852,7 @@
                 int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)
                         | ((in_buff[ix++] & 0xFF) << 16)
                         | ((in_buff[ix++] & 0xFF) << 24);
-                x -= 0x7FFFFFFF;
+                x -= 0x80000000;
                 out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
             }
             return out_buff;
@@ -847,7 +864,7 @@
             int ox = out_offset;
             for (int i = 0; i < in_len; i++) {
                 int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
-                x += 0x7FFFFFFF;
+                x += 0x80000000;
                 for (int j = 0; j < xbytes; j++) {
                     out_buff[ox++] = 0;
                 }
@@ -863,7 +880,7 @@
     // PCM 32+ bit, unsigned, big-endian
     private static class AudioFloatConversion32xUB extends AudioFloatConverter {
 
-        final int xbytes;
+        private final int xbytes;
 
         AudioFloatConversion32xUB(int xbytes) {
             this.xbytes = xbytes;
@@ -878,7 +895,7 @@
                         ((in_buff[ix++] & 0xFF) << 16) |
                         ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
                 ix += xbytes;
-                x -= 2147483647;
+                x -= 0x80000000;
                 out_buff[ox++] = x * (1.0f / 2147483647.0f);
             }
             return out_buff;
@@ -889,8 +906,8 @@
             int ix = in_offset;
             int ox = out_offset;
             for (int i = 0; i < in_len; i++) {
-                int x = (int) (in_buff[ix++] * 2147483647.0);
-                x += 2147483647;
+                int x = (int) (in_buff[ix++] * 2147483647.0f);
+                x += 0x80000000;
                 out_buff[ox++] = (byte) (x >>> 24);
                 out_buff[ox++] = (byte) (x >>> 16);
                 out_buff[ox++] = (byte) (x >>> 8);
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,8 +25,6 @@
 
 package com.sun.media.sound;
 
-import sun.misc.ManagedLocalsThread;
-
 import java.io.BufferedInputStream;
 import java.io.InputStream;
 import java.io.File;
@@ -145,12 +143,11 @@
     static Thread createThread(final Runnable runnable,
                                final String threadName,
                                final boolean isDaemon, final int priority,
-                               final boolean doStart) {
-        Thread thread = new ManagedLocalsThread(runnable);
+                               final boolean doStart)
+    {
+        String name = (threadName != null) ? threadName : "JSSM Thread";
+        Thread thread = new Thread(null, runnable, threadName, 0, false);
 
-        if (threadName != null) {
-            thread.setName(threadName);
-        }
         thread.setDaemon(isDaemon);
         if (priority >= 0) {
             thread.setPriority(priority);
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/JavaSoundAudioClip.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/JavaSoundAudioClip.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, 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
@@ -232,7 +232,7 @@
         } else if (sequencer != null) {
             try {
                 sequencerloop = false;
-                sequencer.addMetaEventListener(this);
+                sequencer.removeMetaEventListener(this);
                 sequencer.stop();
             } catch (Exception e3) {
                 if (Printer.err) e3.printStackTrace();
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftAudioPusher.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftAudioPusher.java	Thu Apr 28 23:08:16 2016 -0700
@@ -24,8 +24,6 @@
  */
 package com.sun.media.sound;
 
-import sun.misc.ManagedLocalsThread;
-
 import java.io.IOException;
 
 import javax.sound.sampled.AudioInputStream;
@@ -55,7 +53,7 @@
         if (active)
             return;
         active = true;
-        audiothread = new ManagedLocalsThread(this);
+        audiothread = new Thread(null, this, "AudioPusher", 0, false);
         audiothread.setDaemon(true);
         audiothread.setPriority(Thread.MAX_PRIORITY);
         audiothread.start();
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftJitterCorrector.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftJitterCorrector.java	Thu Apr 28 23:08:16 2016 -0700
@@ -24,8 +24,6 @@
  */
 package com.sun.media.sound;
 
-import sun.misc.ManagedLocalsThread;
-
 import javax.sound.sampled.AudioFormat;
 import javax.sound.sampled.AudioInputStream;
 import java.io.EOFException;
@@ -216,7 +214,7 @@
                 }
             };
 
-            thread = new ManagedLocalsThread(runnable);
+            thread = new Thread(null, runnable, "JitterCorrector", 0, false);
             thread.setDaemon(true);
             thread.setPriority(Thread.MAX_PRIORITY);
             thread.start();
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftSynthesizer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftSynthesizer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,8 +25,6 @@
 
 package com.sun.media.sound;
 
-import sun.misc.ManagedLocalsThread;
-
 import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.FileInputStream;
@@ -141,7 +139,7 @@
                      pusher = null;
                      jitter_stream = null;
                      sourceDataLine = null;
-                     new ManagedLocalsThread(runnable).start();
+                     new Thread(null, runnable, "Synthesizer",0,false).start();
                  }
                  return len;
              }
--- a/jdk/src/java.desktop/share/classes/java/awt/Component.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/java/awt/Component.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2016, 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
@@ -68,7 +68,6 @@
 import sun.awt.ConstrainableGraphics;
 import sun.awt.SubRegionShowable;
 import sun.awt.SunToolkit;
-import sun.awt.CausedFocusEvent;
 import sun.awt.EmbeddedFrame;
 import sun.awt.dnd.SunDropTargetEvent;
 import sun.awt.im.CompositionArea;
@@ -878,7 +877,7 @@
             {
                 comp.setGraphicsConfiguration(gc);
             }
-            public boolean requestFocus(Component comp, CausedFocusEvent.Cause cause) {
+            public boolean requestFocus(Component comp, FocusEvent.Cause cause) {
                 return comp.requestFocus(cause);
             }
             public boolean canBeFocusOwner(Component comp) {
@@ -7538,7 +7537,7 @@
         requestFocusHelper(false, true);
     }
 
-    boolean requestFocus(CausedFocusEvent.Cause cause) {
+    boolean requestFocus(FocusEvent.Cause cause) {
         return requestFocusHelper(false, true, cause);
     }
 
@@ -7605,7 +7604,7 @@
         return requestFocusHelper(temporary, true);
     }
 
-    boolean requestFocus(boolean temporary, CausedFocusEvent.Cause cause) {
+    boolean requestFocus(boolean temporary, FocusEvent.Cause cause) {
         return requestFocusHelper(temporary, true, cause);
     }
     /**
@@ -7656,7 +7655,7 @@
         return requestFocusHelper(false, false);
     }
 
-    boolean requestFocusInWindow(CausedFocusEvent.Cause cause) {
+    boolean requestFocusInWindow(FocusEvent.Cause cause) {
         return requestFocusHelper(false, false, cause);
     }
 
@@ -7721,18 +7720,18 @@
         return requestFocusHelper(temporary, false);
     }
 
-    boolean requestFocusInWindow(boolean temporary, CausedFocusEvent.Cause cause) {
+    boolean requestFocusInWindow(boolean temporary, FocusEvent.Cause cause) {
         return requestFocusHelper(temporary, false, cause);
     }
 
     final boolean requestFocusHelper(boolean temporary,
                                      boolean focusedWindowChangeAllowed) {
-        return requestFocusHelper(temporary, focusedWindowChangeAllowed, CausedFocusEvent.Cause.UNKNOWN);
+        return requestFocusHelper(temporary, focusedWindowChangeAllowed, FocusEvent.Cause.UNKNOWN);
     }
 
     final boolean requestFocusHelper(boolean temporary,
                                      boolean focusedWindowChangeAllowed,
-                                     CausedFocusEvent.Cause cause)
+                                     FocusEvent.Cause cause)
     {
         // 1) Check if the event being dispatched is a system-generated mouse event.
         AWTEvent currentEvent = EventQueue.getCurrentEvent();
@@ -7820,7 +7819,7 @@
 
     private boolean isRequestFocusAccepted(boolean temporary,
                                            boolean focusedWindowChangeAllowed,
-                                           CausedFocusEvent.Cause cause)
+                                           FocusEvent.Cause cause)
     {
         if (!isFocusable() || !isVisible()) {
             if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
@@ -7867,7 +7866,7 @@
             return true;
         }
 
-        if (CausedFocusEvent.Cause.ACTIVATION == cause) {
+        if (FocusEvent.Cause.ACTIVATION == cause) {
             // we shouldn't call RequestFocusController in case we are
             // in activation.  We do request focus on component which
             // has got temporary focus lost and then on component which is
@@ -7899,7 +7898,7 @@
     private static class DummyRequestFocusController implements RequestFocusController {
         public boolean acceptRequestFocus(Component from, Component to,
                                           boolean temporary, boolean focusedWindowChangeAllowed,
-                                          CausedFocusEvent.Cause cause)
+                                          FocusEvent.Cause cause)
         {
             return true;
         }
@@ -7983,7 +7982,7 @@
         Component toFocus = getNextFocusCandidate();
         boolean res = false;
         if (toFocus != null && !toFocus.isFocusOwner() && toFocus != this) {
-            res = toFocus.requestFocusInWindow(CausedFocusEvent.Cause.TRAVERSAL_FORWARD);
+            res = toFocus.requestFocusInWindow(FocusEvent.Cause.TRAVERSAL_FORWARD);
         }
         if (clearOnFailure && !res) {
             if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
@@ -8063,7 +8062,7 @@
                 toFocus = policy.getDefaultComponent(rootAncestor);
             }
             if (toFocus != null) {
-                res = toFocus.requestFocusInWindow(CausedFocusEvent.Cause.TRAVERSAL_BACKWARD);
+                res = toFocus.requestFocusInWindow(FocusEvent.Cause.TRAVERSAL_BACKWARD);
             }
         }
         if (clearOnFailure && !res) {
@@ -8108,7 +8107,7 @@
 
             KeyboardFocusManager.getCurrentKeyboardFocusManager().
                 setGlobalCurrentFocusCycleRootPriv(fcr);
-            rootAncestor.requestFocus(CausedFocusEvent.Cause.TRAVERSAL_UP);
+            rootAncestor.requestFocus(FocusEvent.Cause.TRAVERSAL_UP);
         } else {
             Window window = getContainingWindow();
 
@@ -8118,7 +8117,7 @@
                 if (toFocus != null) {
                     KeyboardFocusManager.getCurrentKeyboardFocusManager().
                         setGlobalCurrentFocusCycleRootPriv(window);
-                    toFocus.requestFocus(CausedFocusEvent.Cause.TRAVERSAL_UP);
+                    toFocus.requestFocus(FocusEvent.Cause.TRAVERSAL_UP);
                 }
             }
         }
--- a/jdk/src/java.desktop/share/classes/java/awt/Container.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/java/awt/Container.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -55,7 +55,6 @@
 
 import sun.awt.AppContext;
 import sun.awt.AWTAccessor;
-import sun.awt.CausedFocusEvent;
 import sun.awt.PeerEvent;
 import sun.awt.SunToolkit;
 
@@ -3515,7 +3514,7 @@
             Component toFocus = getFocusTraversalPolicy().
                 getDefaultComponent(this);
             if (toFocus != null) {
-                toFocus.requestFocus(CausedFocusEvent.Cause.TRAVERSAL_DOWN);
+                toFocus.requestFocus(FocusEvent.Cause.TRAVERSAL_DOWN);
             }
         }
     }
--- a/jdk/src/java.desktop/share/classes/java/awt/DefaultKeyboardFocusManager.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/java/awt/DefaultKeyboardFocusManager.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,7 +40,6 @@
 import sun.awt.AppContext;
 import sun.awt.SunToolkit;
 import sun.awt.AWTAccessor;
-import sun.awt.CausedFocusEvent;
 import sun.awt.TimedWindowEvent;
 
 /**
@@ -165,13 +164,13 @@
                                    boolean clearOnFailure)
     {
         if (toFocus != vetoedComponent && toFocus.isShowing() && toFocus.canBeFocusOwner() &&
-            toFocus.requestFocus(false, CausedFocusEvent.Cause.ROLLBACK))
+            toFocus.requestFocus(false, FocusEvent.Cause.ROLLBACK))
         {
             return true;
         } else {
             Component nextFocus = toFocus.getNextFocusCandidate();
             if (nextFocus != null && nextFocus != vetoedComponent &&
-                nextFocus.requestFocusInWindow(CausedFocusEvent.Cause.ROLLBACK))
+                nextFocus.requestFocusInWindow(FocusEvent.Cause.ROLLBACK))
             {
                 return true;
             } else if (clearOnFailure) {
@@ -431,13 +430,13 @@
                                        tempLost, toFocus);
                     }
                     if (tempLost != null) {
-                        tempLost.requestFocusInWindow(CausedFocusEvent.Cause.ACTIVATION);
+                        tempLost.requestFocusInWindow(FocusEvent.Cause.ACTIVATION);
                     }
 
                     if (toFocus != null && toFocus != tempLost) {
                         // If there is a component which requested focus when this window
                         // was inactive it expects to receive focus after activation.
-                        toFocus.requestFocusInWindow(CausedFocusEvent.Cause.ACTIVATION);
+                        toFocus.requestFocusInWindow(FocusEvent.Cause.ACTIVATION);
                     }
                 }
 
@@ -490,8 +489,6 @@
 
             case FocusEvent.FOCUS_GAINED: {
                 FocusEvent fe = (FocusEvent)e;
-                CausedFocusEvent.Cause cause = (fe instanceof CausedFocusEvent) ?
-                    ((CausedFocusEvent)fe).getCause() : CausedFocusEvent.Cause.UNKNOWN;
                 Component oldFocusOwner = getGlobalFocusOwner();
                 Component newFocusOwner = fe.getComponent();
                 if (oldFocusOwner == newFocusOwner) {
@@ -509,10 +506,10 @@
                 if (oldFocusOwner != null) {
                     boolean isEventDispatched =
                         sendMessage(oldFocusOwner,
-                                    new CausedFocusEvent(oldFocusOwner,
+                                    new FocusEvent(oldFocusOwner,
                                                    FocusEvent.FOCUS_LOST,
                                                    fe.isTemporary(),
-                                                   newFocusOwner, cause));
+                                                   newFocusOwner, fe.getCause()));
                     // Failed to dispatch, clear by ourselves
                     if (!isEventDispatched) {
                         setGlobalFocusOwner(null);
@@ -552,7 +549,7 @@
                     // Refuse focus on a disabled component if the focus event
                     // isn't of UNKNOWN reason (i.e. not a result of a direct request
                     // but traversal, activation or system generated).
-                    (newFocusOwner.isEnabled() || cause.equals(CausedFocusEvent.Cause.UNKNOWN))))
+                    (newFocusOwner.isEnabled() || fe.getCause().equals(FocusEvent.Cause.UNKNOWN))))
                 {
                     // we should not accept focus on such component, so reject it.
                     dequeueKeyEvents(-1, newFocusOwner);
@@ -601,10 +598,10 @@
                 Component realOppositeComponent = this.realOppositeComponentWR.get();
                 if (realOppositeComponent != null &&
                     realOppositeComponent != fe.getOppositeComponent()) {
-                    fe = new CausedFocusEvent(newFocusOwner,
+                    fe = new FocusEvent(newFocusOwner,
                                         FocusEvent.FOCUS_GAINED,
                                         fe.isTemporary(),
-                                        realOppositeComponent, cause);
+                                        realOppositeComponent, fe.getCause());
                     ((AWTEvent) fe).isPosted = true;
                 }
                 return typeAheadAssertions(newFocusOwner, fe);
@@ -729,10 +726,10 @@
                         oppositeComp = oppositeWindow;
                     }
                     sendMessage(currentFocusOwner,
-                                new CausedFocusEvent(currentFocusOwner,
+                                new FocusEvent(currentFocusOwner,
                                                FocusEvent.FOCUS_LOST,
                                                true,
-                                               oppositeComp, CausedFocusEvent.Cause.ACTIVATION));
+                                               oppositeComp, FocusEvent.Cause.ACTIVATION));
                 }
 
                 setGlobalFocusedWindow(null);
--- a/jdk/src/java.desktop/share/classes/java/awt/EventDispatchThread.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/java/awt/EventDispatchThread.java	Thu Apr 28 23:08:16 2016 -0700
@@ -31,7 +31,6 @@
 
 import java.util.ArrayList;
 
-import sun.misc.ManagedLocalsThread;
 import sun.util.logging.PlatformLogger;
 
 import sun.awt.dnd.SunDragSourceContextPeer;
@@ -55,7 +54,7 @@
  *
  * @since 1.1
  */
-class EventDispatchThread extends ManagedLocalsThread {
+class EventDispatchThread extends Thread {
 
     private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.EventDispatchThread");
 
@@ -66,8 +65,16 @@
 
     private ArrayList<EventFilter> eventFilters = new ArrayList<EventFilter>();
 
+   /**
+    * Must always call 5 args super-class constructor passing false
+    * to indicate not to inherit locals.
+    */
+    private EventDispatchThread() {
+        throw new UnsupportedOperationException("Must erase locals");
+    }
+
     EventDispatchThread(ThreadGroup group, String name, EventQueue queue) {
-        super(group, name);
+        super(group, null, name, 0, false);
         setEventQueue(queue);
     }
 
--- a/jdk/src/java.desktop/share/classes/java/awt/Font.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/java/awt/Font.java	Thu Apr 28 23:08:16 2016 -0700
@@ -766,6 +766,49 @@
     }
 
     /**
+     * Returns true if any part of the specified text is from a
+     * complex script for which the implementation will need to invoke
+     * layout processing in order to render correctly when using
+     * {@link Graphics#drawString(String,int,int) drawString(String,int,int)}
+     * and other text rendering methods. Measurement of the text
+     * may similarly need the same extra processing.
+     * The {@code start} and {@code end} indices are provided so that
+     * the application can request only a subset of the text be considered.
+     * The last char index examined is at {@code "end-1"},
+     * i.e a request to examine the entire array would be
+     * <pre>
+     * {@code Font.textRequiresLayout(chars, 0, chars.length);}
+     * </pre>
+     * An application may find this information helpful in
+     * performance sensitive code.
+     * <p>
+     * Note that even if this method returns {@code false}, layout processing
+     * may still be invoked when used with any {@code Font}
+     * for which {@link #hasLayoutAttributes()} returns {@code true},
+     * so that method will need to be consulted for the specific font,
+     * in order to obtain an answer which accounts for such font attributes.
+     *
+     * @param chars the text.
+     * @param start the index of the first char to examine.
+     * @param end the ending index, exclusive.
+     * @return {@code true} if the specified text will need special layout.
+     * @throws NullPointerException if {@code chars} is null.
+     * @throws ArrayIndexOutOfBoundsException if {@code start} is negative or
+     * {@code end} is greater than the length of the {@code chars} array.
+     * @since 9
+     */
+    public static boolean textRequiresLayout(char[] chars,
+                                             int start, int end) {
+        if (chars == null) {
+           throw new NullPointerException("null char array");
+        }
+        if (start < 0 || end > chars.length) {
+            throw new ArrayIndexOutOfBoundsException("start < 0 or end > len");
+        }
+        return FontUtilities.isComplexScript(chars, start, end);
+    }
+
+    /**
      * Returns a {@code Font} appropriate to the attributes.
      * If {@code attributes} contains a {@code FONT} attribute
      * with a valid {@code Font} as its value, it will be
--- a/jdk/src/java.desktop/share/classes/java/awt/KeyboardFocusManager.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/java/awt/KeyboardFocusManager.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -57,7 +57,6 @@
 
 import sun.awt.AppContext;
 import sun.awt.SunToolkit;
-import sun.awt.CausedFocusEvent;
 import sun.awt.KeyboardFocusManagerPeerProvider;
 import sun.awt.AWTAccessor;
 
@@ -124,7 +123,7 @@
                                                    boolean temporary,
                                                    boolean focusedWindowChangeAllowed,
                                                    long time,
-                                                   CausedFocusEvent.Cause cause)
+                                                   FocusEvent.Cause cause)
                 {
                     return KeyboardFocusManager.shouldNativelyFocusHeavyweight(
                         heavyweight, descendant, temporary, focusedWindowChangeAllowed, time, cause);
@@ -2164,9 +2163,9 @@
     private static final class LightweightFocusRequest {
         final Component component;
         final boolean temporary;
-        final CausedFocusEvent.Cause cause;
+        final FocusEvent.Cause cause;
 
-        LightweightFocusRequest(Component component, boolean temporary, CausedFocusEvent.Cause cause) {
+        LightweightFocusRequest(Component component, boolean temporary, FocusEvent.Cause cause) {
             this.component = component;
             this.temporary = temporary;
             this.cause = cause;
@@ -2190,7 +2189,7 @@
         }
 
         HeavyweightFocusRequest(Component heavyweight, Component descendant,
-                                boolean temporary, CausedFocusEvent.Cause cause) {
+                                boolean temporary, FocusEvent.Cause cause) {
             if (log.isLoggable(PlatformLogger.Level.FINE)) {
                 if (heavyweight == null) {
                     log.fine("Assertion (heavyweight != null) failed");
@@ -2202,7 +2201,7 @@
             addLightweightRequest(descendant, temporary, cause);
         }
         boolean addLightweightRequest(Component descendant,
-                                      boolean temporary, CausedFocusEvent.Cause cause) {
+                                      boolean temporary, FocusEvent.Cause cause) {
             if (log.isLoggable(PlatformLogger.Level.FINE)) {
                 if (this == HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER) {
                     log.fine("Assertion (this != HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER) failed");
@@ -2314,7 +2313,7 @@
 
                 hwFocusRequest =
                     new HeavyweightFocusRequest(heavyweight, descendant,
-                                                temporary, CausedFocusEvent.Cause.UNKNOWN);
+                                                temporary, FocusEvent.Cause.UNKNOWN);
                 heavyweightRequests.add(hwFocusRequest);
 
                 if (currentFocusOwner != null) {
@@ -2379,7 +2378,7 @@
      */
     static int shouldNativelyFocusHeavyweight
         (Component heavyweight, Component descendant, boolean temporary,
-         boolean focusedWindowChangeAllowed, long time, CausedFocusEvent.Cause cause)
+         boolean focusedWindowChangeAllowed, long time, FocusEvent.Cause cause)
     {
         if (log.isLoggable(PlatformLogger.Level.FINE)) {
             if (heavyweight == null) {
@@ -2445,7 +2444,7 @@
 
                 if (currentFocusOwner != null) {
                     FocusEvent currentFocusOwnerEvent =
-                        new CausedFocusEvent(currentFocusOwner,
+                        new FocusEvent(currentFocusOwner,
                                        FocusEvent.FOCUS_LOST,
                                        temporary, descendant, cause);
                     // Fix 5028014. Rolled out.
@@ -2454,7 +2453,7 @@
                                          currentFocusOwnerEvent);
                 }
                 FocusEvent newFocusOwnerEvent =
-                    new CausedFocusEvent(descendant, FocusEvent.FOCUS_GAINED,
+                    new FocusEvent(descendant, FocusEvent.FOCUS_GAINED,
                                    temporary, currentFocusOwner, cause);
                 // Fix 5028014. Rolled out.
                 // SunToolkit.postPriorityEvent(newFocusOwnerEvent);
@@ -2670,13 +2669,13 @@
                      * lw requests.
                      */
                     if (currentFocusOwner != null) {
-                        currentFocusOwnerEvent = new CausedFocusEvent(currentFocusOwner,
+                        currentFocusOwnerEvent = new FocusEvent(currentFocusOwner,
                                        FocusEvent.FOCUS_LOST,
                                        lwFocusRequest.temporary,
                                        lwFocusRequest.component, lwFocusRequest.cause);
                     }
                     FocusEvent newFocusOwnerEvent =
-                        new CausedFocusEvent(lwFocusRequest.component,
+                        new FocusEvent(lwFocusRequest.component,
                                        FocusEvent.FOCUS_GAINED,
                                        lwFocusRequest.temporary,
                                        currentFocusOwner == null ? lastFocusOwner : currentFocusOwner,
@@ -2726,8 +2725,8 @@
             {
                 temporary = true;
             }
-            return new CausedFocusEvent(source, fe.getID(), temporary, opposite,
-                                        CausedFocusEvent.Cause.NATIVE_SYSTEM);
+            return new FocusEvent(source, fe.getID(), temporary, opposite,
+                                        FocusEvent.Cause.UNEXPECTED);
         }
     }
 
@@ -2802,7 +2801,7 @@
 
                 // 'opposite' will be fixed by
                 // DefaultKeyboardFocusManager.realOppositeComponent
-                return new CausedFocusEvent(newSource,
+                return new FocusEvent(newSource,
                                       FocusEvent.FOCUS_GAINED, temporary,
                                       opposite, lwFocusRequest.cause);
             }
@@ -2815,8 +2814,8 @@
                 // If it arrives as the result of activation we should skip it
                 // This event will not have appropriate request record and
                 // on arrival there will be already some focus owner set.
-                return new CausedFocusEvent(currentFocusOwner, FocusEvent.FOCUS_GAINED, false,
-                                            null, CausedFocusEvent.Cause.ACTIVATION);
+                return new FocusEvent(currentFocusOwner, FocusEvent.FOCUS_GAINED, false,
+                                            null, FocusEvent.Cause.ACTIVATION);
             }
 
             return retargetUnexpectedFocusEvent(fe);
@@ -2839,9 +2838,9 @@
                 if (currentFocusOwner != null) {
                     // Call to KeyboardFocusManager.clearGlobalFocusOwner()
                     heavyweightRequests.removeFirst();
-                    return new CausedFocusEvent(currentFocusOwner,
+                    return new FocusEvent(currentFocusOwner,
                                                 FocusEvent.FOCUS_LOST, false, null,
-                                                CausedFocusEvent.Cause.CLEAR_GLOBAL_FOCUS_OWNER);
+                                                FocusEvent.Cause.CLEAR_GLOBAL_FOCUS_OWNER);
                 }
 
                 // Otherwise, fall through to failure case below
@@ -2850,9 +2849,9 @@
             {
                 // Focus leaving application
                 if (currentFocusOwner != null) {
-                    return new CausedFocusEvent(currentFocusOwner,
+                    return new FocusEvent(currentFocusOwner,
                                                 FocusEvent.FOCUS_LOST,
-                                                true, null, CausedFocusEvent.Cause.ACTIVATION);
+                                                true, null, FocusEvent.Cause.ACTIVATION);
                 } else {
                     return fe;
                 }
@@ -2878,15 +2877,15 @@
                     ? true
                     : lwFocusRequest.temporary;
 
-                return new CausedFocusEvent(currentFocusOwner, FocusEvent.FOCUS_LOST,
+                return new FocusEvent(currentFocusOwner, FocusEvent.FOCUS_LOST,
                                             temporary, lwFocusRequest.component, lwFocusRequest.cause);
             } else if (focusedWindowChanged(opposite, currentFocusOwner)) {
                 // If top-level changed there might be no focus request in a list
                 // But we know the opposite, we now it is temporary - dispatch the event.
                 if (!fe.isTemporary() && currentFocusOwner != null) {
                     // Create copy of the event with only difference in temporary parameter.
-                    fe = new CausedFocusEvent(currentFocusOwner, FocusEvent.FOCUS_LOST,
-                                              true, opposite, CausedFocusEvent.Cause.ACTIVATION);
+                    fe = new FocusEvent(currentFocusOwner, FocusEvent.FOCUS_LOST,
+                                              true, opposite, FocusEvent.Cause.ACTIVATION);
                 }
                 return fe;
             }
--- a/jdk/src/java.desktop/share/classes/java/awt/Window.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/java/awt/Window.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2016, 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
@@ -52,7 +52,6 @@
 import sun.awt.AWTAccessor;
 import sun.awt.AWTPermissions;
 import sun.awt.AppContext;
-import sun.awt.CausedFocusEvent;
 import sun.awt.DebugSettings;
 import sun.awt.SunToolkit;
 import sun.awt.util.IdentityArrayList;
@@ -2599,7 +2598,7 @@
                 {
                     Component toFocus =
                         KeyboardFocusManager.getMostRecentFocusOwner(owner);
-                    if (toFocus != null && toFocus.requestFocus(false, CausedFocusEvent.Cause.ACTIVATION)) {
+                    if (toFocus != null && toFocus.requestFocus(false, FocusEvent.Cause.ACTIVATION)) {
                         return;
                     }
                 }
--- a/jdk/src/java.desktop/share/classes/java/awt/event/FocusEvent.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/java/awt/event/FocusEvent.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, 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 @@
 package java.awt.event;
 
 import java.awt.Component;
+import java.io.ObjectStreamException;
+
+import sun.awt.AWTAccessor;
 import sun.awt.AppContext;
 import sun.awt.SunToolkit;
 
@@ -51,6 +54,10 @@
  * the FOCUS_GAINED and FOCUS_LOST event ids; the level may be distinguished in
  * the event using the isTemporary() method.
  * <p>
+ * Every {@code FocusEvent} records its cause - the reason why this event was
+ * generated. The cause is assigned during the focus event creation and may be
+ * retrieved by calling {@link #getCause}.
+ * <p>
  * An unspecified behavior will be caused if the {@code id} parameter
  * of any particular {@code FocusEvent} instance is not
  * in the range from {@code FOCUS_FIRST} to {@code FOCUS_LAST}.
@@ -66,6 +73,61 @@
 public class FocusEvent extends ComponentEvent {
 
     /**
+     * This enum represents the cause of a {@code FocusEvent}- the reason why it
+     * occurred. Possible reasons include mouse events, keyboard focus
+     * traversal, window activation.
+     * If no cause is provided then the reason is {@code UNKNOWN}.
+     *
+     * @since 9
+     */
+    public enum Cause {
+        /**
+         * The default value.
+         */
+        UNKNOWN,
+        /**
+         * An activating mouse event.
+         */
+        MOUSE_EVENT,
+        /**
+         * A focus traversal action with unspecified direction.
+         */
+        TRAVERSAL,
+        /**
+         * An up-cycle focus traversal action.
+         */
+        TRAVERSAL_UP,
+        /**
+         * A down-cycle focus traversal action.
+         */
+        TRAVERSAL_DOWN,
+        /**
+         * A forward focus traversal action.
+         */
+        TRAVERSAL_FORWARD,
+        /**
+         * A backward focus traversal action.
+         */
+        TRAVERSAL_BACKWARD,
+        /**
+         * Restoring focus after a focus request has been rejected.
+         */
+        ROLLBACK,
+        /**
+         * A system action causing an unexpected focus change.
+         */
+        UNEXPECTED,
+        /**
+         * An activation of a toplevel window.
+         */
+        ACTIVATION,
+        /**
+         * Clearing global focus owner.
+         */
+        CLEAR_GLOBAL_FOCUS_OWNER
+    }
+
+    /**
      * The first number in the range of ids used for focus events.
      */
     public static final int FOCUS_FIRST         = 1004;
@@ -86,6 +148,16 @@
     public static final int FOCUS_LOST = 1 + FOCUS_FIRST; //Event.LOST_FOCUS
 
     /**
+     * A focus event has the reason why this event was generated.
+     * The cause is set during the focus event creation.
+     *
+     * @serial
+     * @see #getCause()
+     * @since 9
+     */
+    private final Cause cause;
+
+    /**
      * A focus event can have two different levels, permanent and temporary.
      * It will be set to true if some operation takes away the focus
      * temporarily and intends on getting it back once the event is completed.
@@ -115,7 +187,8 @@
 
     /**
      * Constructs a {@code FocusEvent} object with the
-     * specified temporary state and opposite {@code Component}.
+     * specified temporary state, opposite {@code Component} and the
+     * {@code Cause.UNKNOWN} cause.
      * The opposite {@code Component} is the other
      * {@code Component} involved in this focus change.
      * For a {@code FOCUS_GAINED} event, this is the
@@ -142,13 +215,57 @@
      * @see #getID()
      * @see #isTemporary()
      * @see #getOppositeComponent()
+     * @see Cause#UNKNOWN
      * @since 1.4
      */
     public FocusEvent(Component source, int id, boolean temporary,
                       Component opposite) {
+        this(source, id, temporary, opposite, Cause.UNKNOWN);
+    }
+
+    /**
+     * Constructs a {@code FocusEvent} object with the
+     * specified temporary state, opposite {@code Component} and the cause.
+     * The opposite {@code Component} is the other
+     * {@code Component} involved in this focus change.
+     * For a {@code FOCUS_GAINED} event, this is the
+     * {@code Component} that lost focus. For a
+     * {@code FOCUS_LOST} event, this is the {@code Component}
+     * that gained focus. If this focus change occurs with a native
+     * application, with a Java application in a different VM,
+     * or with no other {@code Component}, then the opposite
+     * {@code Component} is {@code null}.
+     * <p> This method throws an
+     * {@code IllegalArgumentException} if {@code source} or {@code cause}
+     * is {@code null}.
+     *
+     * @param source    The {@code Component} that originated the event
+     * @param id        An integer indicating the type of event.
+     *                  For information on allowable values, see
+     *                  the class description for {@link FocusEvent}
+     * @param temporary Equals {@code true} if the focus change is temporary;
+     *                  {@code false} otherwise
+     * @param opposite  The other Component involved in the focus change,
+     *                  or {@code null}
+     * @param cause     The focus event cause.
+     * @throws IllegalArgumentException if {@code source} equals {@code null}
+     *                                  or if {@code cause} equals {@code null}
+     * @see #getSource()
+     * @see #getID()
+     * @see #isTemporary()
+     * @see #getOppositeComponent()
+     * @see Cause
+     * @since 9
+     */
+    public FocusEvent(Component source, int id, boolean temporary,
+                      Component opposite, Cause cause) {
         super(source, id);
+        if (cause == null) {
+            throw new IllegalArgumentException("null cause");
+        }
         this.temporary = temporary;
         this.opposite = opposite;
+        this.cause = cause;
     }
 
     /**
@@ -220,8 +337,8 @@
 
         return (SunToolkit.targetToAppContext(opposite) ==
                 AppContext.getAppContext())
-            ? opposite
-            : null;
+                ? opposite
+                : null;
     }
 
     /**
@@ -233,17 +350,56 @@
     public String paramString() {
         String typeStr;
         switch(id) {
-          case FOCUS_GAINED:
-              typeStr = "FOCUS_GAINED";
-              break;
-          case FOCUS_LOST:
-              typeStr = "FOCUS_LOST";
-              break;
-          default:
-              typeStr = "unknown type";
+            case FOCUS_GAINED:
+                typeStr = "FOCUS_GAINED";
+                break;
+            case FOCUS_LOST:
+                typeStr = "FOCUS_LOST";
+                break;
+            default:
+                typeStr = "unknown type";
         }
         return typeStr + (temporary ? ",temporary" : ",permanent") +
-            ",opposite=" + getOppositeComponent();
+                ",opposite=" + getOppositeComponent() + ",cause=" + getCause();
+    }
+
+    /**
+     * Returns the event cause.
+     *
+     * @return one of {@link Cause} values
+     * @since 9
+     */
+    public final Cause getCause() {
+        return cause;
     }
 
-}
+    /**
+     * Checks if this deserialized {@code FocusEvent} instance is compatible
+     * with the current specification which implies that focus event has
+     * non-null {@code cause} value. If the check fails a new {@code FocusEvent}
+     * instance is returned which {@code cause} field equals to
+     * {@link Cause#UNKNOWN} and its other fields have the same values as in
+     * this {@code FocusEvent} instance.
+     *
+     * @serial
+     * @see #cause
+     * @since 9
+     */
+    @SuppressWarnings("serial")
+    Object readResolve() throws ObjectStreamException {
+        if (cause != null) {
+            return this;
+        }
+        FocusEvent focusEvent = new FocusEvent(new Component(){}, getID(),
+                isTemporary(), getOppositeComponent());
+        focusEvent.setSource(null);
+        focusEvent.consumed = consumed;
+
+        AWTAccessor.AWTEventAccessor accessor =
+                AWTAccessor.getAWTEventAccessor();
+        accessor.setBData(focusEvent, accessor.getBData(this));
+        return focusEvent;
+    }
+
+
+}
\ No newline at end of file
--- a/jdk/src/java.desktop/share/classes/java/awt/font/TextAttribute.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/java/awt/font/TextAttribute.java	Thu Apr 28 23:08:16 2016 -0700
@@ -79,7 +79,7 @@
  *   will be ignored.
  *   <li>The identity of the value does not matter, only the actual
  *   value.  For example, {@code TextAttribute.WEIGHT_BOLD} and
- *   {@code new Float(2.0)}
+ *   {@code Float.valueOf(2.0f)}
  *   indicate the same {@code WEIGHT}.
  *   <li>Attribute values of type {@code Number} (used for
  *   {@code WEIGHT}, {@code WIDTH}, {@code POSTURE},
--- a/jdk/src/java.desktop/share/classes/java/awt/font/TextMeasurer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/java/awt/font/TextMeasurer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -105,7 +105,7 @@
         String s = System.getProperty("estLines");
         if (s != null) {
             try {
-                Float f = new Float(s);
+                Float f = Float.valueOf(s);
                 EST_LINES = f.floatValue();
             }
             catch(NumberFormatException e) {
--- a/jdk/src/java.desktop/share/classes/java/awt/image/PackedColorModel.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/java/awt/image/PackedColorModel.java	Thu Apr 28 23:08:16 2016 -0700
@@ -404,9 +404,6 @@
 
         PackedColorModel cm = (PackedColorModel) obj;
         int numC = cm.getNumComponents();
-        if (numC != numComponents) {
-            return false;
-        }
         for(int i=0; i < numC; i++) {
             if (maskArray[i] != cm.getMask(i)) {
                 return false;
--- a/jdk/src/java.desktop/share/classes/java/awt/image/Raster.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/java/awt/image/Raster.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -629,7 +629,8 @@
                                                          int scanlineStride,
                                                          int pixelStride,
                                                          int bandOffsets[],
-                                                         Point location) {
+                                                         Point location)
+    {
         if (dataBuffer == null) {
             throw new NullPointerException("DataBuffer cannot be null");
         }
@@ -645,15 +646,26 @@
                                             bandOffsets);
         switch(dataType) {
         case DataBuffer.TYPE_BYTE:
-            return new ByteInterleavedRaster(csm, dataBuffer, location);
+            if (dataBuffer instanceof DataBufferByte) {
+                return new ByteInterleavedRaster(csm,
+                        (DataBufferByte) dataBuffer, location);
+            }
+            break;
 
         case DataBuffer.TYPE_USHORT:
-            return new ShortInterleavedRaster(csm, dataBuffer, location);
+            if (dataBuffer instanceof DataBufferUShort) {
+                return new ShortInterleavedRaster(csm,
+                        (DataBufferUShort) dataBuffer, location);
+            }
+            break;
 
         default:
             throw new IllegalArgumentException("Unsupported data type " +
                                                 dataType);
         }
+
+        // Create the generic raster
+        return new SunWritableRaster(csm, dataBuffer, location);
     }
 
     /**
@@ -691,7 +703,8 @@
                                                     int scanlineStride,
                                                     int bankIndices[],
                                                     int bandOffsets[],
-                                                    Point location) {
+                                                    Point location)
+    {
         if (dataBuffer == null) {
             throw new NullPointerException("DataBuffer cannot be null");
         }
@@ -713,18 +726,29 @@
 
         switch(dataType) {
         case DataBuffer.TYPE_BYTE:
-            return new ByteBandedRaster(bsm, dataBuffer, location);
+            if (dataBuffer instanceof DataBufferByte) {
+                return new ByteBandedRaster(bsm,
+                        (DataBufferByte) dataBuffer, location);
+            }
+            break;
 
         case DataBuffer.TYPE_USHORT:
-            return new ShortBandedRaster(bsm, dataBuffer, location);
+            if (dataBuffer instanceof DataBufferUShort) {
+                return new ShortBandedRaster(bsm,
+                        (DataBufferUShort) dataBuffer, location);
+            }
+            break;
 
         case DataBuffer.TYPE_INT:
-            return new SunWritableRaster(bsm, dataBuffer, location);
+            break;
 
         default:
             throw new IllegalArgumentException("Unsupported data type " +
                                                 dataType);
         }
+
+        // Create the generic raster
+        return new SunWritableRaster(bsm, dataBuffer, location);
     }
 
     /**
@@ -761,7 +785,8 @@
                                                     int w, int h,
                                                     int scanlineStride,
                                                     int bandMasks[],
-                                                    Point location) {
+                                                    Point location)
+    {
         if (dataBuffer == null) {
             throw new NullPointerException("DataBuffer cannot be null");
         }
@@ -776,18 +801,33 @@
 
         switch(dataType) {
         case DataBuffer.TYPE_BYTE:
-            return new ByteInterleavedRaster(sppsm, dataBuffer, location);
+            if (dataBuffer instanceof DataBufferByte) {
+                return new ByteInterleavedRaster(sppsm,
+                        (DataBufferByte) dataBuffer, location);
+            }
+            break;
 
         case DataBuffer.TYPE_USHORT:
-            return new ShortInterleavedRaster(sppsm, dataBuffer, location);
+            if (dataBuffer instanceof DataBufferUShort) {
+                return new ShortInterleavedRaster(sppsm,
+                        (DataBufferUShort) dataBuffer, location);
+            }
+            break;
 
         case DataBuffer.TYPE_INT:
-            return new IntegerInterleavedRaster(sppsm, dataBuffer, location);
+            if (dataBuffer instanceof DataBufferInt) {
+                return new IntegerInterleavedRaster(sppsm,
+                        (DataBufferInt) dataBuffer, location);
+            }
+            break;
 
         default:
             throw new IllegalArgumentException("Unsupported data type " +
                                                 dataType);
         }
+
+        // Create the generic raster
+        return new SunWritableRaster(sppsm, dataBuffer, location);
     }
 
     /**
@@ -821,7 +861,8 @@
     public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
                                                     int w, int h,
                                                     int bitsPerPixel,
-                                                    Point location) {
+                                                    Point location)
+    {
         if (dataBuffer == null) {
             throw new NullPointerException("DataBuffer cannot be null");
         }
@@ -846,9 +887,10 @@
         MultiPixelPackedSampleModel mppsm =
                 new MultiPixelPackedSampleModel(dataType, w, h, bitsPerPixel);
 
-        if (dataType == DataBuffer.TYPE_BYTE &&
-            (bitsPerPixel == 1 || bitsPerPixel == 2 || bitsPerPixel == 4)) {
-            return new BytePackedRaster(mppsm, dataBuffer, location);
+        if (dataBuffer instanceof DataBufferByte &&
+            (bitsPerPixel == 1 || bitsPerPixel == 2 || bitsPerPixel == 4))
+        {
+            return new BytePackedRaster(mppsm, (DataBufferByte) dataBuffer, location);
         } else {
             return new SunWritableRaster(mppsm, dataBuffer, location);
         }
@@ -878,7 +920,8 @@
      */
     public static Raster createRaster(SampleModel sm,
                                       DataBuffer db,
-                                      Point location) {
+                                      Point location)
+    {
         if ((sm == null) || (db == null)) {
             throw new NullPointerException("SampleModel and DataBuffer cannot be null");
         }
@@ -890,32 +933,53 @@
 
         if (sm instanceof PixelInterleavedSampleModel) {
             switch(dataType) {
-                case DataBuffer.TYPE_BYTE:
-                    return new ByteInterleavedRaster(sm, db, location);
+            case DataBuffer.TYPE_BYTE:
+                if (db instanceof DataBufferByte) {
+                    return new ByteInterleavedRaster(sm,
+                            (DataBufferByte) db, location);
+                }
+                break;
 
-                case DataBuffer.TYPE_USHORT:
-                    return new ShortInterleavedRaster(sm, db, location);
+            case DataBuffer.TYPE_USHORT:
+                if (db instanceof DataBufferUShort) {
+                    return new ShortInterleavedRaster(sm,
+                            (DataBufferUShort) db, location);
+                }
+                break;
             }
         } else if (sm instanceof SinglePixelPackedSampleModel) {
             switch(dataType) {
-                case DataBuffer.TYPE_BYTE:
-                    return new ByteInterleavedRaster(sm, db, location);
+            case DataBuffer.TYPE_BYTE:
+                if (db instanceof DataBufferByte) {
+                    return new ByteInterleavedRaster(sm,
+                            (DataBufferByte) db, location);
+                }
+                break;
 
-                case DataBuffer.TYPE_USHORT:
-                    return new ShortInterleavedRaster(sm, db, location);
+            case DataBuffer.TYPE_USHORT:
+                if (db instanceof DataBufferUShort) {
+                    return new ShortInterleavedRaster(sm,
+                            (DataBufferUShort) db, location);
+                }
+                break;
 
-                case DataBuffer.TYPE_INT:
-                    return new IntegerInterleavedRaster(sm, db, location);
+            case DataBuffer.TYPE_INT:
+                if (db instanceof DataBufferInt) {
+                    return new IntegerInterleavedRaster(sm,
+                            (DataBufferInt) db, location);
+                }
+                break;
             }
         } else if (sm instanceof MultiPixelPackedSampleModel &&
                    dataType == DataBuffer.TYPE_BYTE &&
-                   sm.getSampleSize(0) < 8) {
-            return new BytePackedRaster(sm, db, location);
+                   db instanceof DataBufferByte &&
+                   sm.getSampleSize(0) < 8)
+        {
+            return new BytePackedRaster(sm, (DataBufferByte) db, location);
         }
 
         // we couldn't do anything special - do the generic thing
-
-        return new Raster(sm,db,location);
+        return new Raster(sm, db, location);
     }
 
     /**
@@ -964,7 +1028,8 @@
      */
     public static WritableRaster createWritableRaster(SampleModel sm,
                                                       DataBuffer db,
-                                                      Point location) {
+                                                      Point location)
+    {
         if ((sm == null) || (db == null)) {
             throw new NullPointerException("SampleModel and DataBuffer cannot be null");
         }
@@ -976,32 +1041,53 @@
 
         if (sm instanceof PixelInterleavedSampleModel) {
             switch(dataType) {
-                case DataBuffer.TYPE_BYTE:
-                    return new ByteInterleavedRaster(sm, db, location);
+            case DataBuffer.TYPE_BYTE:
+                if (db instanceof DataBufferByte) {
+                    return new ByteInterleavedRaster(sm,
+                            (DataBufferByte) db, location);
+                }
+                break;
 
-                case DataBuffer.TYPE_USHORT:
-                    return new ShortInterleavedRaster(sm, db, location);
+            case DataBuffer.TYPE_USHORT:
+                if (db instanceof DataBufferUShort) {
+                    return new ShortInterleavedRaster(sm,
+                            (DataBufferUShort) db, location);
+                }
+                break;
             }
         } else if (sm instanceof SinglePixelPackedSampleModel) {
             switch(dataType) {
-                case DataBuffer.TYPE_BYTE:
-                    return new ByteInterleavedRaster(sm, db, location);
+            case DataBuffer.TYPE_BYTE:
+                if (db instanceof DataBufferByte) {
+                    return new ByteInterleavedRaster(sm,
+                            (DataBufferByte) db, location);
+                }
+                break;
 
-                case DataBuffer.TYPE_USHORT:
-                    return new ShortInterleavedRaster(sm, db, location);
+            case DataBuffer.TYPE_USHORT:
+                if (db instanceof DataBufferUShort) {
+                    return new ShortInterleavedRaster(sm,
+                            (DataBufferUShort) db, location);
+                }
+                break;
 
-                case DataBuffer.TYPE_INT:
-                    return new IntegerInterleavedRaster(sm, db, location);
+            case DataBuffer.TYPE_INT:
+                if (db instanceof DataBufferInt) {
+                    return new IntegerInterleavedRaster(sm,
+                            (DataBufferInt) db, location);
+                }
+                break;
             }
         } else if (sm instanceof MultiPixelPackedSampleModel &&
                    dataType == DataBuffer.TYPE_BYTE &&
-                   sm.getSampleSize(0) < 8) {
-            return new BytePackedRaster(sm, db, location);
+                   db instanceof DataBufferByte &&
+                   sm.getSampleSize(0) < 8)
+        {
+            return new BytePackedRaster(sm, (DataBufferByte) db, location);
         }
 
         // we couldn't do anything special - do the generic thing
-
-        return new SunWritableRaster(sm,db,location);
+        return new SunWritableRaster(sm, db, location);
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/java/awt/image/renderable/ParameterBlock.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/java/awt/image/renderable/ParameterBlock.java	Thu Apr 28 23:08:16 2016 -0700
@@ -392,7 +392,7 @@
      *         the specified parameter.
      */
     public ParameterBlock add(float f) {
-        return add(new Float(f));
+        return add(Float.valueOf(f));
     }
 
     /**
@@ -403,7 +403,7 @@
      *         the specified parameter.
      */
     public ParameterBlock add(double d) {
-        return add(new Double(d));
+        return add(Double.valueOf(d));
     }
 
     /**
@@ -521,7 +521,7 @@
      *        the specified parameter.
      */
     public ParameterBlock set(float f, int index) {
-        return set(new Float(f), index);
+        return set(Float.valueOf(f), index);
     }
 
     /**
@@ -537,7 +537,7 @@
      *        the specified parameter.
      */
     public ParameterBlock set(double d, int index) {
-        return set(new Double(d), index);
+        return set(Double.valueOf(d), index);
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/java/awt/image/renderable/RenderableImageProducer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/java/awt/image/renderable/RenderableImageProducer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -35,8 +35,6 @@
 
 package java.awt.image.renderable;
 
-import sun.misc.ManagedLocalsThread;
-
 import java.awt.image.ColorModel;
 import java.awt.image.DataBuffer;
 import java.awt.image.ImageConsumer;
@@ -137,7 +135,7 @@
         addConsumer(ic);
         // Need to build a runnable object for the Thread.
         String name = "RenderableImageProducer Thread";
-        Thread thread = new ManagedLocalsThread(this, name);
+        Thread thread = new Thread(null, this, name, 0, false);
         thread.start();
     }
 
--- a/jdk/src/java.desktop/share/classes/java/awt/peer/ComponentPeer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/java/awt/peer/ComponentPeer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2016, 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,12 +27,12 @@
 
 import java.awt.*;
 import java.awt.event.PaintEvent;
+import java.awt.event.FocusEvent.Cause;
 import java.awt.image.ColorModel;
 import java.awt.image.ImageObserver;
 import java.awt.image.ImageProducer;
 import java.awt.image.VolatileImage;
 
-import sun.awt.CausedFocusEvent;
 import sun.java2d.pipe.Region;
 
 
@@ -343,7 +343,7 @@
      */
     boolean requestFocus(Component lightweightChild, boolean temporary,
                          boolean focusedWindowChangeAllowed, long time,
-                         CausedFocusEvent.Cause cause);
+                         Cause cause);
 
     /**
      * Returns {@code true} when the component takes part in the focus
--- a/jdk/src/java.desktop/share/classes/java/awt/print/PrinterJob.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/java/awt/print/PrinterJob.java	Thu Apr 28 23:08:16 2016 -0700
@@ -577,6 +577,8 @@
     /**
      * Gets the name of the printing user.
      * @return the name of the printing user
+     * @throws SecurityException if a security manager exists and
+     *         PropertyPermission - user.name is not given in the policy file
      */
     public abstract String getUserName();
 
--- a/jdk/src/java.desktop/share/classes/javax/imageio/ImageIO.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/imageio/ImageIO.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1294,7 +1294,8 @@
      *
      * @exception IllegalArgumentException if {@code input} is
      * {@code null}.
-     * @exception IOException if an error occurs during reading.
+     * @exception IOException if an error occurs during reading or when not
+     * able to create required ImageInputStream.
      */
     public static BufferedImage read(File input) throws IOException {
         if (input == null) {
@@ -1344,7 +1345,8 @@
      *
      * @exception IllegalArgumentException if {@code input} is
      * {@code null}.
-     * @exception IOException if an error occurs during reading.
+     * @exception IOException if an error occurs during reading or when not
+     * able to create required ImageInputStream.
      */
     public static BufferedImage read(InputStream input) throws IOException {
         if (input == null) {
@@ -1352,6 +1354,9 @@
         }
 
         ImageInputStream stream = createImageInputStream(input);
+        if (stream == null) {
+            throw new IIOException("Can't create an ImageInputStream!");
+        }
         BufferedImage bi = read(stream);
         if (bi == null) {
             stream.close();
@@ -1384,7 +1389,8 @@
      *
      * @exception IllegalArgumentException if {@code input} is
      * {@code null}.
-     * @exception IOException if an error occurs during reading.
+     * @exception IOException if an error occurs during reading or when not
+     * able to create required ImageInputStream.
      */
     public static BufferedImage read(URL input) throws IOException {
         if (input == null) {
@@ -1398,6 +1404,14 @@
             throw new IIOException("Can't get input stream from URL!", e);
         }
         ImageInputStream stream = createImageInputStream(istream);
+        if (stream == null) {
+            /* close the istream when stream is null so that if user has
+             * given filepath as URL he can delete it, otherwise stream will
+             * be open to that file and he will not be able to delete it.
+             */
+            istream.close();
+            throw new IIOException("Can't create an ImageInputStream!");
+        }
         BufferedImage bi;
         try {
             bi = read(stream);
@@ -1510,7 +1524,8 @@
      *
      * @exception IllegalArgumentException if any parameter is
      * {@code null}.
-     * @exception IOException if an error occurs during writing.
+     * @exception IOException if an error occurs during writing or when not
+     * able to create required ImageOutputStream.
      */
     public static boolean write(RenderedImage im,
                                 String formatName,
@@ -1518,7 +1533,6 @@
         if (output == null) {
             throw new IllegalArgumentException("output == null!");
         }
-        ImageOutputStream stream = null;
 
         ImageWriter writer = getWriter(im, formatName);
         if (writer == null) {
@@ -1528,13 +1542,11 @@
             return false;
         }
 
-        try {
-            output.delete();
-            stream = createImageOutputStream(output);
-        } catch (IOException e) {
-            throw new IIOException("Can't create output stream!", e);
+        output.delete();
+        ImageOutputStream stream = createImageOutputStream(output);
+        if (stream == null) {
+            throw new IIOException("Can't create an ImageOutputStream!");
         }
-
         try {
             return doWrite(im, writer, stream);
         } finally {
@@ -1562,7 +1574,8 @@
      *
      * @exception IllegalArgumentException if any parameter is
      * {@code null}.
-     * @exception IOException if an error occurs during writing.
+     * @exception IOException if an error occurs during writing or when not
+     * able to create required ImageOutputStream.
      */
     public static boolean write(RenderedImage im,
                                 String formatName,
@@ -1570,13 +1583,10 @@
         if (output == null) {
             throw new IllegalArgumentException("output == null!");
         }
-        ImageOutputStream stream = null;
-        try {
-            stream = createImageOutputStream(output);
-        } catch (IOException e) {
-            throw new IIOException("Can't create output stream!", e);
+        ImageOutputStream stream = createImageOutputStream(output);
+        if (stream == null) {
+            throw new IIOException("Can't create an ImageOutputStream!");
         }
-
         try {
             return doWrite(im, getWriter(im, formatName), stream);
         } finally {
--- a/jdk/src/java.desktop/share/classes/javax/swing/JComponent.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JComponent.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -36,7 +36,6 @@
 
 import java.awt.*;
 import java.awt.event.*;
-import java.awt.peer.LightweightPeer;
 
 import java.applet.Applet;
 
@@ -57,7 +56,6 @@
 import sun.awt.AWTAccessor;
 import sun.awt.SunToolkit;
 import sun.swing.SwingUtilities2;
-import sun.swing.UIClientPropertyKey;
 
 /**
  * The base class for all Swing components except top-level containers.
@@ -3558,7 +3556,7 @@
         new sun.awt.RequestFocusController() {
             public boolean acceptRequestFocus(Component from, Component to,
                                               boolean temporary, boolean focusedWindowChangeAllowed,
-                                              sun.awt.CausedFocusEvent.Cause cause)
+                                              FocusEvent.Cause cause)
             {
                 if ((to == null) || !(to instanceof JComponent)) {
                     return true;
--- a/jdk/src/java.desktop/share/classes/javax/swing/JFileChooser.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JFileChooser.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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,13 +26,12 @@
 
 import javax.swing.event.*;
 import javax.swing.filechooser.*;
+import javax.swing.filechooser.FileFilter;
 import javax.swing.plaf.FileChooserUI;
 
 import javax.accessibility.*;
 
-import java.io.File;
-import java.io.ObjectOutputStream;
-import java.io.IOException;
+import java.io.*;
 
 import java.util.Vector;
 import java.awt.AWTEvent;
@@ -51,8 +50,6 @@
 import java.beans.BeanProperty;
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyChangeEvent;
-import java.io.InvalidObjectException;
-import java.io.ObjectInputStream;
 import java.lang.ref.WeakReference;
 
 /**
@@ -390,19 +387,7 @@
     }
 
     private void installHierarchyListener() {
-        addHierarchyListener(new HierarchyListener() {
-            @Override
-            public void hierarchyChanged(HierarchyEvent e) {
-                if ((e.getChangeFlags() & HierarchyEvent.PARENT_CHANGED)
-                        == HierarchyEvent.PARENT_CHANGED) {
-                    JFileChooser fc = JFileChooser.this;
-                    JRootPane rootPane = SwingUtilities.getRootPane(fc);
-                    if (rootPane != null) {
-                        rootPane.setDefaultButton(fc.getUI().getDefaultButton(fc));
-                    }
-                }
-            }
-        });
+        addHierarchyListener(new FCHierarchyListener());
     }
 
     private void installShowFilesListener() {
@@ -2055,4 +2040,18 @@
 
     } // inner class AccessibleJFileChooser
 
+    private class FCHierarchyListener implements HierarchyListener,
+            Serializable {
+        @Override
+        public void hierarchyChanged(HierarchyEvent e) {
+            if ((e.getChangeFlags() & HierarchyEvent.PARENT_CHANGED)
+                    == HierarchyEvent.PARENT_CHANGED) {
+                JFileChooser fc = JFileChooser.this;
+                JRootPane rootPane = SwingUtilities.getRootPane(fc);
+                if (rootPane != null) {
+                    rootPane.setDefaultButton(fc.getUI().getDefaultButton(fc));
+                }
+            }
+        }
+    }
 }
--- a/jdk/src/java.desktop/share/classes/javax/swing/JLayeredPane.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JLayeredPane.java	Thu Apr 28 23:08:16 2016 -0700
@@ -98,7 +98,7 @@
  * <PRE>
  *     layeredPane.add(child, JLayeredPane.DEFAULT_LAYER);
  * or
- *     layeredPane.add(child, new Integer(10));
+ *     layeredPane.add(child, Integer.valueOf.valueOf(10));
  * </PRE>
  * The layer attribute can also be set on a Component by calling<PRE>
  *     layeredPaneParent.setLayer(child, 10)</PRE>
@@ -162,23 +162,23 @@
 @SuppressWarnings("serial")
 public class JLayeredPane extends JComponent implements Accessible {
     /// Watch the values in getObjectForLayer()
-    /** Convenience object defining the Default layer. Equivalent to new Integer(0).*/
+    /** Convenience object defining the Default layer. Equivalent to Integer.valueOf(0).*/
     public static final Integer DEFAULT_LAYER = 0;
-    /** Convenience object defining the Palette layer. Equivalent to new Integer(100).*/
+    /** Convenience object defining the Palette layer. Equivalent to Integer.valueOf(100).*/
     public static final Integer PALETTE_LAYER = 100;
-    /** Convenience object defining the Modal layer. Equivalent to new Integer(200).*/
+    /** Convenience object defining the Modal layer. Equivalent to Integer.valueOf(200).*/
     public static final Integer MODAL_LAYER = 200;
-    /** Convenience object defining the Popup layer. Equivalent to new Integer(300).*/
+    /** Convenience object defining the Popup layer. Equivalent to Integer.valueOf(300).*/
     public static final Integer POPUP_LAYER = 300;
-    /** Convenience object defining the Drag layer. Equivalent to new Integer(400).*/
+    /** Convenience object defining the Drag layer. Equivalent to Integer.valueOf(400).*/
     public static final Integer DRAG_LAYER = 400;
     /** Convenience object defining the Frame Content layer.
       * This layer is normally only use to position the contentPane and menuBar
       * components of JFrame.
-      * Equivalent to new Integer(-30000).
+      * Equivalent to Integer.valueOf(-30000).
       * @see JFrame
       */
-    public static final Integer FRAME_CONTENT_LAYER = new Integer(-30000);
+    public static final Integer FRAME_CONTENT_LAYER = -30000;
 
     /** Bound property */
     public static final String LAYER_PROPERTY = "layeredContainerLayer";
--- a/jdk/src/java.desktop/share/classes/javax/swing/JMenu.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JMenu.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1296,7 +1296,7 @@
      * @return the array of menu items
      */
     private MenuElement[] buildMenuElementArray(JMenu leaf) {
-        Vector<MenuElement> elements = new Vector<MenuElement>();
+        Vector<MenuElement> elements = new Vector<>();
         Component current = leaf.getPopupMenu();
         JPopupMenu pop;
         JMenu menu;
@@ -1314,11 +1314,14 @@
             } else if (current instanceof JMenuBar) {
                 bar = (JMenuBar) current;
                 elements.insertElementAt(bar, 0);
-                MenuElement me[] = new MenuElement[elements.size()];
-                elements.copyInto(me);
-                return me;
+                break;
+            } else {
+                break;
             }
         }
+        MenuElement me[] = new MenuElement[elements.size()];
+        elements.copyInto(me);
+        return me;
     }
 
 
--- a/jdk/src/java.desktop/share/classes/javax/swing/JProgressBar.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JProgressBar.java	Thu Apr 28 23:08:16 2016 -0700
@@ -478,7 +478,7 @@
             if (format == null) {
                 format = NumberFormat.getPercentInstance();
             }
-            return format.format(new Double(getPercentComplete()));
+            return format.format(Double.valueOf(getPercentComplete()));
         }
     }
 
--- a/jdk/src/java.desktop/share/classes/javax/swing/JTable.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JTable.java	Thu Apr 28 23:08:16 2016 -0700
@@ -56,7 +56,6 @@
 import javax.print.attribute.*;
 import javax.print.PrintService;
 
-import sun.misc.ManagedLocalsThread;
 import sun.reflect.misc.ReflectUtil;
 
 import sun.swing.SwingUtilities2;
@@ -82,7 +81,7 @@
  *      TableModel dataModel = new AbstractTableModel() {
  *          public int getColumnCount() { return 10; }
  *          public int getRowCount() { return 10;}
- *          public Object getValueAt(int row, int col) { return new Integer(row*col); }
+ *          public Object getValueAt(int row, int col) { return Integer.valueOf(row*col); }
  *      };
  *      JTable table = new JTable(dataModel);
  *      JScrollPane scrollpane = new JScrollPane(table);
@@ -6375,7 +6374,7 @@
         };
 
         // start printing on another thread
-        Thread th = new ManagedLocalsThread(runnable);
+        Thread th = new Thread(null, runnable, "JTablePrint", 0, false);
         th.start();
 
         printingStatus.showModal(true);
--- a/jdk/src/java.desktop/share/classes/javax/swing/SpinnerNumberModel.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/SpinnerNumberModel.java	Thu Apr 28 23:08:16 2016 -0700
@@ -51,10 +51,10 @@
  * range zero to one hundred, with
  * fifty as the initial value, one could write:
  * <pre>
- * Integer value = new Integer(50);
- * Integer min = new Integer(0);
- * Integer max = new Integer(100);
- * Integer step = new Integer(1);
+ * Integer value = Integer.valueOf(50);
+ * Integer min = Integer.valueOf(0);
+ * Integer max = Integer.valueOf(100);
+ * Integer step = Integer.valueOf(1);
  * SpinnerNumberModel model = new SpinnerNumberModel(value, min, max, step);
  * int fifty = model.getNumber().intValue();
  * </pre>
@@ -175,7 +175,8 @@
      *     <code>minimum &lt;= value &lt;= maximum</code>
      */
     public SpinnerNumberModel(double value, double minimum, double maximum, double stepSize) {
-        this(new Double(value), new Double(minimum), new Double(maximum), new Double(stepSize));
+        this(Double.valueOf(value), Double.valueOf(minimum),
+             Double.valueOf(maximum), Double.valueOf(stepSize));
     }
 
 
@@ -337,10 +338,10 @@
         if ((value instanceof Float) || (value instanceof Double)) {
             double v = value.doubleValue() + (stepSize.doubleValue() * (double)dir);
             if (value instanceof Double) {
-                newValue = new Double(v);
+                newValue = Double.valueOf(v);
             }
             else {
-                newValue = new Float(v);
+                newValue = Float.valueOf((float)v);
             }
         } else {
             long v = value.longValue() + (stepSize.longValue() * (long)dir);
--- a/jdk/src/java.desktop/share/classes/javax/swing/SwingUtilities.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/SwingUtilities.java	Thu Apr 28 23:08:16 2016 -0700
@@ -846,14 +846,46 @@
     }
 
     /**
+     * Check whether MouseEvent contains speficied mouse button or
+     * mouse button down mask based on MouseEvent ID.
+     *
+     * @param anEvent  a MouseEvent object
+     * @param mouseButton mouse button type
+     * @param mouseButtonDownMask mouse button down mask event modifier
+     *
+     * @return true if the anEvent contains speficied mouseButton or
+     * mouseButtonDownMask based on MouseEvent ID.
+     */
+    private static boolean checkMouseButton(MouseEvent anEvent,
+                                            int mouseButton,
+                                            int mouseButtonDownMask)
+    {
+        switch (anEvent.getID()) {
+        case MouseEvent.MOUSE_PRESSED:
+        case MouseEvent.MOUSE_RELEASED:
+        case MouseEvent.MOUSE_CLICKED:
+            return (anEvent.getButton() == mouseButton);
+
+        case MouseEvent.MOUSE_ENTERED:
+        case MouseEvent.MOUSE_EXITED:
+        case MouseEvent.MOUSE_DRAGGED:
+            return ((anEvent.getModifiersEx() & mouseButtonDownMask) != 0);
+
+        default:
+            return ((anEvent.getModifiersEx() & mouseButtonDownMask) != 0 ||
+                    anEvent.getButton() == mouseButton);
+        }
+    }
+
+    /**
      * Returns true if the mouse event specifies the left mouse button.
      *
      * @param anEvent  a MouseEvent object
      * @return true if the left mouse button was active
      */
     public static boolean isLeftMouseButton(MouseEvent anEvent) {
-         return ((anEvent.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0 ||
-                 anEvent.getButton() == MouseEvent.BUTTON1);
+        return checkMouseButton(anEvent, MouseEvent.BUTTON1,
+                                InputEvent.BUTTON1_DOWN_MASK);
     }
 
     /**
@@ -863,8 +895,8 @@
      * @return true if the middle mouse button was active
      */
     public static boolean isMiddleMouseButton(MouseEvent anEvent) {
-        return ((anEvent.getModifiersEx() & InputEvent.BUTTON2_DOWN_MASK) != 0 ||
-                anEvent.getButton() == MouseEvent.BUTTON2);
+        return checkMouseButton(anEvent, MouseEvent.BUTTON2,
+                                InputEvent.BUTTON2_DOWN_MASK);
     }
 
     /**
@@ -874,8 +906,8 @@
      * @return true if the right mouse button was active
      */
     public static boolean isRightMouseButton(MouseEvent anEvent) {
-        return ((anEvent.getModifiersEx() & InputEvent.BUTTON3_DOWN_MASK) != 0 ||
-                anEvent.getButton() == MouseEvent.BUTTON3);
+        return checkMouseButton(anEvent, MouseEvent.BUTTON3,
+                                InputEvent.BUTTON3_DOWN_MASK);
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/TimerQueue.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/TimerQueue.java	Thu Apr 28 23:08:16 2016 -0700
@@ -36,7 +36,6 @@
 import java.util.concurrent.locks.*;
 import java.util.concurrent.atomic.AtomicLong;
 import sun.awt.AppContext;
-import sun.misc.ManagedLocalsThread;
 
 /**
  * Internal class to manage all Timers using one thread.
@@ -101,8 +100,8 @@
                 final ThreadGroup threadGroup = AppContext.getAppContext().getThreadGroup();
                 AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                     String name = "TimerQueue";
-                    Thread timerThread = new ManagedLocalsThread(threadGroup,
-                                                                 this, name);
+                    Thread timerThread =
+                        new Thread(threadGroup, this, name, 0, false);
                     timerThread.setDaemon(true);
                     timerThread.setPriority(Thread.NORM_PRIORITY);
                     timerThread.start();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/UIClientPropertyKey.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2006, 2016, 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 javax.swing;
+
+/**
+ * This interface is used only for tagging keys for client properties for
+ * {@code JComponent} set by UI which needs to be cleared on {@literal L&F}
+ * change and serialization.
+ * <p>
+ * All such keys are removed from client properties in
+ * {@code JComponent.setUI()} method after uninstalling old UI and before
+ * installing the new one. They are also removed prior to serialization.
+ *
+ * @author Igor Kushnirskiy
+ * @since 9
+ */
+public interface UIClientPropertyKey {
+}
--- a/jdk/src/java.desktop/share/classes/javax/swing/UIDefaults.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/UIDefaults.java	Thu Apr 28 23:08:16 2016 -0700
@@ -120,7 +120,7 @@
         Object[] uiDefaults = {
              "Font", new Font("Dialog", Font.BOLD, 12),
             "Color", Color.red,
-             "five", new Integer(5)
+             "five", Integer.valueOf(5)
         }
         UIDefaults myDefaults = new UIDefaults(uiDefaults);
      * </pre>
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java	Thu Apr 28 23:08:16 2016 -0700
@@ -26,7 +26,6 @@
 package javax.swing.plaf.basic;
 
 import sun.awt.shell.ShellFolder;
-import sun.misc.ManagedLocalsThread;
 
 import javax.swing.*;
 import javax.swing.event.ListDataEvent;
@@ -271,7 +270,7 @@
             this.currentDirectory = currentDirectory;
             this.fid = fid;
             String name = "Basic L&F File Loading Thread";
-            this.loadThread = new ManagedLocalsThread(this, name);
+            this.loadThread = new Thread(null, this, name, 0, false);
             this.loadThread.start();
         }
 
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicPopupMenuUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicPopupMenuUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -797,9 +797,11 @@
             if (invoker instanceof JPopupMenu) {
                 invoker = ((JPopupMenu)invoker).getInvoker();
             }
-            grabbedWindow = invoker instanceof Window?
-                    (Window)invoker :
-                    SwingUtilities.getWindowAncestor(invoker);
+            grabbedWindow = (invoker == null)
+                    ? null
+                    : ((invoker instanceof Window)
+                            ? (Window) invoker
+                            : SwingUtilities.getWindowAncestor(invoker));
             if(grabbedWindow != null) {
                 if(tk instanceof sun.awt.SunToolkit) {
                     ((sun.awt.SunToolkit)tk).grab(grabbedWindow);
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/metal/OceanTheme.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/metal/OceanTheme.java	Thu Apr 28 23:08:16 2016 -0700
@@ -134,7 +134,7 @@
             new BorderUIResource.LineBorderUIResource(getPrimary1());
         // .30 0 DDE8F3 white secondary2
         java.util.List<?> buttonGradient = Arrays.asList(
-                 new Object[] {new Float(.3f), new Float(0f),
+                 new Object[] {Float.valueOf(.3f), Float.valueOf(0f),
                  new ColorUIResource(0xDDE8F3), getWhite(), getSecondary2() });
 
         // Other possible properties that aren't defined:
@@ -150,7 +150,7 @@
         Object directoryIcon = getIconResource("icons/ocean/directory.gif");
         Object fileIcon = getIconResource("icons/ocean/file.gif");
         java.util.List<?> sliderGradient = Arrays.asList(new Object[] {
-            new Float(.3f), new Float(.2f),
+            Float.valueOf(.3f), Float.valueOf(.2f),
             c8ddf2, getWhite(), new ColorUIResource(SECONDARY2) });
 
         Object[] defaults = new Object[] {
@@ -192,7 +192,7 @@
             "Menu.opaque", Boolean.FALSE,
 
             "MenuBar.gradient", Arrays.asList(new Object[] {
-                     new Float(1f), new Float(0f),
+                     Float.valueOf(1f), Float.valueOf(0f),
                      getWhite(), dadada,
                      new ColorUIResource(dadada) }),
             "MenuBar.borderColor", cccccc,
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/nimbus/NimbusStyle.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/nimbus/NimbusStyle.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -995,16 +995,7 @@
                     // StateInfo match, otherwise a StateInfo with
                     // SELECTED | ENABLED would match ENABLED, which we
                     // don't want.
-
-                    // This comes from BigInteger.bitCnt
-                    int bitCount = oState;
-                    bitCount -= (0xaaaaaaaa & bitCount) >>> 1;
-                    bitCount = (bitCount & 0x33333333) + ((bitCount >>> 2) &
-                            0x33333333);
-                    bitCount = bitCount + (bitCount >>> 4) & 0x0f0f0f0f;
-                    bitCount += bitCount >>> 8;
-                    bitCount += bitCount >>> 16;
-                    bitCount = bitCount & 0xff;
+                    int bitCount = Integer.bitCount(oState);
                     if (bitCount > bestCount) {
                         bestIndex = counter;
                         bestCount = bitCount;
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthArrowButton.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthArrowButton.java	Thu Apr 28 23:08:16 2016 -0700
@@ -139,7 +139,6 @@
                 }
             }
 
-            context.dispose();
             return dim;
         }
     }
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthBorder.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthBorder.java	Thu Apr 28 23:08:16 2016 -0700
@@ -61,7 +61,6 @@
             return;
         }
         ui.paintBorder(context, g, x, y, width, height);
-        context.dispose();
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthButtonUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthButtonUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -105,7 +105,6 @@
             }
 
         }
-        context.dispose();
     }
 
     /**
@@ -125,7 +124,6 @@
         SynthContext context = getContext(b, ENABLED);
 
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
     }
 
@@ -226,7 +224,6 @@
         else {
             baseline = textRect.y + fm.getAscent();
         }
-        context.dispose();
         return baseline;
     }
 
@@ -253,7 +250,6 @@
         SynthLookAndFeel.update(context, g);
         paintBackground(context, g, c);
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -270,7 +266,6 @@
         SynthContext context = getContext(c);
 
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -321,7 +316,6 @@
     protected Icon getDefaultIcon(AbstractButton b) {
         SynthContext context = getContext(b);
         Icon icon = context.getStyle().getIcon(context, getPropertyPrefix() + "icon");
-        context.dispose();
         return icon;
     }
 
@@ -473,7 +467,6 @@
                b.getVerticalTextPosition(), b.getIconTextGap(),
                b.getDisplayedMnemonicIndex());
 
-        ss.dispose();
         return size;
     }
 
@@ -494,7 +487,6 @@
                b.getVerticalTextPosition(), b.getIconTextGap(),
                b.getDisplayedMnemonicIndex());
 
-        ss.dispose();
         return size;
     }
 
@@ -516,7 +508,6 @@
                b.getVerticalTextPosition(), b.getIconTextGap(),
                b.getDisplayedMnemonicIndex());
 
-        ss.dispose();
         return size;
     }
 
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthColorChooserUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthColorChooserUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -65,7 +65,6 @@
         SynthContext context = getContext(chooser, ENABLED);
         AbstractColorChooserPanel[] panels = (AbstractColorChooserPanel[])
                      context.getStyle().get(context, "ColorChooser.panels");
-        context.dispose();
 
         if (panels == null) {
             panels = ColorChooserComponentFactory.getDefaultChooserPanels();
@@ -85,7 +84,6 @@
     private void updateStyle(JComponent c) {
         SynthContext context = getContext(c, ENABLED);
         style = SynthLookAndFeel.updateStyle(context, this);
-        context.dispose();
     }
 
     /**
@@ -96,7 +94,6 @@
         SynthContext context = getContext(chooser, ENABLED);
 
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
         super.uninstallDefaults();
     }
@@ -155,7 +152,6 @@
         context.getPainter().paintColorChooserBackground(context, g, 0, 0,
                                                   c.getWidth(), c.getHeight());
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -172,7 +168,6 @@
         SynthContext context = getContext(c);
 
         paint(context, g);
-        context.dispose();
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthComboBoxUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthComboBoxUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -144,7 +144,6 @@
             forceOpaque = style.getBoolean(context,
                     "ComboBox.forceOpaque", false);
         }
-        context.dispose();
 
         if(listBox != null) {
             SynthLookAndFeel.updateStyles(listBox);
@@ -182,7 +181,6 @@
         SynthContext context = getContext(comboBox, ENABLED);
 
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
     }
 
@@ -323,7 +321,6 @@
         context.getPainter().paintComboBoxBackground(context, g, 0, 0,
                                                   c.getWidth(), c.getHeight());
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -340,7 +337,6 @@
         SynthContext context = getContext(c);
 
         paint(context, g);
-        context.dispose();
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthContext.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthContext.java	Thu Apr 28 23:08:16 2016 -0700
@@ -24,8 +24,6 @@
  */
 package javax.swing.plaf.synth;
 
-import java.util.Queue;
-import java.util.concurrent.ConcurrentLinkedQueue;
 import javax.swing.JComponent;
 
 /**
@@ -40,7 +38,6 @@
  * @author Scott Violet
  */
 public class SynthContext {
-    private static final Queue<SynthContext> queue = new ConcurrentLinkedQueue<>();
 
     private JComponent component;
     private Region region;
@@ -54,19 +51,15 @@
     static SynthContext getContext(JComponent component,
                                    Region region, SynthStyle style,
                                    int state) {
-        SynthContext context = queue.poll();
-        if (context == null) {
-            context = new SynthContext();
-        }
-        context.reset(component, region, style, state);
+        SynthContext context = new SynthContext();
+        context.component = component;
+        context.region = region;
+        context.style = style;
+        context.state = state;
         return context;
     }
 
-    static void releaseContext(SynthContext context) {
-        queue.offer(context);
-    }
-
-    SynthContext() {
+    private SynthContext() {
     }
 
     /**
@@ -86,7 +79,11 @@
             throw new NullPointerException(
                 "You must supply a non-null component, region and style");
         }
-        reset(component, region, style, state);
+
+        this.component = component;
+        this.region = region;
+        this.style = style;
+        this.state = state;
     }
 
 
@@ -147,23 +144,6 @@
     }
 
     /**
-     * Resets the state of the Context.
-     */
-    void reset(JComponent component, Region region, SynthStyle style,
-               int state) {
-        this.component = component;
-        this.region = region;
-        this.style = style;
-        this.state = state;
-    }
-
-    void dispose() {
-        this.component = null;
-        this.style = null;
-        releaseContext(this);
-    }
-
-    /**
      * Convenience method to get the Painter from the current SynthStyle.
      * This will NEVER return null.
      */
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthDefaultLookup.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthDefaultLookup.java	Thu Apr 28 23:08:16 2016 -0700
@@ -41,7 +41,6 @@
         }
         SynthContext context = ((SynthUI)ui).getContext(c);
         Object value = context.getStyle().get(context, key);
-        context.dispose();
         return value;
     }
 }
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthDesktopIconUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthDesktopIconUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -121,7 +121,6 @@
     private void updateStyle(JComponent c) {
         SynthContext context = getContext(c, ENABLED);
         style = SynthLookAndFeel.updateStyle(context, this);
-        context.dispose();
     }
 
     /**
@@ -131,7 +130,6 @@
     protected void uninstallDefaults() {
         SynthContext context = getContext(desktopIcon, ENABLED);
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
     }
 
@@ -171,7 +169,6 @@
         context.getPainter().paintDesktopIconBackground(context, g, 0, 0,
                                                   c.getWidth(), c.getHeight());
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -188,7 +185,6 @@
         SynthContext context = getContext(c);
 
         paint(context, g);
-        context.dispose();
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthDesktopPaneUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthDesktopPaneUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -119,7 +119,6 @@
             uninstallKeyboardActions();
             installKeyboardActions();
         }
-        context.dispose();
     }
 
     /**
@@ -143,7 +142,6 @@
         SynthContext context = getContext(desktop, ENABLED);
 
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
 
         if (taskBar != null) {
@@ -460,7 +458,6 @@
         context.getPainter().paintDesktopPaneBackground(context, g, 0, 0,
                                                   c.getWidth(), c.getHeight());
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -477,7 +474,6 @@
         SynthContext context = getContext(c);
 
         paint(context, g);
-        context.dispose();
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthEditorPaneUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthEditorPaneUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -83,7 +83,6 @@
         c.putClientProperty("caretAspectRatio", null);
 
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
 
         Object clientProperty =
@@ -127,7 +126,6 @@
                 installKeyboardActions();
             }
         }
-        context.dispose();
     }
 
     /**
@@ -165,7 +163,6 @@
         SynthLookAndFeel.update(context, g);
         paintBackground(context, g, c);
         paint(context, g);
-        context.dispose();
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthInternalFrameTitlePane.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthInternalFrameTitlePane.java	Thu Apr 28 23:08:16 2016 -0700
@@ -138,7 +138,6 @@
                 }
             }
         }
-        context.dispose();
     }
 
     protected void installDefaults() {
@@ -149,7 +148,6 @@
     protected void uninstallDefaults() {
         SynthContext context = getContext(this, ENABLED);
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
         JInternalFrame.JDesktopIcon di = frame.getDesktopIcon();
         if(di != null && di.getComponentPopupMenu() == systemPopupMenu) {
@@ -235,7 +233,6 @@
         context.getPainter().paintInternalFrameTitlePaneBackground(context,
                           g, 0, 0, getWidth(), getHeight());
         paint(context, g);
-        context.dispose();
     }
 
     protected void paint(SynthContext context, Graphics g) {
@@ -321,7 +318,6 @@
         SynthContext context = getContext(this);
         LayoutManager lm =
             (LayoutManager)style.get(context, "InternalFrameTitlePane.titlePaneLayout");
-        context.dispose();
         return (lm != null) ? lm : new SynthTitlePaneLayout();
     }
 
@@ -362,7 +358,6 @@
                              Image.SCALE_SMOOTH));
             }
         }
-        context.dispose();
         menuButton.setIcon(frameIcon);
     }
 
@@ -433,7 +428,6 @@
             Insets insets = getInsets();
             height += insets.top + insets.bottom;
             width += insets.left + insets.right;
-            context.dispose();
             return new Dimension(width, height);
         }
 
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthInternalFrameUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthInternalFrameUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -118,7 +118,6 @@
                 installKeyboardActions();
             }
         }
-        context.dispose();
     }
 
     /**
@@ -128,7 +127,6 @@
     protected void uninstallDefaults() {
         SynthContext context = getContext(frame, ENABLED);
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
         if(frame.getLayout() == internalFrameLayout) {
             frame.setLayout(null);
@@ -216,7 +214,6 @@
         context.getPainter().paintInternalFrameBackground(context,
                           g, 0, 0, c.getWidth(), c.getHeight());
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -233,7 +230,6 @@
         SynthContext context = getContext(c);
 
         paint(context, g);
-        context.dispose();
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthLabelUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthLabelUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -67,7 +67,6 @@
     void updateStyle(JLabel c) {
         SynthContext context = getContext(c, ENABLED);
         style = SynthLookAndFeel.updateStyle(context, this);
-        context.dispose();
     }
 
     /**
@@ -78,7 +77,6 @@
         SynthContext context = getContext(c, ENABLED);
 
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
     }
 
@@ -150,7 +148,6 @@
         else {
             baseline = textRect.y + fm.getAscent();
         }
-        context.dispose();
         return baseline;
     }
 
@@ -174,7 +171,6 @@
         context.getPainter().paintLabelBackground(context,
                           g, 0, 0, c.getWidth(), c.getHeight());
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -191,7 +187,6 @@
         SynthContext context = getContext(c);
 
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -242,7 +237,6 @@
                label.getVerticalTextPosition(), label.getIconTextGap(),
                label.getDisplayedMnemonicIndex());
 
-        context.dispose();
         return size;
     }
 
@@ -263,7 +257,6 @@
                label.getVerticalTextPosition(), label.getIconTextGap(),
                label.getDisplayedMnemonicIndex());
 
-        context.dispose();
         return size;
     }
 
@@ -284,7 +277,6 @@
                label.getVerticalTextPosition(), label.getIconTextGap(),
                label.getDisplayedMnemonicIndex());
 
-        context.dispose();
         return size;
     }
 
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthListUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthListUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -75,7 +75,6 @@
         SynthLookAndFeel.update(context, g);
         context.getPainter().paintListBackground(context,
                           g, 0, 0, c.getWidth(), c.getHeight());
-        context.dispose();
         paint(g, c);
     }
 
@@ -162,7 +161,6 @@
                 installKeyboardActions();
             }
         }
-        context.dispose();
     }
 
     /**
@@ -175,7 +173,6 @@
         SynthContext context = getContext(list, ENABLED);
 
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
     }
 
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java	Thu Apr 28 23:08:16 2016 -0700
@@ -976,7 +976,6 @@
                 if (currBG != null && !currBG.equals(lastBG)) {
                     comp.repaint();
                 }
-                context.dispose();
             }
         }
     }
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthMenuBarUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthMenuBarUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -83,7 +83,6 @@
                 installKeyboardActions();
             }
         }
-        context.dispose();
     }
 
     /**
@@ -94,7 +93,6 @@
         SynthContext context = getContext(menuBar, ENABLED);
 
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
     }
 
@@ -143,7 +141,6 @@
         context.getPainter().paintMenuBarBackground(context,
                           g, 0, 0, c.getWidth(), c.getHeight());
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -160,7 +157,6 @@
         SynthContext context = getContext(c);
 
         paint(context, g);
-        context.dispose();
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthMenuItemUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthMenuItemUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -124,13 +124,11 @@
                 installKeyboardActions();
             }
         }
-        context.dispose();
 
         SynthContext accContext = getContext(mi, Region.MENU_ITEM_ACCELERATOR,
                                              ENABLED);
 
         accStyle = SynthLookAndFeel.updateStyle(accContext, this);
-        accContext.dispose();
     }
 
     /**
@@ -140,13 +138,11 @@
     protected void uninstallDefaults() {
         SynthContext context = getContext(menuItem, ENABLED);
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
 
         SynthContext accContext = getContext(menuItem,
                                      Region.MENU_ITEM_ACCELERATOR, ENABLED);
         accStyle.uninstallDefaults(accContext);
-        accContext.dispose();
         accStyle = null;
 
         super.uninstallDefaults();
@@ -218,8 +214,6 @@
                 defaultTextIconGap, acceleratorDelimiter,
                 MenuItemLayoutHelper.useCheckAndArrow(menuItem),
                 getPropertyPrefix());
-        context.dispose();
-        accContext.dispose();
         return value;
     }
 
@@ -243,7 +237,6 @@
         SynthLookAndFeel.update(context, g);
         paintBackground(context, g, c);
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -260,7 +253,6 @@
         SynthContext context = getContext(c);
 
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -280,7 +272,6 @@
         Icon arrowIcon = style.getIcon(context, prefix + ".arrowIcon");
         SynthGraphicsUtils.paint(context, accContext, g, checkIcon, arrowIcon,
               acceleratorDelimiter, defaultTextIconGap, getPropertyPrefix());
-        accContext.dispose();
     }
 
     void paintBackground(SynthContext context, Graphics g, JComponent c) {
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthMenuUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthMenuUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -110,13 +110,11 @@
                 installKeyboardActions();
             }
         }
-        context.dispose();
 
         SynthContext accContext = getContext(mi, Region.MENU_ITEM_ACCELERATOR,
                                              ENABLED);
 
         accStyle = SynthLookAndFeel.updateStyle(accContext, this);
-        accContext.dispose();
     }
 
     /**
@@ -140,13 +138,11 @@
     protected void uninstallDefaults() {
         SynthContext context = getContext(menuItem, ENABLED);
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
 
         SynthContext accContext = getContext(menuItem,
                                      Region.MENU_ITEM_ACCELERATOR, ENABLED);
         accStyle.uninstallDefaults(accContext);
-        accContext.dispose();
         accStyle = null;
 
         super.uninstallDefaults();
@@ -218,8 +214,6 @@
                 defaultTextIconGap, acceleratorDelimiter,
                 MenuItemLayoutHelper.useCheckAndArrow(menuItem),
                 getPropertyPrefix());
-        context.dispose();
-        accContext.dispose();
         return value;
     }
 
@@ -243,7 +237,6 @@
         context.getPainter().paintMenuBackground(context,
                           g, 0, 0, c.getWidth(), c.getHeight());
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -260,7 +253,6 @@
         SynthContext context = getContext(c);
 
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -279,7 +271,6 @@
         Icon arrowIcon = style.getIcon(context, prefix + ".arrowIcon");
         SynthGraphicsUtils.paint(context, accContext, g, checkIcon, arrowIcon,
               acceleratorDelimiter, defaultTextIconGap, getPropertyPrefix());
-        accContext.dispose();
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthOptionPaneUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthOptionPaneUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -88,7 +88,6 @@
                 installKeyboardActions();
             }
         }
-        context.dispose();
     }
 
     /**
@@ -99,7 +98,6 @@
         SynthContext context = getContext(optionPane, ENABLED);
 
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
     }
 
@@ -125,7 +123,6 @@
             SynthContext context = getContext(optionPane, ENABLED);
             optionPane.add(Box.createVerticalStrut(context.getStyle().
                        getInt(context, "OptionPane.separatorPadding", 6)));
-            context.dispose();
         }
         optionPane.add(createButtonArea());
         optionPane.applyComponentOrientation(optionPane.getComponentOrientation());
@@ -167,7 +164,6 @@
         context.getPainter().paintOptionPaneBackground(context,
                           g, 0, 0, c.getWidth(), c.getHeight());
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -184,7 +180,6 @@
         SynthContext context = getContext(c);
 
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -259,7 +254,6 @@
         SynthContext context = getContext(optionPane, ENABLED);
         cons.anchor = context.getStyle().getInt(context,
                       "OptionPane.messageAnchor", GridBagConstraints.CENTER);
-        context.dispose();
 
         cons.insets = new Insets(0,0,3,0);
 
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthPanelUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthPanelUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -108,14 +108,12 @@
         SynthContext context = getContext(p, ENABLED);
 
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
     }
 
     private void updateStyle(JPanel c) {
         SynthContext context = getContext(c, ENABLED);
         style = SynthLookAndFeel.updateStyle(context, this);
-        context.dispose();
     }
 
     /**
@@ -154,7 +152,6 @@
         context.getPainter().paintPanelBackground(context,
                           g, 0, 0, c.getWidth(), c.getHeight());
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -171,7 +168,6 @@
         SynthContext context = getContext(c);
 
         paint(context, g);
-        context.dispose();
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthPopupMenuUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthPopupMenuUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -77,7 +77,6 @@
                 installKeyboardActions();
             }
         }
-        context.dispose();
     }
 
     /**
@@ -97,7 +96,6 @@
         SynthContext context = getContext(popupMenu, ENABLED);
 
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
 
         if (popupMenu.getLayout() instanceof UIResource) {
@@ -150,7 +148,6 @@
         context.getPainter().paintPopupMenuBackground(context,
                           g, 0, 0, c.getWidth(), c.getHeight());
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -167,7 +164,6 @@
         SynthContext context = getContext(c);
 
         paint(context, g);
-        context.dispose();
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthProgressBarUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthProgressBarUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -118,7 +118,6 @@
         }
         minBarSize = (Dimension)style.get(context, "ProgressBar.minBarSize");
         glowWidth = style.getInt(context, "ProgressBar.glowWidth", 0);
-        context.dispose();
     }
 
     /**
@@ -129,7 +128,6 @@
         SynthContext context = getContext(progressBar, ENABLED);
 
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
     }
 
@@ -160,7 +158,6 @@
             SynthContext context = getContext(c);
             Font font = context.getStyle().getFont(context);
             FontMetrics metrics = progressBar.getFontMetrics(font);
-            context.dispose();
             return (height - metrics.getAscent() - metrics.getDescent()) / 2 +
                     metrics.getAscent();
         }
@@ -216,7 +213,6 @@
                           g, 0, 0, c.getWidth(), c.getHeight(),
                           progressBar.getOrientation());
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -233,7 +229,6 @@
         SynthContext context = getContext(c);
 
         paint(context, g);
-        context.dispose();
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthRootPaneUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthRootPaneUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -67,7 +67,6 @@
         SynthContext context = getContext(root, ENABLED);
 
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
     }
 
@@ -97,7 +96,6 @@
                 installKeyboardActions((JRootPane)c);
             }
         }
-        context.dispose();
     }
 
     /**
@@ -120,7 +118,6 @@
         context.getPainter().paintRootPaneBackground(context,
                           g, 0, 0, c.getWidth(), c.getHeight());
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -137,7 +134,6 @@
         SynthContext context = getContext(c);
 
         paint(context, g);
-        context.dispose();
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthScrollBarUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthScrollBarUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -129,15 +129,12 @@
                 installKeyboardActions();
             }
         }
-        context.dispose();
 
         context = getContext(c, Region.SCROLL_BAR_TRACK, ENABLED);
         trackStyle = SynthLookAndFeel.updateStyle(context, this);
-        context.dispose();
 
         context = getContext(c, Region.SCROLL_BAR_THUMB, ENABLED);
         thumbStyle = SynthLookAndFeel.updateStyle(context, this);
-        context.dispose();
     }
 
     /**
@@ -165,17 +162,14 @@
     protected void uninstallDefaults(){
         SynthContext context = getContext(scrollbar, ENABLED);
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
 
         context = getContext(scrollbar, Region.SCROLL_BAR_TRACK, ENABLED);
         trackStyle.uninstallDefaults(context);
-        context.dispose();
         trackStyle = null;
 
         context = getContext(scrollbar, Region.SCROLL_BAR_THUMB, ENABLED);
         thumbStyle.uninstallDefaults(context);
-        context.dispose();
         thumbStyle = null;
 
         super.uninstallDefaults();
@@ -222,7 +216,6 @@
         SynthContext context = getContext(scrollbar);
         boolean value = style.getBoolean(context,
                       "ScrollBar.allowsAbsolutePositioning", false);
-        context.dispose();
         return value;
     }
 
@@ -247,7 +240,6 @@
                           g, 0, 0, c.getWidth(), c.getHeight(),
                           scrollbar.getOrientation());
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -264,7 +256,6 @@
         SynthContext context = getContext(c);
 
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -278,11 +269,9 @@
         SynthContext subcontext = getContext(scrollbar,
                                              Region.SCROLL_BAR_TRACK);
         paintTrack(subcontext, g, getTrackBounds());
-        subcontext.dispose();
 
         subcontext = getContext(scrollbar, Region.SCROLL_BAR_THUMB);
         paintThumb(subcontext, g, getThumbBounds());
-        subcontext.dispose();
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthScrollPaneUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthScrollPaneUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -83,7 +83,6 @@
         context.getPainter().paintScrollPaneBackground(context,
                           g, 0, 0, c.getWidth(), c.getHeight());
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -100,7 +99,6 @@
         SynthContext context = getContext(c);
 
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -150,7 +148,6 @@
                 installKeyboardActions(c);
             }
         }
-        context.dispose();
     }
 
     /**
@@ -178,7 +175,6 @@
         SynthContext context = getContext(c, ENABLED);
 
         style.uninstallDefaults(context);
-        context.dispose();
 
         if (scrollpane.getViewportBorder() instanceof UIResource) {
             scrollpane.setViewportBorder(null);
@@ -254,7 +250,6 @@
             }
             context.getPainter().paintViewportBorder(context, g, x, y, width,
                                                      height);
-            context.dispose();
         }
 
         @Override
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthSeparatorUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthSeparatorUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -106,7 +106,6 @@
             }
         }
 
-        context.dispose();
     }
 
     /**
@@ -120,7 +119,6 @@
         SynthContext context = getContext(c, ENABLED);
 
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
     }
 
@@ -168,7 +166,6 @@
                           g, 0, 0, c.getWidth(), c.getHeight(),
                           separator.getOrientation());
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -185,7 +182,6 @@
         SynthContext context = getContext(c);
 
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -231,7 +227,6 @@
             size = new Dimension(insets.left + insets.right,
                                  insets.top + insets.bottom + thickness);
         }
-        context.dispose();
         return size;
     }
 
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthSliderUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthSliderUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -116,17 +116,14 @@
     protected void uninstallDefaults(JSlider slider) {
         SynthContext context = getContext(slider, ENABLED);
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
 
         context = getContext(slider, Region.SLIDER_TRACK, ENABLED);
         sliderTrackStyle.uninstallDefaults(context);
-        context.dispose();
         sliderTrackStyle = null;
 
         context = getContext(slider, Region.SLIDER_THUMB, ENABLED);
         sliderThumbStyle.uninstallDefaults(context);
-        context.dispose();
         sliderThumbStyle = null;
     }
 
@@ -190,17 +187,14 @@
                 installKeyboardActions(c);
             }
         }
-        context.dispose();
 
         context = getContext(c, Region.SLIDER_TRACK, ENABLED);
         sliderTrackStyle =
             SynthLookAndFeel.updateStyle(context, this);
-        context.dispose();
 
         context = getContext(c, Region.SLIDER_THUMB, ENABLED);
         sliderThumbStyle =
             SynthLookAndFeel.updateStyle(context, this);
-        context.dispose();
     }
 
     /**
@@ -252,14 +246,12 @@
             SynthContext trackContext = getContext(slider,
                                                    Region.SLIDER_TRACK);
             style.getInsets(trackContext, trackInsets);
-            trackContext.dispose();
             if (slider.getOrientation() == JSlider.HORIZONTAL) {
                 int valueHeight = 0;
                 if (paintValue) {
                     SynthContext context = getContext(slider);
                     valueHeight = context.getStyle().getGraphicsUtils(context).
                             getMaximumCharHeight(context);
-                    context.dispose();
                 }
                 int tickHeight = 0;
                 if (slider.getPaintTicks()) {
@@ -287,7 +279,6 @@
                         SynthContext context = getContext(slider);
                         valueHeight = context.getStyle().getGraphicsUtils(
                                 context).getMaximumCharHeight(context);
-                        context.dispose();
                     }
                     int contentHeight = height - insetCache.top -
                             insetCache.bottom;
@@ -359,7 +350,6 @@
         Insets trackInsets = new Insets(0, 0, 0, 0);
         SynthContext trackContext = getContext(slider, Region.SLIDER_TRACK);
         style.getInsets(trackContext, trackInsets);
-        trackContext.dispose();
 
         if (slider.getOrientation() == JSlider.HORIZONTAL) {
             // Calculate the height of all the subcomponents so we can center
@@ -509,7 +499,6 @@
                 trackRect.x = startX + tickRect.width + trackInsets.left;
             }
         }
-        context.dispose();
         lastSize = slider.getSize();
     }
 
@@ -715,7 +704,6 @@
             insetCache = newInsets;
             calculateGeometry();
         }
-        context.dispose();
     }
 
     /**
@@ -774,7 +762,6 @@
                           g, 0, 0, c.getWidth(), c.getHeight(),
                           slider.getOrientation());
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -790,7 +777,6 @@
     public void paint(Graphics g, JComponent c) {
         SynthContext context = getContext(c);
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -835,13 +821,11 @@
         if (slider.getPaintTrack() && clip.intersects(trackRect)) {
             SynthContext subcontext = getContext(slider, Region.SLIDER_TRACK);
             paintTrack(subcontext, g, trackRect);
-            subcontext.dispose();
         }
 
         if (clip.intersects(thumbRect)) {
             SynthContext subcontext = getContext(slider, Region.SLIDER_THUMB);
             paintThumb(subcontext, g, thumbRect);
-            subcontext.dispose();
         }
 
         if (slider.getPaintTicks() && clip.intersects(tickRect)) {
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthSpinnerUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthSpinnerUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -131,7 +131,6 @@
                 installKeyboardActions();
             }
         }
-        context.dispose();
     }
 
 
@@ -151,7 +150,6 @@
         SynthContext context = getContext(spinner, ENABLED);
 
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
     }
 
@@ -301,7 +299,6 @@
         context.getPainter().paintSpinnerBackground(context,
                           g, 0, 0, c.getWidth(), c.getHeight());
         paint(context, g);
-        context.dispose();
     }
 
 
@@ -319,7 +316,6 @@
         SynthContext context = getContext(c);
 
         paint(context, g);
-        context.dispose();
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthSplitPaneDivider.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthSplitPaneDivider.java	Thu Apr 28 23:08:16 2016 -0700
@@ -81,7 +81,6 @@
 
         context.getPainter().paintSplitPaneDividerForeground(context, g, 0, 0,
                 getWidth(), getHeight(), splitPane.getOrientation());
-        context.dispose();
 
         // super.paint(g2);
         for (int counter = 0; counter < getComponentCount(); counter++) {
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthSplitPaneUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthSplitPaneUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -121,7 +121,6 @@
                                           ENABLED);
         SynthStyle oldDividerStyle = dividerStyle;
         dividerStyle = SynthLookAndFeel.updateStyle(context, this);
-        context.dispose();
 
         context = getContext(splitPane, ENABLED);
         SynthStyle oldStyle = style;
@@ -160,7 +159,6 @@
             divider.setBasicSplitPaneUI(this);
             splitPane.add(divider, JSplitPane.DIVIDER);
         }
-        context.dispose();
     }
 
     /**
@@ -180,12 +178,10 @@
         SynthContext context = getContext(splitPane, ENABLED);
 
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
 
         context = getContext(splitPane, Region.SPLIT_PANE_DIVIDER, ENABLED);
         dividerStyle.uninstallDefaults(context);
-        context.dispose();
         dividerStyle = null;
 
         super.uninstallDefaults();
@@ -287,7 +283,6 @@
         context.getPainter().paintSplitPaneBackground(context,
                           g, 0, 0, c.getWidth(), c.getHeight());
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -304,7 +299,6 @@
         SynthContext context = getContext(c);
 
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -338,7 +332,6 @@
         context.getPainter().paintSplitPaneDragDivider(context, g, x, y, w, h,
                                            splitPane.getOrientation());
         g.setClip(oldClip);
-        context.dispose();
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthStyle.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthStyle.java	Thu Apr 28 23:08:16 2016 -0700
@@ -775,7 +775,7 @@
                 if (disabledColor == null || disabledColor instanceof UIResource) {
                     return getColorForState(context, type);
                 }
-            } else if (c instanceof JLabel &&
+            } else if ((c instanceof JLabel || c instanceof JMenuItem) &&
                             (type == ColorType.FOREGROUND ||
                              type == ColorType.TEXT_FOREGROUND)) {
                 return getColorForState(context, type);
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -154,27 +154,17 @@
                 installKeyboardActions();
             }
         }
-        context.dispose();
 
-        if (tabContext != null) {
-            tabContext.dispose();
-        }
         tabContext = getContext(c, Region.TABBED_PANE_TAB, ENABLED);
         this.tabStyle = SynthLookAndFeel.updateStyle(tabContext, this);
         tabInsets = tabStyle.getInsets(tabContext, null);
 
 
-        if (tabAreaContext != null) {
-            tabAreaContext.dispose();
-        }
         tabAreaContext = getContext(c, Region.TABBED_PANE_TAB_AREA, ENABLED);
         this.tabAreaStyle = SynthLookAndFeel.updateStyle(tabAreaContext, this);
         tabAreaInsets = tabAreaStyle.getInsets(tabAreaContext, null);
 
 
-        if (tabContentContext != null) {
-            tabContentContext.dispose();
-        }
         tabContentContext = getContext(c, Region.TABBED_PANE_CONTENT, ENABLED);
         this.tabContentStyle = SynthLookAndFeel.updateStyle(tabContentContext,
                                                             this);
@@ -207,21 +197,17 @@
     protected void uninstallDefaults() {
         SynthContext context = getContext(tabPane, ENABLED);
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
 
         tabStyle.uninstallDefaults(tabContext);
-        tabContext.dispose();
         tabContext = null;
         tabStyle = null;
 
         tabAreaStyle.uninstallDefaults(tabAreaContext);
-        tabAreaContext.dispose();
         tabAreaContext = null;
         tabAreaStyle = null;
 
         tabContentStyle.uninstallDefaults(tabContentContext);
-        tabContentContext.dispose();
         tabContentContext = null;
         tabContentStyle = null;
     }
@@ -374,7 +360,6 @@
         context.getPainter().paintTabbedPaneBackground(context,
                           g, 0, 0, c.getWidth(), c.getHeight());
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -424,7 +409,6 @@
         SynthContext context = getContext(c);
 
         paint(context, g);
-        context.dispose();
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTableHeaderUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTableHeaderUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -85,7 +85,6 @@
                 installKeyboardActions();
             }
         }
-        context.dispose();
     }
 
     /**
@@ -109,7 +108,6 @@
         SynthContext context = getContext(header, ENABLED);
 
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
     }
 
@@ -142,7 +140,6 @@
         context.getPainter().paintTableHeaderBackground(context,
                           g, 0, 0, c.getWidth(), c.getHeight());
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -159,7 +156,6 @@
         SynthContext context = getContext(c);
 
         paint(context, g);
-        context.dispose();
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTableUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTableUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -189,7 +189,6 @@
                 installKeyboardActions();
             }
         }
-        context.dispose();
     }
 
     /**
@@ -220,7 +219,6 @@
         }
         SynthContext context = getContext(table, ENABLED);
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
     }
 
@@ -273,7 +271,6 @@
         context.getPainter().paintTableBackground(context,
                           g, 0, 0, c.getWidth(), c.getHeight());
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -299,7 +296,6 @@
         SynthContext context = getContext(c);
 
         paint(context, g);
-        context.dispose();
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTextAreaUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTextAreaUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -88,7 +88,6 @@
         getComponent().removeFocusListener(handler);
 
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
         super.uninstallDefaults();
     }
@@ -107,7 +106,6 @@
                 installKeyboardActions();
             }
         }
-        context.dispose();
     }
 
     /**
@@ -142,7 +140,6 @@
         context.getPainter().paintTextAreaBackground(context,
                           g, 0, 0, c.getWidth(), c.getHeight());
         paint(context, g);
-        context.dispose();
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTextFieldUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTextFieldUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -79,7 +79,6 @@
                 installKeyboardActions();
             }
         }
-        context.dispose();
     }
 
     static void updateStyle(JTextComponent comp, SynthContext context,
@@ -179,7 +178,6 @@
         SynthLookAndFeel.update(context, g);
         paintBackground(context, g, c);
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -262,7 +260,6 @@
         getComponent().removeFocusListener(handler);
 
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
         super.uninstallDefaults();
     }
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthToolBarUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthToolBarUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -98,11 +98,9 @@
         SynthContext context = getContext(
                 c, Region.TOOL_BAR_CONTENT, null, ENABLED);
         contentStyle = SynthLookAndFeel.updateStyle(context, this);
-        context.dispose();
 
         context = getContext(c, Region.TOOL_BAR_DRAG_WINDOW, null, ENABLED);
         dragWindowStyle = SynthLookAndFeel.updateStyle(context, this);
-        context.dispose();
 
         context = getContext(c, ENABLED);
         SynthStyle oldStyle = style;
@@ -116,7 +114,6 @@
                 installKeyboardActions();
             }
         }
-        context.dispose();
     }
 
     /**
@@ -127,7 +124,6 @@
         SynthContext context = getContext(toolBar, ENABLED);
 
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
 
         handleIcon = null;
@@ -135,13 +131,11 @@
         context = getContext(toolBar, Region.TOOL_BAR_CONTENT,
                              contentStyle, ENABLED);
         contentStyle.uninstallDefaults(context);
-        context.dispose();
         contentStyle = null;
 
         context = getContext(toolBar, Region.TOOL_BAR_DRAG_WINDOW,
                              dragWindowStyle, ENABLED);
         dragWindowStyle.uninstallDefaults(context);
-        context.dispose();
         dragWindowStyle = null;
 
         toolBar.setLayout(null);
@@ -215,7 +209,6 @@
                           g, 0, 0, c.getWidth(), c.getHeight(),
                           toolBar.getOrientation());
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -232,7 +225,6 @@
         SynthContext context = getContext(c);
 
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -289,7 +281,6 @@
         SynthContext subcontext = getContext(
                 toolBar, Region.TOOL_BAR_CONTENT, contentStyle);
         paintContent(subcontext, g, contentRect);
-        subcontext.dispose();
     }
 
     /**
@@ -326,7 +317,6 @@
                                                            dragWindow.getOrientation());
         context.getPainter().paintToolBarDragWindowBorder(context, g, 0, 0, w, h,
                                                           dragWindow.getOrientation());
-        context.dispose();
     }
 
     //
@@ -383,7 +373,6 @@
             dim.width += insets.left + insets.right;
             dim.height += insets.top + insets.bottom;
 
-            context.dispose();
             return dim;
         }
 
@@ -421,7 +410,6 @@
             dim.width += insets.left + insets.right;
             dim.height += insets.top + insets.bottom;
 
-            context.dispose();
             return dim;
         }
 
@@ -543,7 +531,6 @@
                     }
                 }
             }
-            context.dispose();
         }
 
         private boolean isGlue(Component c) {
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthToolTipUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthToolTipUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -68,7 +68,6 @@
     private void updateStyle(JComponent c) {
         SynthContext context = getContext(c, ENABLED);
         style = SynthLookAndFeel.updateStyle(context, this);
-        context.dispose();
     }
 
     /**
@@ -78,7 +77,6 @@
     protected void uninstallDefaults(JComponent c) {
         SynthContext context = getContext(c, ENABLED);
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
     }
 
@@ -139,7 +137,6 @@
         context.getPainter().paintToolTipBackground(context,
                           g, 0, 0, c.getWidth(), c.getHeight());
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -165,7 +162,6 @@
         SynthContext context = getContext(c);
 
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -218,7 +214,6 @@
                 prefSize.height += fm.getHeight();
             }
         }
-        context.dispose();
         return prefSize;
     }
 
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTreeUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTreeUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -147,11 +147,9 @@
                 installKeyboardActions();
             }
         }
-        context.dispose();
 
         context = getContext(tree, Region.TREE_CELL, ENABLED);
         cellStyle = SynthLookAndFeel.updateStyle(context, this);
-        context.dispose();
     }
 
     /**
@@ -223,12 +221,10 @@
         SynthContext context = getContext(tree, ENABLED);
 
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
 
         context = getContext(tree, Region.TREE_CELL, ENABLED);
         cellStyle.uninstallDefaults(context);
-        context.dispose();
         cellStyle = null;
 
 
@@ -266,7 +262,6 @@
         context.getPainter().paintTreeBackground(context,
                           g, 0, 0, c.getWidth(), c.getHeight());
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -292,7 +287,6 @@
         SynthContext context = getContext(c);
 
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -425,7 +419,6 @@
                 row++;
             }
         }
-        cellContext.dispose();
 
         paintDropLine(g);
 
@@ -743,7 +736,6 @@
                     context.getPainter().paintTreeCellFocus(context, g,
                             0, 0, getWidth() - imageOffset, getHeight());
                 }
-                context.dispose();
             }
             SynthLookAndFeel.resetSelectedUI();
         }
@@ -785,7 +777,6 @@
             if (context == null) {
                 context = getContext(tree);
                 SynthGraphicsUtils.paintIcon(expandedIcon, context, g, x, y, w, h);
-                context.dispose();
             }
             else {
                 SynthGraphicsUtils.paintIcon(expandedIcon, context, g, x, y, w, h);
@@ -797,7 +788,6 @@
             if (context == null) {
                 context = getContext(tree);
                 width = SynthGraphicsUtils.getIconWidth(expandedIcon, context);
-                context.dispose();
             }
             else {
                 width = SynthGraphicsUtils.getIconWidth(expandedIcon, context);
@@ -810,7 +800,6 @@
             if (context == null) {
                 context = getContext(tree);
                 height = SynthGraphicsUtils.getIconHeight(expandedIcon, context);
-                context.dispose();
             }
             else {
                 height = SynthGraphicsUtils.getIconHeight(expandedIcon, context);
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthViewportUI.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthViewportUI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -99,7 +99,6 @@
             newStyle.installDefaults(context);
         }
         this.style = newStyle;
-        context.dispose();
     }
 
     /**
@@ -128,7 +127,6 @@
     protected void uninstallDefaults(JComponent c) {
         SynthContext context = getContext(c, ENABLED);
         style.uninstallDefaults(context);
-        context.dispose();
         style = null;
     }
 
@@ -168,7 +166,6 @@
         context.getPainter().paintViewportBackground(context,
                           g, 0, 0, c.getWidth(), c.getHeight());
         paint(context, g);
-        context.dispose();
     }
 
     /**
@@ -202,7 +199,6 @@
         SynthContext context = getContext(c);
 
         paint(context, g);
-        context.dispose();
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/JTextComponent.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/JTextComponent.java	Thu Apr 28 23:08:16 2016 -0700
@@ -70,7 +70,6 @@
 import sun.awt.AppContext;
 
 
-import sun.misc.ManagedLocalsThread;
 import sun.swing.PrintingStatus;
 import sun.swing.SwingUtilities2;
 import sun.swing.text.TextComponentPrintable;
@@ -2353,7 +2352,8 @@
             runnablePrinting.run();
         } else {
             if (isEventDispatchThread) {
-                new ManagedLocalsThread(runnablePrinting).start();
+                new Thread(null, runnablePrinting,
+                           "JTextComponentPrint", 0, false ).start();
                 printingStatus.showModal(true);
             } else {
                 printingStatus.showModal(false);
@@ -2580,7 +2580,7 @@
          * @param e the DocumentEvent
          */
         public void insertUpdate(DocumentEvent e) {
-            final Integer pos = new Integer (e.getOffset());
+            final Integer pos = e.getOffset();
             if (SwingUtilities.isEventDispatchThread()) {
                 firePropertyChange(ACCESSIBLE_TEXT_PROPERTY, null, pos);
             } else {
@@ -2602,7 +2602,7 @@
          * @param e the DocumentEvent
          */
         public void removeUpdate(DocumentEvent e) {
-            final Integer pos = new Integer (e.getOffset());
+            final Integer pos = e.getOffset();
             if (SwingUtilities.isEventDispatchThread()) {
                 firePropertyChange(ACCESSIBLE_TEXT_PROPERTY, null, pos);
             } else {
@@ -2624,7 +2624,7 @@
          * @param e the DocumentEvent
          */
         public void changedUpdate(DocumentEvent e) {
-            final Integer pos = new Integer (e.getOffset());
+            final Integer pos = e.getOffset();
             if (SwingUtilities.isEventDispatchThread()) {
                 firePropertyChange(ACCESSIBLE_TEXT_PROPERTY, null, pos);
             } else {
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/LayoutQueue.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/LayoutQueue.java	Thu Apr 28 23:08:16 2016 -0700
@@ -26,7 +26,6 @@
 
 import java.util.Vector;
 import sun.awt.AppContext;
-import sun.misc.ManagedLocalsThread;
 
 /**
  * A queue of text layout tasks.
@@ -92,7 +91,7 @@
                     }
                 } while (work != null);
             };
-            worker = new ManagedLocalsThread(workerRunnable, "text-layout");
+            worker = new Thread(null, workerRunnable, "text-layout", 0, false);
             worker.setPriority(Thread.MIN_PRIORITY);
             worker.start();
         }
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/NumberFormatter.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/NumberFormatter.java	Thu Apr 28 23:08:16 2016 -0700
@@ -73,7 +73,7 @@
  * type the value class represents. For example:
  * <code>setValueClass(Integer.class)</code> will cause the resulting
  * value to be created via
- * <code>new Integer(((Number)formatter.parseObject(string)).intValue())</code>.
+ * <code>Integer.valueOf(((Number)formatter.parseObject(string)).intValue())</code>.
  * This is typically useful if you
  * wish to set a min/max value as the various <code>Number</code>
  * implementations are generally not comparable to each other. This is also
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/StyleConstants.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/StyleConstants.java	Thu Apr 28 23:08:16 2016 -0700
@@ -608,7 +608,7 @@
      * @param i the value
      */
     public static void setFirstLineIndent(MutableAttributeSet a, float i) {
-        a.addAttribute(FirstLineIndent, new Float(i));
+        a.addAttribute(FirstLineIndent, Float.valueOf(i));
     }
 
     /**
@@ -632,7 +632,7 @@
      * @param i the value
      */
     public static void setRightIndent(MutableAttributeSet a, float i) {
-        a.addAttribute(RightIndent, new Float(i));
+        a.addAttribute(RightIndent, Float.valueOf(i));
     }
 
     /**
@@ -656,7 +656,7 @@
      * @param i the value
      */
     public static void setLeftIndent(MutableAttributeSet a, float i) {
-        a.addAttribute(LeftIndent, new Float(i));
+        a.addAttribute(LeftIndent, Float.valueOf(i));
     }
 
     /**
@@ -680,7 +680,7 @@
      * @param i the value
      */
     public static void setLineSpacing(MutableAttributeSet a, float i) {
-        a.addAttribute(LineSpacing, new Float(i));
+        a.addAttribute(LineSpacing, Float.valueOf(i));
     }
 
     /**
@@ -704,7 +704,7 @@
      * @param i the value
      */
     public static void setSpaceAbove(MutableAttributeSet a, float i) {
-        a.addAttribute(SpaceAbove, new Float(i));
+        a.addAttribute(SpaceAbove, Float.valueOf(i));
     }
 
     /**
@@ -728,7 +728,7 @@
      * @param i the value
      */
     public static void setSpaceBelow(MutableAttributeSet a, float i) {
-        a.addAttribute(SpaceBelow, new Float(i));
+        a.addAttribute(SpaceBelow, Float.valueOf(i));
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/html/CSS.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/html/CSS.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, 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
@@ -1522,8 +1522,16 @@
                 current++;
             }
             last = current;
-            while (current < length && !Character.isWhitespace
-                   (value.charAt(current))) {
+            int inParentheses = 0;
+            char ch;
+            while (current < length && (
+                    !Character.isWhitespace(ch = value.charAt(current))
+                            || inParentheses > 0)) {
+                if (ch == '(') {
+                    inParentheses++;
+                } else if (ch == ')') {
+                    inParentheses--;
+                }
                 current++;
             }
             if (last != current) {
@@ -2556,7 +2564,7 @@
          *   represents the CSS attribute value
          */
         Object toStyleConstants(StyleConstants key, View v) {
-            return new Float(getValue(false));
+            return Float.valueOf(getValue(false));
         }
 
         /** If true, span is a percentage value, and that to determine
@@ -2829,25 +2837,25 @@
         static Hashtable<String, Float> lengthMapping = new Hashtable<String, Float>(6);
         static Hashtable<String, Float> w3cLengthMapping = new Hashtable<String, Float>(6);
         static {
-            lengthMapping.put("pt", new Float(1f));
+            lengthMapping.put("pt", Float.valueOf(1f));
             // Not sure about 1.3, determined by experiementation.
-            lengthMapping.put("px", new Float(1.3f));
-            lengthMapping.put("mm", new Float(2.83464f));
-            lengthMapping.put("cm", new Float(28.3464f));
-            lengthMapping.put("pc", new Float(12f));
-            lengthMapping.put("in", new Float(72f));
+            lengthMapping.put("px", Float.valueOf(1.3f));
+            lengthMapping.put("mm", Float.valueOf(2.83464f));
+            lengthMapping.put("cm", Float.valueOf(28.3464f));
+            lengthMapping.put("pc", Float.valueOf(12f));
+            lengthMapping.put("in", Float.valueOf(72f));
             int res = 72;
             try {
                 res = Toolkit.getDefaultToolkit().getScreenResolution();
             } catch (HeadlessException e) {
             }
             // mapping according to the CSS2 spec
-            w3cLengthMapping.put("pt", new Float(res/72f));
-            w3cLengthMapping.put("px", new Float(1f));
-            w3cLengthMapping.put("mm", new Float(res/25.4f));
-            w3cLengthMapping.put("cm", new Float(res/2.54f));
-            w3cLengthMapping.put("pc", new Float(res/6f));
-            w3cLengthMapping.put("in", new Float(res));
+            w3cLengthMapping.put("pt", Float.valueOf(res/72f));
+            w3cLengthMapping.put("px", Float.valueOf(1f));
+            w3cLengthMapping.put("mm", Float.valueOf(res/25.4f));
+            w3cLengthMapping.put("cm", Float.valueOf(res/2.54f));
+            w3cLengthMapping.put("pc", Float.valueOf(res/6f));
+            w3cLengthMapping.put("in", Float.valueOf((float)res));
         }
 
         LengthUnit(String value, short defaultType, float defaultValue) {
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/rtf/RTFAttributes.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/rtf/RTFAttributes.java	Thu Apr 28 23:08:16 2016 -0700
@@ -357,7 +357,7 @@
         public static NumericAttribute NewTwips(int d, Object s, String r,
                                                 float ds, int dr)
         {
-            return new NumericAttribute(d, s, r, new Float(ds), dr, 20f);
+            return new NumericAttribute(d, s, r, Float.valueOf(ds), dr, 20f);
         }
 
         public static NumericAttribute NewTwips(int d, Object s, String r,
@@ -378,7 +378,7 @@
             if (scale == 1f)
                 swingValue = Integer.valueOf(parameter);
             else
-                swingValue = new Float(parameter / scale);
+                swingValue = Float.valueOf(parameter / scale);
             target.addAttribute(swingName, swingValue);
             return true;
         }
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletClassLoader.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletClassLoader.java	Thu Apr 28 23:08:16 2016 -0700
@@ -52,7 +52,6 @@
 import java.security.PermissionCollection;
 import sun.awt.AppContext;
 import sun.awt.SunToolkit;
-import sun.misc.ManagedLocalsThread;
 import sun.net.www.ParseUtil;
 import sun.security.util.SecurityConstants;
 
@@ -858,13 +857,20 @@
  * this operation to complete before continuing, wait for the notifyAll()
  * operation on the syncObject to occur.
  */
-class AppContextCreator extends ManagedLocalsThread {
+class AppContextCreator extends Thread {
     Object syncObject = new Object();
     AppContext appContext = null;
     volatile boolean created = false;
 
+    /**
+     * Must call the 5-args super-class constructor to erase locals.
+     */
+    private AppContextCreator() {
+        throw new UnsupportedOperationException("Must erase locals");
+    }
+
     AppContextCreator(ThreadGroup group)  {
-        super(group, "AppContextCreator");
+        super(group, null, "AppContextCreator", 0, false);
     }
 
     public void run()  {
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletPanel.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletPanel.java	Thu Apr 28 23:08:16 2016 -0700
@@ -44,7 +44,6 @@
 import sun.awt.EmbeddedFrame;
 import sun.awt.SunToolkit;
 import sun.awt.util.PerformanceLogger;
-import sun.misc.ManagedLocalsThread;
 import sun.security.util.SecurityConstants;
 
 /**
@@ -166,7 +165,7 @@
 
 
         ThreadGroup appletGroup = loader.getThreadGroup();
-        handler = new ManagedLocalsThread(appletGroup, this, "thread " + nm);
+        handler = new Thread(appletGroup, this, "thread " + nm, 0, false);
         // set the context class loader for this thread
         AccessController.doPrivileged(new PrivilegedAction<Object>() {
                 @Override
@@ -396,9 +395,8 @@
                       // until the loader thread terminates.
                       // (one way or another).
                       if (loaderThread == null) {
-                          // REMIND: do we want a name?
-                          //System.out.println("------------------- loading applet");
-                          setLoaderThread(new ManagedLocalsThread(this));
+                          setLoaderThread(new Thread(null, this,
+                                          "AppletLoader", 0, false));
                           loaderThread.start();
                           // we get to go to sleep while this runs
                           loaderThread.join();
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletViewer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletViewer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -38,7 +38,6 @@
 import java.security.PrivilegedAction;
 import sun.awt.SunToolkit;
 import sun.awt.AppContext;
-import sun.misc.ManagedLocalsThread;
 
 /**
  * A frame to show the applet tag in.
@@ -854,7 +853,7 @@
         //
         final AppletPanel p = panel;
 
-        new ManagedLocalsThread(new Runnable()
+        new Thread(null, new Runnable()
         {
             @Override
             public void run()
@@ -867,7 +866,8 @@
                     appletSystemExit();
                 }
             }
-        }).start();
+        },
+        "AppletCloser", 0, false).start();
     }
 
     /**
@@ -890,7 +890,7 @@
         // spawn a new thread to avoid blocking the event queue
         // when calling appletShutdown.
         //
-        new ManagedLocalsThread(new Runnable()
+        new Thread(null, new Runnable()
         {
             @Override
             public void run()
@@ -901,7 +901,8 @@
                 }
                 appletSystemExit();
             }
-        }).start();
+        },
+         "AppletQuit", 0, false).start();
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/sun/awt/AWTAccessor.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/awt/AWTAccessor.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, 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,6 +29,7 @@
 
 import javax.accessibility.AccessibleContext;
 import java.awt.*;
+import java.awt.event.FocusEvent.Cause;
 import java.awt.dnd.DragSourceContext;
 import java.awt.dnd.DropTargetContext;
 import java.awt.dnd.peer.DragSourceContextPeer;
@@ -104,7 +105,7 @@
         /*
          * Requests focus to the component.
          */
-        boolean requestFocus(Component comp, CausedFocusEvent.Cause cause);
+        boolean requestFocus(Component comp, Cause cause);
         /*
          * Determines if the component can gain focus.
          */
@@ -438,7 +439,7 @@
                                            boolean temporary,
                                            boolean focusedWindowChangeAllowed,
                                            long time,
-                                           CausedFocusEvent.Cause cause);
+                                           Cause cause);
         /**
          * Delivers focus for the lightweight descendant of the heavyweight
          * synchronously.
--- a/jdk/src/java.desktop/share/classes/sun/awt/AWTAutoShutdown.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/awt/AWTAutoShutdown.java	Thu Apr 28 23:08:16 2016 -0700
@@ -34,7 +34,6 @@
 import java.util.Set;
 
 import sun.awt.util.ThreadGroupUtils;
-import sun.misc.ManagedLocalsThread;
 import sun.util.logging.PlatformLogger;
 
 /**
@@ -337,8 +336,8 @@
     private void activateBlockerThread() {
         AccessController.doPrivileged((PrivilegedAction<Thread>) () -> {
             String name = "AWT-Shutdown";
-            Thread thread = new ManagedLocalsThread(
-                    ThreadGroupUtils.getRootThreadGroup(), this, name);
+            Thread thread = new Thread(
+                   ThreadGroupUtils.getRootThreadGroup(), this, name, 0, false);
             thread.setContextClassLoader(null);
             thread.setDaemon(false);
             blockerThread = thread;
--- a/jdk/src/java.desktop/share/classes/sun/awt/AppContext.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/awt/AppContext.java	Thu Apr 28 23:08:16 2016 -0700
@@ -46,7 +46,6 @@
 
 import jdk.internal.misc.JavaAWTAccess;
 import jdk.internal.misc.SharedSecrets;
-import sun.misc.ManagedLocalsThread;
 import sun.util.logging.PlatformLogger;
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.Lock;
@@ -598,8 +597,8 @@
         }
 
         public Thread run() {
-            Thread t = new ManagedLocalsThread(appContext.getThreadGroup(),
-                                               runnable, "AppContext Disposer");
+            Thread t = new Thread(appContext.getThreadGroup(),
+                                  runnable, "AppContext Disposer", 0, false);
             t.setContextClassLoader(appContext.getContextClassLoader());
             t.setPriority(Thread.NORM_PRIORITY + 1);
             t.setDaemon(true);
--- a/jdk/src/java.desktop/share/classes/sun/awt/CausedFocusEvent.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/awt/CausedFocusEvent.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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,17 +27,18 @@
 
 import java.awt.event.FocusEvent;
 import java.awt.Component;
+import java.io.ObjectStreamException;
+import java.lang.reflect.Field;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 
 /**
- * This class represents FocusEvents with a known "cause" - reason why this event happened. It can
- * be mouse press, traversal, activation, and so on - all causes are described as Cause enum. The
- * event with the cause can be constructed in two ways - explicitly through constructor of
- * CausedFocusEvent class or implicitly, by calling appropriate requestFocusXXX method with "cause"
- * parameter. The default cause is UNKNOWN.
+ * This class exists for deserialization compatibility only.
  */
-@SuppressWarnings("serial")
-public class CausedFocusEvent extends FocusEvent {
-    public enum Cause {
+class CausedFocusEvent extends FocusEvent {
+    private static final long serialVersionUID = -3647309088427840738L;
+
+    private enum Cause {
         UNKNOWN,
         MOUSE_EVENT,
         TRAVERSAL,
@@ -51,39 +52,82 @@
         NATIVE_SYSTEM,
         ACTIVATION,
         CLEAR_GLOBAL_FOCUS_OWNER,
-        RETARGETED
+        RETARGETED;
     };
 
+    @SuppressWarnings("serial")
+    private static final Component dummy = new Component(){};
+
     private final Cause cause;
 
-    public Cause getCause() {
-        return cause;
-    }
-
-    public String toString() {
-        return "java.awt.FocusEvent[" + super.paramString() + ",cause=" + cause + "] on " + getSource();
-    }
-
-    public CausedFocusEvent(Component source, int id, boolean temporary,
+    private CausedFocusEvent(Component source, int id, boolean temporary,
                             Component opposite, Cause cause) {
         super(source, id, temporary, opposite);
-        if (cause == null) {
-            cause = Cause.UNKNOWN;
-        }
-        this.cause = cause;
+        throw new IllegalStateException();
     }
 
-    /**
-     * Retargets the original focus event to the new target.  If the
-     * original focus event is CausedFocusEvent, it remains such and
-     * cause is copied.  Otherwise, new CausedFocusEvent is created,
-     * with cause as RETARGETED.
-     * @return retargeted event, or null if e is null
-     */
-    public static FocusEvent retarget(FocusEvent e, Component newSource) {
-        if (e == null) return null;
+    Object readResolve() throws ObjectStreamException {
+        FocusEvent.Cause newCause;
+        switch (cause) {
+            case UNKNOWN:
+                newCause = FocusEvent.Cause.UNKNOWN;
+                break;
+            case MOUSE_EVENT:
+                newCause = FocusEvent.Cause.MOUSE_EVENT;
+                break;
+            case TRAVERSAL:
+                newCause = FocusEvent.Cause.TRAVERSAL;
+                break;
+            case TRAVERSAL_UP:
+                newCause = FocusEvent.Cause.TRAVERSAL_UP;
+                break;
+            case TRAVERSAL_DOWN:
+                newCause = FocusEvent.Cause.TRAVERSAL_DOWN;
+                break;
+            case TRAVERSAL_FORWARD:
+                newCause = FocusEvent.Cause.TRAVERSAL_FORWARD;
+                break;
+            case TRAVERSAL_BACKWARD:
+                newCause = FocusEvent.Cause.TRAVERSAL_BACKWARD;
+                break;
+            case ROLLBACK:
+                newCause = FocusEvent.Cause.ROLLBACK;
+                break;
+            case NATIVE_SYSTEM:
+                newCause = FocusEvent.Cause.UNEXPECTED;
+                break;
+            case ACTIVATION:
+                newCause = FocusEvent.Cause.ACTIVATION;
+                break;
+            case CLEAR_GLOBAL_FOCUS_OWNER:
+                newCause = FocusEvent.Cause.CLEAR_GLOBAL_FOCUS_OWNER;
+                break;
+            default:
+                newCause = FocusEvent.Cause.UNKNOWN;
+        }
 
-        return new CausedFocusEvent(newSource, e.getID(), e.isTemporary(), e.getOppositeComponent(),
-                                    (e instanceof CausedFocusEvent) ? ((CausedFocusEvent)e).getCause() : Cause.RETARGETED);
+        FocusEvent focusEvent = new FocusEvent(dummy, getID(), isTemporary(),
+                        getOppositeComponent(), newCause);
+        focusEvent.setSource(null);
+        try {
+            final Field consumedField = FocusEvent.class.getField("consumed");
+            AccessController.doPrivileged(new PrivilegedAction<Object>() {
+                @Override
+                public Object run() {
+                    consumedField.setAccessible(true);
+                    try {
+                        consumedField.set(focusEvent, consumed);
+                    } catch (IllegalAccessException e) {
+                    }
+                    return null;
+                }
+            });
+        } catch (NoSuchFieldException e) {
+        }
+
+        AWTAccessor.AWTEventAccessor accessor =
+                                           AWTAccessor.getAWTEventAccessor();
+        accessor.setBData(focusEvent, accessor.getBData(this));
+        return focusEvent;
     }
 }
--- a/jdk/src/java.desktop/share/classes/sun/awt/KeyboardFocusManagerPeerImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/awt/KeyboardFocusManagerPeerImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -60,8 +60,8 @@
                 focusLog.fine("Clearing global focus owner " + focusOwner);
             }
             if (focusOwner != null) {
-                FocusEvent fl = new CausedFocusEvent(focusOwner, FocusEvent.FOCUS_LOST, false, null,
-                                                     CausedFocusEvent.Cause.CLEAR_GLOBAL_FOCUS_OWNER);
+                FocusEvent fl = new FocusEvent(focusOwner, FocusEvent.FOCUS_LOST, false, null,
+                                                     FocusEvent.Cause.CLEAR_GLOBAL_FOCUS_OWNER);
                 SunToolkit.postPriorityEvent(fl);
             }
         }
@@ -110,7 +110,7 @@
                                        boolean temporary,
                                        boolean focusedWindowChangeAllowed,
                                        long time,
-                                       CausedFocusEvent.Cause cause,
+                                       FocusEvent.Cause cause,
                                        Component currentFocusOwner) // provided by the descendant peers
     {
         if (lightweightChild == null) {
@@ -122,7 +122,7 @@
             currentOwner = null;
         }
         if (currentOwner != null) {
-            FocusEvent fl = new CausedFocusEvent(currentOwner, FocusEvent.FOCUS_LOST,
+            FocusEvent fl = new FocusEvent(currentOwner, FocusEvent.FOCUS_LOST,
                                                  false, lightweightChild, cause);
 
             if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
@@ -131,7 +131,7 @@
             SunToolkit.postEvent(SunToolkit.targetToAppContext(currentOwner), fl);
         }
 
-        FocusEvent fg = new CausedFocusEvent(lightweightChild, FocusEvent.FOCUS_GAINED,
+        FocusEvent fg = new FocusEvent(lightweightChild, FocusEvent.FOCUS_GAINED,
                                              false, currentOwner, cause);
 
         if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
@@ -142,7 +142,7 @@
     }
 
     // WARNING: Don't call it on the Toolkit thread.
-    public static boolean requestFocusFor(Component target, CausedFocusEvent.Cause cause) {
+    public static boolean requestFocusFor(Component target, FocusEvent.Cause cause) {
         return AWTAccessor.getComponentAccessor().requestFocus(target, cause);
     }
 
@@ -152,7 +152,7 @@
                                                      boolean temporary,
                                                      boolean focusedWindowChangeAllowed,
                                                      long time,
-                                                     CausedFocusEvent.Cause cause)
+                                                     FocusEvent.Cause cause)
     {
         return KfmAccessor.instance.shouldNativelyFocusHeavyweight(
             heavyweight, descendant, temporary, focusedWindowChangeAllowed,
--- a/jdk/src/java.desktop/share/classes/sun/awt/NullComponentPeer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/awt/NullComponentPeer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,7 @@
 import java.awt.GraphicsConfiguration;
 import java.awt.Image;
 import java.awt.Insets;
-import java.awt.MenuBar;
+import java.awt.event.FocusEvent.Cause;
 import java.awt.Point;
 import java.awt.Event;
 import java.awt.event.PaintEvent;
@@ -178,7 +178,7 @@
 
     public boolean requestFocus
         (Component lightweightChild, boolean temporary,
-         boolean focusedWindowChangeAllowed, long time, CausedFocusEvent.Cause cause) {
+         boolean focusedWindowChangeAllowed, long time, Cause cause) {
         return false;
     }
 
--- a/jdk/src/java.desktop/share/classes/sun/awt/RequestFocusController.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/awt/RequestFocusController.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016 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,10 +25,11 @@
 package sun.awt;
 
 import java.awt.Component;
+import java.awt.event.FocusEvent.Cause;
 
 public interface RequestFocusController
 {
     public boolean acceptRequestFocus(Component from, Component to,
                                       boolean temporary, boolean focusedWindowChangeAllowed,
-                                      CausedFocusEvent.Cause cause);
+                                      Cause cause);
 }
--- a/jdk/src/java.desktop/share/classes/sun/awt/im/InputMethodManager.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/awt/im/InputMethodManager.java	Thu Apr 28 23:08:16 2016 -0700
@@ -55,7 +55,6 @@
 import java.util.prefs.Preferences;
 import sun.awt.InputMethodSupport;
 import sun.awt.SunToolkit;
-import sun.misc.ManagedLocalsThread;
 
 /**
  * {@code InputMethodManager} is an abstract class that manages the input
@@ -166,7 +165,8 @@
                 // to choose from. Otherwise, just keep the instance.
                 if (imm.hasMultipleInputMethods()) {
                     imm.initialize();
-                    Thread immThread = new ManagedLocalsThread(imm, threadName);
+                    Thread immThread =
+                        new Thread(null, imm, threadName, 0, false);
                     immThread.setDaemon(true);
                     immThread.setPriority(Thread.NORM_PRIORITY + 1);
                     immThread.start();
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/ByteBandedRaster.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/ByteBandedRaster.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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,7 +29,6 @@
 import java.awt.image.RasterFormatException;
 import java.awt.image.SampleModel;
 import java.awt.image.BandedSampleModel;
-import java.awt.image.DataBuffer;
 import java.awt.image.DataBufferByte;
 import java.awt.Rectangle;
 import java.awt.Point;
@@ -74,10 +73,9 @@
      *  @param sampleModel     The SampleModel that specifies the layout.
      *  @param origin          The Point that specifies the origin.
      */
-    public ByteBandedRaster(SampleModel sampleModel,
-                               Point origin) {
+    public ByteBandedRaster(SampleModel sampleModel, Point origin) {
         this(sampleModel,
-             sampleModel.createDataBuffer(),
+             (DataBufferByte) sampleModel.createDataBuffer(),
              new Rectangle(origin.x,
                            origin.y,
                            sampleModel.getWidth(),
@@ -93,12 +91,13 @@
      *  initialized and must be a DataBufferShort compatible with SampleModel.
      *  SampleModel must be of type BandedSampleModel.
      *  @param sampleModel     The SampleModel that specifies the layout.
-     *  @param dataBuffer      The DataBufferShort that contains the image data.
+     *  @param dataBuffer      The DataBufferByte that contains the image data.
      *  @param origin          The Point that specifies the origin.
      */
     public ByteBandedRaster(SampleModel sampleModel,
-                               DataBuffer dataBuffer,
-                               Point origin) {
+                            DataBufferByte dataBuffer,
+                            Point origin)
+    {
         this(sampleModel, dataBuffer,
              new Rectangle(origin.x , origin.y,
                            sampleModel.getWidth(),
@@ -119,39 +118,33 @@
      *  Note that this constructor should generally be called by other
      *  constructors or create methods, it should not be used directly.
      *  @param sampleModel     The SampleModel that specifies the layout.
-     *  @param dataBuffer      The DataBufferShort that contains the image data.
+     *  @param dataBuffer      The DataBufferByte that contains the image data.
      *  @param aRegion         The Rectangle that specifies the image area.
      *  @param origin          The Point that specifies the origin.
      *  @param parent          The parent (if any) of this raster.
      */
     public ByteBandedRaster(SampleModel sampleModel,
-                            DataBuffer dataBuffer,
+                            DataBufferByte dataBuffer,
                             Rectangle aRegion,
                             Point origin,
-                            ByteBandedRaster parent) {
-
+                            ByteBandedRaster parent)
+    {
         super(sampleModel, dataBuffer, aRegion, origin, parent);
         this.maxX = minX + width;
         this.maxY = minY + height;
 
-        if (!(dataBuffer instanceof DataBufferByte)) {
-           throw new RasterFormatException("ByteBandedRaster must have" +
-                "byte DataBuffers");
-        }
-        DataBufferByte dbb = (DataBufferByte)dataBuffer;
-
         if (sampleModel instanceof BandedSampleModel) {
             BandedSampleModel bsm = (BandedSampleModel)sampleModel;
             this.scanlineStride = bsm.getScanlineStride();
             int bankIndices[] = bsm.getBankIndices();
             int bandOffsets[] = bsm.getBandOffsets();
-            int dOffsets[] = dbb.getOffsets();
+            int dOffsets[] = dataBuffer.getOffsets();
             dataOffsets = new int[bankIndices.length];
             data = new byte[bankIndices.length][];
             int xOffset = aRegion.x - origin.x;
             int yOffset = aRegion.y - origin.y;
             for (int i = 0; i < bankIndices.length; i++) {
-               data[i] = stealData(dbb, bankIndices[i]);
+               data[i] = stealData(dataBuffer, bankIndices[i]);
                dataOffsets[i] = dOffsets[bankIndices[i]] +
                    xOffset + yOffset*scanlineStride + bandOffsets[i];
             }
@@ -672,7 +665,7 @@
         int deltaY = y0 - y;
 
         return new ByteBandedRaster(sm,
-                                    dataBuffer,
+                                    (DataBufferByte) dataBuffer,
                                     new Rectangle(x0,y0,width,height),
                                     new Point(sampleModelTranslateX+deltaX,
                                               sampleModelTranslateY+deltaY),
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/ByteComponentRaster.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/ByteComponentRaster.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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,7 +30,6 @@
 import java.awt.image.SampleModel;
 import java.awt.image.ComponentSampleModel;
 import java.awt.image.SinglePixelPackedSampleModel;
-import java.awt.image.DataBuffer;
 import java.awt.image.DataBufferByte;
 import java.awt.Rectangle;
 import java.awt.Point;
@@ -94,7 +93,7 @@
      */
     public ByteComponentRaster(SampleModel sampleModel, Point origin) {
         this(sampleModel,
-             sampleModel.createDataBuffer(),
+             (DataBufferByte) sampleModel.createDataBuffer(),
              new Rectangle(origin.x,
                            origin.y,
                            sampleModel.getWidth(),
@@ -111,12 +110,13 @@
      * SampleModel must be of type SinglePixelPackedSampleModel
      * or ComponentSampleModel.
      * @param sampleModel     The SampleModel that specifies the layout.
-     * @param dataBuffer      The DataBufferShort that contains the image data.
+     * @param dataBuffer      The DataBufferByte that contains the image data.
      * @param origin          The Point that specifies the origin.
      */
     public ByteComponentRaster(SampleModel sampleModel,
-                                  DataBuffer dataBuffer,
-                                  Point origin) {
+                               DataBufferByte dataBuffer,
+                               Point origin)
+    {
         this(sampleModel,
              dataBuffer,
              new Rectangle(origin.x,
@@ -141,33 +141,28 @@
      * Note that this constructor should generally be called by other
      * constructors or create methods, it should not be used directly.
      * @param sampleModel     The SampleModel that specifies the layout.
-     * @param dataBuffer      The DataBufferShort that contains the image data.
+     * @param dataBuffer      The DataBufferByte that contains the image data.
      * @param aRegion         The Rectangle that specifies the image area.
      * @param origin          The Point that specifies the origin.
      * @param parent          The parent (if any) of this raster.
      */
     public ByteComponentRaster(SampleModel sampleModel,
-                                  DataBuffer dataBuffer,
-                                  Rectangle aRegion,
-                                  Point origin,
-                                  ByteComponentRaster parent) {
+                               DataBufferByte dataBuffer,
+                               Rectangle aRegion,
+                               Point origin,
+                               ByteComponentRaster parent)
+    {
         super(sampleModel, dataBuffer, aRegion, origin, parent);
         this.maxX = minX + width;
         this.maxY = minY + height;
 
-        if (!(dataBuffer instanceof DataBufferByte)) {
-            throw new RasterFormatException("ByteComponentRasters must have " +
-                                            "byte DataBuffers");
-        }
-
-        DataBufferByte dbb = (DataBufferByte)dataBuffer;
-        this.data = stealData(dbb, 0);
-        if (dbb.getNumBanks() != 1) {
+        this.data = stealData(dataBuffer, 0);
+        if (dataBuffer.getNumBanks() != 1) {
             throw new
                 RasterFormatException("DataBuffer for ByteComponentRasters"+
                                       " must only have 1 bank.");
         }
-        int dbOffset = dbb.getOffset();
+        int dbOffset = dataBuffer.getOffset();
 
         if (sampleModel instanceof ComponentSampleModel) {
             ComponentSampleModel ism = (ComponentSampleModel)sampleModel;
@@ -823,7 +818,7 @@
         int deltaY = y0 - y;
 
         return new ByteComponentRaster(sm,
-                                       dataBuffer,
+                                       (DataBufferByte) dataBuffer,
                                        new Rectangle(x0, y0, width, height),
                                        new Point(sampleModelTranslateX+deltaX,
                                                  sampleModelTranslateY+deltaY),
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/ByteInterleavedRaster.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/ByteInterleavedRaster.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,6 @@
 import java.awt.image.ComponentSampleModel;
 import java.awt.image.PixelInterleavedSampleModel;
 import java.awt.image.SinglePixelPackedSampleModel;
-import java.awt.image.DataBuffer;
 import java.awt.image.DataBufferByte;
 import java.awt.Rectangle;
 import java.awt.Point;
@@ -87,7 +86,7 @@
      */
     public ByteInterleavedRaster(SampleModel sampleModel, Point origin) {
         this(sampleModel,
-             sampleModel.createDataBuffer(),
+             (DataBufferByte) sampleModel.createDataBuffer(),
              new Rectangle(origin.x,
                            origin.y,
                            sampleModel.getWidth(),
@@ -104,12 +103,13 @@
      * SampleModel must be of type SinglePixelPackedSampleModel
      * or InterleavedSampleModel.
      * @param sampleModel     The SampleModel that specifies the layout.
-     * @param dataBuffer      The DataBufferShort that contains the image data.
+     * @param dataBuffer      The DataBufferByte that contains the image data.
      * @param origin          The Point that specifies the origin.
      */
     public ByteInterleavedRaster(SampleModel sampleModel,
-                                  DataBuffer dataBuffer,
-                                  Point origin) {
+                                 DataBufferByte dataBuffer,
+                                 Point origin)
+    {
         this(sampleModel,
              dataBuffer,
              new Rectangle(origin.x,
@@ -178,27 +178,22 @@
      * Note that this constructor should generally be called by other
      * constructors or create methods, it should not be used directly.
      * @param sampleModel     The SampleModel that specifies the layout.
-     * @param dataBuffer      The DataBufferShort that contains the image data.
+     * @param dataBuffer      The DataBufferByte that contains the image data.
      * @param aRegion         The Rectangle that specifies the image area.
      * @param origin          The Point that specifies the origin.
      * @param parent          The parent (if any) of this raster.
      */
     public ByteInterleavedRaster(SampleModel sampleModel,
-                                  DataBuffer dataBuffer,
-                                  Rectangle aRegion,
-                                  Point origin,
-                                  ByteInterleavedRaster parent) {
+                                 DataBufferByte dataBuffer,
+                                 Rectangle aRegion,
+                                 Point origin,
+                                 ByteInterleavedRaster parent)
+    {
         super(sampleModel, dataBuffer, aRegion, origin, parent);
         this.maxX = minX + width;
         this.maxY = minY + height;
 
-        if (!(dataBuffer instanceof DataBufferByte)) {
-            throw new RasterFormatException("ByteInterleavedRasters must have " +
-                                            "byte DataBuffers");
-        }
-
-        DataBufferByte dbb = (DataBufferByte)dataBuffer;
-        this.data = stealData(dbb, 0);
+        this.data = stealData(dataBuffer, 0);
 
         int xOffset = aRegion.x - origin.x;
         int yOffset = aRegion.y - origin.y;
@@ -221,7 +216,7 @@
             this.scanlineStride = sppsm.getScanlineStride();
             this.pixelStride = 1;
             this.dataOffsets = new int[1];
-            this.dataOffsets[0] = dbb.getOffset();
+            this.dataOffsets[0] = dataBuffer.getOffset();
             dataOffsets[0] += xOffset*pixelStride+yOffset*scanlineStride;
         } else {
             throw new RasterFormatException("ByteInterleavedRasters must " +
@@ -1259,7 +1254,7 @@
         int deltaY = y0 - y;
 
         return new ByteInterleavedRaster(sm,
-                                       dataBuffer,
+                                       (DataBufferByte) dataBuffer,
                                        new Rectangle(x0, y0, width, height),
                                        new Point(sampleModelTranslateX+deltaX,
                                                  sampleModelTranslateY+deltaY),
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/BytePackedRaster.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/BytePackedRaster.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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,7 +29,6 @@
 import java.awt.image.RasterFormatException;
 import java.awt.image.SampleModel;
 import java.awt.image.MultiPixelPackedSampleModel;
-import java.awt.image.DataBuffer;
 import java.awt.image.DataBufferByte;
 import java.awt.Rectangle;
 import java.awt.Point;
@@ -89,10 +88,9 @@
      * @param sampleModel     The SampleModel that specifies the layout.
      * @param origin          The Point that specified the origin.
      */
-    public BytePackedRaster(SampleModel sampleModel,
-                            Point origin) {
+    public BytePackedRaster(SampleModel sampleModel, Point origin) {
         this(sampleModel,
-             sampleModel.createDataBuffer(),
+             (DataBufferByte) sampleModel.createDataBuffer(),
              new Rectangle(origin.x,
                            origin.y,
                            sampleModel.getWidth(),
@@ -108,12 +106,13 @@
      * initialized and must be a DataBufferByte compatible with SampleModel.
      * SampleModel must be of type MultiPixelPackedSampleModel.
      * @param sampleModel     The SampleModel that specifies the layout.
-     * @param dataBuffer      The DataBufferShort that contains the image data.
+     * @param dataBuffer      The DataBufferByte that contains the image data.
      * @param origin          The Point that specifies the origin.
      */
     public BytePackedRaster(SampleModel sampleModel,
-                            DataBuffer dataBuffer,
-                            Point origin) {
+                            DataBufferByte dataBuffer,
+                            Point origin)
+    {
         this(sampleModel,
              dataBuffer,
              new Rectangle(origin.x,
@@ -137,7 +136,7 @@
      * Note that this constructor should generally be called by other
      * constructors or create methods, it should not be used directly.
      * @param sampleModel     The SampleModel that specifies the layout.
-     * @param dataBuffer      The DataBufferShort that contains the image data.
+     * @param dataBuffer      The DataBufferByte that contains the image data.
      * @param aRegion         The Rectangle that specifies the image area.
      * @param origin          The Point that specifies the origin.
      * @param parent          The parent (if any) of this raster.
@@ -146,26 +145,22 @@
      * to requirements of this Raster type.
      */
     public BytePackedRaster(SampleModel sampleModel,
-                            DataBuffer dataBuffer,
+                            DataBufferByte dataBuffer,
                             Rectangle aRegion,
                             Point origin,
-                            BytePackedRaster parent){
+                            BytePackedRaster parent)
+    {
         super(sampleModel,dataBuffer,aRegion,origin, parent);
         this.maxX = minX + width;
         this.maxY = minY + height;
 
-        if (!(dataBuffer instanceof DataBufferByte)) {
-           throw new RasterFormatException("BytePackedRasters must have" +
-                "byte DataBuffers");
-        }
-        DataBufferByte dbb = (DataBufferByte)dataBuffer;
-        this.data = stealData(dbb, 0);
-        if (dbb.getNumBanks() != 1) {
+        this.data = stealData(dataBuffer, 0);
+        if (dataBuffer.getNumBanks() != 1) {
             throw new
                 RasterFormatException("DataBuffer for BytePackedRasters"+
                                       " must only have 1 bank.");
         }
-        int dbOffset = dbb.getOffset();
+        int dbOffset = dataBuffer.getOffset();
 
         if (sampleModel instanceof MultiPixelPackedSampleModel) {
             MultiPixelPackedSampleModel mppsm =
@@ -1322,7 +1317,7 @@
         int deltaY = y0 - y;
 
         return new BytePackedRaster(sm,
-                                    dataBuffer,
+                                    (DataBufferByte) dataBuffer,
                                     new Rectangle(x0, y0, width, height),
                                     new Point(sampleModelTranslateX+deltaX,
                                               sampleModelTranslateY+deltaY),
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/ImageFetcher.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/ImageFetcher.java	Thu Apr 28 23:08:16 2016 -0700
@@ -27,7 +27,6 @@
 
 import java.util.Vector;
 import sun.awt.AppContext;
-import sun.misc.ManagedLocalsThread;
 
 /**
   * An ImageFetcher is a thread used to fetch ImageFetchable objects.
@@ -42,7 +41,7 @@
   * @author Jim Graham
   * @author Fred Ecks
   */
-class ImageFetcher extends ManagedLocalsThread {
+class ImageFetcher extends Thread {
     static final int HIGH_PRIORITY = 8;
     static final int LOW_PRIORITY = 3;
     static final int ANIM_PRIORITY = 2;
@@ -52,10 +51,17 @@
                                      // queue before an ImageFetcher dies
 
     /**
+     * We must only call the 5 args super() constructor passing
+     * in "false" to indicate to not inherit locals.
+     */
+    private ImageFetcher() {
+        throw new UnsupportedOperationException("Must erase locals");
+    }
+    /**
       * Constructor for ImageFetcher -- only called by add() below.
       */
     private ImageFetcher(ThreadGroup threadGroup, int index) {
-        super(threadGroup, "Image Fetcher " + index);
+        super(threadGroup, null, "Image Fetcher " + index, 0, false);
         setDaemon(true);
     }
 
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/IntegerComponentRaster.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/IntegerComponentRaster.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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,7 +29,6 @@
 import java.awt.image.RasterFormatException;
 import java.awt.image.SampleModel;
 import java.awt.image.SinglePixelPackedSampleModel;
-import java.awt.image.DataBuffer;
 import java.awt.image.DataBufferInt;
 import java.awt.Rectangle;
 import java.awt.Point;
@@ -107,10 +106,9 @@
      *  @param sampleModel     The SampleModel that specifies the layout.
      *  @param origin          The Point that specified the origin.
      */
-    public IntegerComponentRaster(SampleModel sampleModel,
-                                     Point origin) {
+    public IntegerComponentRaster(SampleModel sampleModel, Point origin) {
         this(sampleModel,
-             sampleModel.createDataBuffer(),
+             (DataBufferInt) sampleModel.createDataBuffer(),
              new Rectangle(origin.x,
                            origin.y,
                            sampleModel.getWidth(),
@@ -130,8 +128,9 @@
      * @param origin          The Point that specifies the origin.
      */
     public IntegerComponentRaster(SampleModel sampleModel,
-                                     DataBuffer dataBuffer,
-                                     Point origin) {
+                                  DataBufferInt dataBuffer,
+                                  Point origin)
+    {
         this(sampleModel,
              dataBuffer,
              new Rectangle(origin.x,
@@ -161,24 +160,21 @@
      * @param parent          The parent (if any) of this raster.
      */
     public IntegerComponentRaster(SampleModel sampleModel,
-                                     DataBuffer dataBuffer,
-                                     Rectangle aRegion,
-                                     Point origin,
-                                     IntegerComponentRaster parent){
+                                  DataBufferInt dataBuffer,
+                                  Rectangle aRegion,
+                                  Point origin,
+                                  IntegerComponentRaster parent)
+    {
         super(sampleModel,dataBuffer,aRegion,origin,parent);
         this.maxX = minX + width;
         this.maxY = minY + height;
-        if (!(dataBuffer instanceof DataBufferInt)) {
-           throw new RasterFormatException("IntegerComponentRasters must have" +
-                "integer DataBuffers");
-        }
-        DataBufferInt dbi = (DataBufferInt)dataBuffer;
-        if (dbi.getNumBanks() != 1) {
+
+        if (dataBuffer.getNumBanks() != 1) {
             throw new
                 RasterFormatException("DataBuffer for IntegerComponentRasters"+
                                       " must only have 1 bank.");
         }
-        this.data = stealData(dbi, 0);
+        this.data = stealData(dataBuffer, 0);
 
         if (sampleModel instanceof SinglePixelPackedSampleModel) {
             SinglePixelPackedSampleModel sppsm =
@@ -197,7 +193,7 @@
             this.scanlineStride = sppsm.getScanlineStride();
             this.pixelStride    = 1;
             this.dataOffsets = new int[1];
-            this.dataOffsets[0] = dbi.getOffset();
+            this.dataOffsets[0] = dataBuffer.getOffset();
             this.bandOffset = this.dataOffsets[0];
             int xOffset = aRegion.x - origin.x;
             int yOffset = aRegion.y - origin.y;
@@ -569,7 +565,7 @@
         int deltaY = y0 - y;
 
         return new IntegerComponentRaster(sm,
-                                          dataBuffer,
+                                          (DataBufferInt) dataBuffer,
                                           new Rectangle(x0,y0,width,height),
                                           new Point(sampleModelTranslateX+deltaX,
                                                     sampleModelTranslateY+deltaY),
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/IntegerInterleavedRaster.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/IntegerInterleavedRaster.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, 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,7 +29,6 @@
 import java.awt.image.RasterFormatException;
 import java.awt.image.SampleModel;
 import java.awt.image.SinglePixelPackedSampleModel;
-import java.awt.image.DataBuffer;
 import java.awt.image.DataBufferInt;
 import java.awt.Rectangle;
 import java.awt.Point;
@@ -67,10 +66,9 @@
      *  @param sampleModel     The SampleModel that specifies the layout.
      *  @param origin          The Point that specified the origin.
      */
-    public IntegerInterleavedRaster(SampleModel sampleModel,
-                                     Point origin) {
+    public IntegerInterleavedRaster(SampleModel sampleModel, Point origin) {
         this(sampleModel,
-             sampleModel.createDataBuffer(),
+             (DataBufferInt) sampleModel.createDataBuffer(),
              new Rectangle(origin.x,
                            origin.y,
                            sampleModel.getWidth(),
@@ -90,8 +88,9 @@
      * @param origin          The Point that specifies the origin.
      */
     public IntegerInterleavedRaster(SampleModel sampleModel,
-                                     DataBuffer dataBuffer,
-                                     Point origin) {
+                                    DataBufferInt dataBuffer,
+                                    Point origin)
+    {
         this(sampleModel,
              dataBuffer,
              new Rectangle(origin.x,
@@ -121,19 +120,16 @@
      * @param parent          The parent (if any) of this raster.
      */
     public IntegerInterleavedRaster(SampleModel sampleModel,
-                                     DataBuffer dataBuffer,
-                                     Rectangle aRegion,
-                                     Point origin,
-                                     IntegerInterleavedRaster parent){
+                                    DataBufferInt dataBuffer,
+                                    Rectangle aRegion,
+                                    Point origin,
+                                    IntegerInterleavedRaster parent)
+    {
         super(sampleModel,dataBuffer,aRegion,origin,parent);
         this.maxX = minX + width;
         this.maxY = minY + height;
-        if (!(dataBuffer instanceof DataBufferInt)) {
-           throw new RasterFormatException("IntegerInterleavedRasters must have" +
-                "integer DataBuffers");
-        }
-        DataBufferInt dbi = (DataBufferInt)dataBuffer;
-        this.data = stealData(dbi, 0);
+
+        this.data = stealData(dataBuffer, 0);
 
         if (sampleModel instanceof SinglePixelPackedSampleModel) {
             SinglePixelPackedSampleModel sppsm =
@@ -141,7 +137,7 @@
             this.scanlineStride = sppsm.getScanlineStride();
             this.pixelStride    = 1;
             this.dataOffsets = new int[1];
-            this.dataOffsets[0] = dbi.getOffset();
+            this.dataOffsets[0] = dataBuffer.getOffset();
             this.bandOffset = this.dataOffsets[0];
             int xOffset = aRegion.x - origin.x;
             int yOffset = aRegion.y - origin.y;
@@ -481,7 +477,7 @@
         int deltaY = y0 - y;
 
         return new IntegerInterleavedRaster(sm,
-                                          dataBuffer,
+                                          (DataBufferInt) dataBuffer,
                                           new Rectangle(x0,y0,width,height),
                                           new Point(sampleModelTranslateX+deltaX,
                                                     sampleModelTranslateY+deltaY),
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/PNGImageDecoder.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/PNGImageDecoder.java	Thu Apr 28 23:08:16 2016 -0700
@@ -87,7 +87,7 @@
         properties.put(key,value);
     }
     private void property(String key,float value) {
-        property(key,new Float(value));
+        property(key, Float.valueOf(value));
     }
     private final void pngassert(boolean b) throws IOException {
         if(!b) {
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/ShortBandedRaster.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/ShortBandedRaster.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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,7 +29,6 @@
 import java.awt.image.RasterFormatException;
 import java.awt.image.SampleModel;
 import java.awt.image.BandedSampleModel;
-import java.awt.image.DataBuffer;
 import java.awt.image.DataBufferUShort;
 import java.awt.Rectangle;
 import java.awt.Point;
@@ -72,10 +71,9 @@
      * @param sampleModel     The SampleModel that specifies the layout.
      * @param origin          The Point that specified the origin.
      */
-    public ShortBandedRaster(SampleModel sampleModel,
-                                Point origin) {
+    public ShortBandedRaster(SampleModel sampleModel, Point origin) {
         this(sampleModel,
-             sampleModel.createDataBuffer(),
+             (DataBufferUShort) sampleModel.createDataBuffer(),
              new Rectangle(origin.x,
                            origin.y,
                            sampleModel.getWidth(),
@@ -95,8 +93,9 @@
      * @param origin          The Point that specifies the origin.
      */
     public ShortBandedRaster(SampleModel sampleModel,
-                                DataBuffer dataBuffer,
-                                Point origin) {
+                             DataBufferUShort dataBuffer,
+                             Point origin)
+    {
         this(sampleModel, dataBuffer,
              new Rectangle(origin.x, origin.y,
                            sampleModel.getWidth(),
@@ -123,32 +122,27 @@
      * @param parent          The parent (if any) of this raster.
      */
     public ShortBandedRaster(SampleModel sampleModel,
-                                DataBuffer dataBuffer,
-                                Rectangle aRegion,
-                                Point origin,
-                                ShortBandedRaster parent) {
-
+                             DataBufferUShort dataBuffer,
+                             Rectangle aRegion,
+                             Point origin,
+                             ShortBandedRaster parent)
+    {
         super(sampleModel, dataBuffer, aRegion, origin, parent);
         this.maxX = minX + width;
         this.maxY = minY + height;
-        if (!(dataBuffer instanceof DataBufferUShort)) {
-           throw new RasterFormatException("ShortBandedRaster must have " +
-                "ushort DataBuffers");
-        }
-        DataBufferUShort dbus = (DataBufferUShort)dataBuffer;
 
         if (sampleModel instanceof BandedSampleModel) {
             BandedSampleModel bsm = (BandedSampleModel)sampleModel;
             this.scanlineStride = bsm.getScanlineStride();
             int bankIndices[] = bsm.getBankIndices();
             int bandOffsets[] = bsm.getBandOffsets();
-            int dOffsets[] = dbus.getOffsets();
+            int dOffsets[] = dataBuffer.getOffsets();
             dataOffsets = new int[bankIndices.length];
             data = new short[bankIndices.length][];
             int xOffset = aRegion.x - origin.x;
             int yOffset = aRegion.y - origin.y;
             for (int i = 0; i < bankIndices.length; i++) {
-               data[i] = stealData(dbus, bankIndices[i]);
+               data[i] = stealData(dataBuffer, bankIndices[i]);
                dataOffsets[i] = dOffsets[bankIndices[i]] +
                    xOffset + yOffset*scanlineStride + bandOffsets[i];
             }
@@ -670,7 +664,7 @@
         int deltaY = y0 - y;
 
         return new ShortBandedRaster(sm,
-                                     dataBuffer,
+                                     (DataBufferUShort) dataBuffer,
                                      new Rectangle(x0, y0, width, height),
                                      new Point(sampleModelTranslateX+deltaX,
                                                sampleModelTranslateY+deltaY),
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/ShortComponentRaster.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/ShortComponentRaster.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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,7 +30,6 @@
 import java.awt.image.SampleModel;
 import java.awt.image.ComponentSampleModel;
 import java.awt.image.SinglePixelPackedSampleModel;
-import java.awt.image.DataBuffer;
 import java.awt.image.DataBufferUShort;
 import java.awt.Rectangle;
 import java.awt.Point;
@@ -94,7 +93,7 @@
      */
     public ShortComponentRaster(SampleModel sampleModel, Point origin) {
         this(sampleModel,
-             sampleModel.createDataBuffer(),
+             (DataBufferUShort) sampleModel.createDataBuffer(),
              new Rectangle(origin.x,
                            origin.y,
                            sampleModel.getWidth(),
@@ -115,8 +114,9 @@
      * @param origin          The Point that specifies the origin.
      */
     public ShortComponentRaster(SampleModel sampleModel,
-                                   DataBuffer dataBuffer,
-                                   Point origin) {
+                                DataBufferUShort dataBuffer,
+                                Point origin)
+    {
         this(sampleModel,
              dataBuffer,
              new Rectangle(origin.x,
@@ -146,28 +146,22 @@
      * @param parent          The parent (if any) of this raster.
      */
     public ShortComponentRaster(SampleModel sampleModel,
-                                   DataBuffer dataBuffer,
-                                   Rectangle aRegion,
-                                   Point origin,
-                                   ShortComponentRaster parent) {
-
+                                DataBufferUShort dataBuffer,
+                                Rectangle aRegion,
+                                Point origin,
+                                ShortComponentRaster parent)
+    {
         super(sampleModel, dataBuffer, aRegion, origin, parent);
         this.maxX = minX + width;
         this.maxY = minY + height;
 
-        if(!(dataBuffer instanceof DataBufferUShort)) {
-            throw new RasterFormatException("ShortComponentRasters must have "+
-                                            "short DataBuffers");
-        }
-
-        DataBufferUShort dbus = (DataBufferUShort)dataBuffer;
-        this.data = stealData(dbus, 0);
-        if (dbus.getNumBanks() != 1) {
+        this.data = stealData(dataBuffer, 0);
+        if (dataBuffer.getNumBanks() != 1) {
             throw new
                 RasterFormatException("DataBuffer for ShortComponentRasters"+
                                       " must only have 1 bank.");
         }
-        int dbOffset = dbus.getOffset();
+        int dbOffset = dataBuffer.getOffset();
 
         if (sampleModel instanceof ComponentSampleModel) {
             ComponentSampleModel csm = (ComponentSampleModel)sampleModel;
@@ -758,7 +752,7 @@
         int deltaY = y0 - y;
 
         return new ShortComponentRaster(sm,
-                                       dataBuffer,
+                                       (DataBufferUShort) dataBuffer,
                                        new Rectangle(x0, y0, width, height),
                                        new Point(sampleModelTranslateX+deltaX,
                                                  sampleModelTranslateY+deltaY),
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/ShortInterleavedRaster.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/ShortInterleavedRaster.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,6 @@
 import java.awt.image.ComponentSampleModel;
 import java.awt.image.PixelInterleavedSampleModel;
 import java.awt.image.SinglePixelPackedSampleModel;
-import java.awt.image.DataBuffer;
 import java.awt.image.DataBufferUShort;
 import java.awt.Rectangle;
 import java.awt.Point;
@@ -71,7 +70,7 @@
      */
     public ShortInterleavedRaster(SampleModel sampleModel, Point origin) {
         this(sampleModel,
-             sampleModel.createDataBuffer(),
+             (DataBufferUShort) sampleModel.createDataBuffer(),
              new Rectangle(origin.x,
                            origin.y,
                            sampleModel.getWidth(),
@@ -92,8 +91,9 @@
      * @param origin          The Point that specifies the origin.
      */
     public ShortInterleavedRaster(SampleModel sampleModel,
-                                   DataBuffer dataBuffer,
-                                   Point origin) {
+                                  DataBufferUShort dataBuffer,
+                                  Point origin)
+    {
         this(sampleModel,
              dataBuffer,
              new Rectangle(origin.x,
@@ -123,22 +123,17 @@
      * @param parent          The parent (if any) of this raster.
      */
     public ShortInterleavedRaster(SampleModel sampleModel,
-                                   DataBuffer dataBuffer,
-                                   Rectangle aRegion,
-                                   Point origin,
-                                   ShortInterleavedRaster parent) {
+                                  DataBufferUShort dataBuffer,
+                                  Rectangle aRegion,
+                                  Point origin,
+                                  ShortInterleavedRaster parent)
+    {
 
         super(sampleModel, dataBuffer, aRegion, origin, parent);
         this.maxX = minX + width;
         this.maxY = minY + height;
 
-        if(!(dataBuffer instanceof DataBufferUShort)) {
-            throw new RasterFormatException("ShortInterleavedRasters must "+
-                                            "have ushort DataBuffers");
-        }
-
-        DataBufferUShort dbus = (DataBufferUShort)dataBuffer;
-        this.data = stealData(dbus, 0);
+        this.data = stealData(dataBuffer, 0);
 
         // REMIND: need case for interleaved ComponentSampleModel
         if ((sampleModel instanceof PixelInterleavedSampleModel) ||
@@ -160,7 +155,7 @@
             this.scanlineStride = sppsm.getScanlineStride();
             this.pixelStride    = 1;
             this.dataOffsets = new int[1];
-            this.dataOffsets[0] = dbus.getOffset();
+            this.dataOffsets[0] = dataBuffer.getOffset();
             int xOffset = aRegion.x - origin.x;
             int yOffset = aRegion.y - origin.y;
             dataOffsets[0] += xOffset+yOffset*scanlineStride;
@@ -730,7 +725,7 @@
         int deltaY = y0 - y;
 
         return new ShortInterleavedRaster(sm,
-                                       dataBuffer,
+                                       (DataBufferUShort) dataBuffer,
                                        new Rectangle(x0, y0, width, height),
                                        new Point(sampleModelTranslateX+deltaX,
                                                  sampleModelTranslateY+deltaY),
--- a/jdk/src/java.desktop/share/classes/sun/font/CreatedFontTracker.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/font/CreatedFontTracker.java	Thu Apr 28 23:08:16 2016 -0700
@@ -36,7 +36,6 @@
 
 import sun.awt.AppContext;
 import sun.awt.util.ThreadGroupUtils;
-import sun.misc.ManagedLocalsThread;
 
 public class CreatedFontTracker {
 
@@ -122,8 +121,8 @@
                      * Make its parent the top-level thread group.
                      */
                     ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
-                    t = new ManagedLocalsThread(rootTG,
-                                                TempFileDeletionHook::runHooks);
+                    t = new Thread(rootTG, TempFileDeletionHook::runHooks,
+                                   "TempFontFileDeleter", 0, false);
                     /* Set context class loader to null in order to avoid
                      * keeping a strong reference to an application classloader.
                      */
--- a/jdk/src/java.desktop/share/classes/sun/font/FontUtilities.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/font/FontUtilities.java	Thu Apr 28 23:08:16 2016 -0700
@@ -183,6 +183,25 @@
     }
 
     /**
+     * Return true if there any characters which would trigger layout.
+     * This method considers supplementary characters to be simple,
+     * since we do not presently invoke layout on any code points in
+     * outside the BMP.
+     */
+    public static boolean isComplexScript(char [] chs, int start, int limit) {
+
+        for (int i = start; i < limit; i++) {
+            if (chs[i] < MIN_LAYOUT_CHARCODE) {
+                continue;
+            }
+            else if (isComplexCharCode(chs[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
      * If there is anything in the text which triggers a case
      * where char->glyph does not map 1:1 in straightforward
      * left->right ordering, then this method returns true.
--- a/jdk/src/java.desktop/share/classes/sun/font/SunFontManager.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/font/SunFontManager.java	Thu Apr 28 23:08:16 2016 -0700
@@ -55,7 +55,6 @@
 import sun.awt.SunToolkit;
 import sun.awt.util.ThreadGroupUtils;
 import sun.java2d.FontSupport;
-import sun.misc.ManagedLocalsThread;
 import sun.util.logging.PlatformLogger;
 
 /**
@@ -1844,7 +1843,7 @@
 
     private PhysicalFont registerFontFile(String file) {
         if (new File(file).isAbsolute() &&
-            !registeredFonts.contains(file)) {
+            !registeredFonts.containsKey(file)) {
             int fontFormat = FONTFORMAT_NONE;
             int fontRank = Font2D.UNKNOWN_RANK;
             if (ttFilter.accept(null, file)) {
@@ -2513,8 +2512,8 @@
                     };
                     AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
                         ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
-                        fileCloser = new ManagedLocalsThread(rootTG,
-                                                             fileCloserRunnable);
+                        fileCloser = new Thread(rootTG, fileCloserRunnable,
+                                                "FileCloser", 0, false);
                         fileCloser.setContextClassLoader(null);
                         Runtime.getRuntime().addShutdownHook(fileCloser);
                         return null;
--- a/jdk/src/java.desktop/share/classes/sun/java2d/Disposer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/Disposer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -26,7 +26,6 @@
 package sun.java2d;
 
 import sun.awt.util.ThreadGroupUtils;
-import sun.misc.ManagedLocalsThread;
 
 import java.lang.ref.Reference;
 import java.lang.ref.ReferenceQueue;
@@ -85,7 +84,7 @@
         AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
             String name = "Java2D Disposer";
             ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
-            Thread t = new ManagedLocalsThread(rootTG, disposerInstance, name);
+            Thread t = new Thread(rootTG, disposerInstance, name, 0, false);
             t.setContextClassLoader(null);
             t.setDaemon(true);
             t.setPriority(Thread.MAX_PRIORITY);
--- a/jdk/src/java.desktop/share/classes/sun/java2d/loops/GraphicsPrimitive.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/loops/GraphicsPrimitive.java	Thu Apr 28 23:08:16 2016 -0700
@@ -48,7 +48,6 @@
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 
-import sun.misc.ManagedLocalsThread;
 import sun.security.action.GetPropertyAction;
 
 /**
@@ -420,8 +419,9 @@
         public static void setShutdownHook() {
             AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
                 TraceReporter t = new TraceReporter();
-                Thread thread = new ManagedLocalsThread(
-                        ThreadGroupUtils.getRootThreadGroup(), t);
+                Thread thread = new Thread(
+                        ThreadGroupUtils.getRootThreadGroup(), t,
+                        "TraceReporter", 0, false);
                 thread.setContextClassLoader(null);
                 Runtime.getRuntime().addShutdownHook(thread);
                 return null;
--- a/jdk/src/java.desktop/share/classes/sun/java2d/opengl/OGLRenderQueue.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/opengl/OGLRenderQueue.java	Thu Apr 28 23:08:16 2016 -0700
@@ -28,7 +28,6 @@
 import sun.awt.util.ThreadGroupUtils;
 import sun.java2d.pipe.RenderBuffer;
 import sun.java2d.pipe.RenderQueue;
-import sun.misc.ManagedLocalsThread;
 
 import static sun.java2d.pipe.BufferedOpCodes.*;
 import java.security.AccessController;
@@ -161,7 +160,8 @@
 
         public QueueFlusher() {
             String name = "Java2D Queue Flusher";
-            thread = new ManagedLocalsThread(ThreadGroupUtils.getRootThreadGroup(), this, name);
+            thread = new Thread(ThreadGroupUtils.getRootThreadGroup(),
+                                this, name, 0, false);
             thread.setDaemon(true);
             thread.setPriority(Thread.MAX_PRIORITY);
             thread.start();
--- a/jdk/src/java.desktop/share/classes/sun/print/PrintJob2D.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/print/PrintJob2D.java	Thu Apr 28 23:08:16 2016 -0700
@@ -71,7 +71,6 @@
 import javax.print.attribute.standard.MediaSizeName;
 import javax.print.attribute.standard.PageRanges;
 
-import sun.misc.ManagedLocalsThread;
 import sun.print.SunPageSelection;
 import sun.print.SunMinMaxPage;
 
@@ -483,8 +482,30 @@
                 pageFormat.setOrientation(PageFormat.LANDSCAPE);
             } else {
                 pageFormat.setOrientation(PageFormat.PORTRAIT);
+            }
+
+            PageRanges pageRangesAttr
+                    = (PageRanges) attributes.get(PageRanges.class);
+            if (pageRangesAttr != null) {
+                // Get the PageRanges from print dialog.
+                int[][] range = pageRangesAttr.getMembers();
+
+                int prevFromPage = this.jobAttributes.getFromPage();
+                int prevToPage = this.jobAttributes.getToPage();
+
+                int currFromPage = range[0][0];
+                int currToPage = range[range.length - 1][1];
+
+                // if from < to update fromPage first followed by toPage
+                // else update toPage first followed by fromPage
+                if (currFromPage < prevToPage) {
+                    this.jobAttributes.setFromPage(currFromPage);
+                    this.jobAttributes.setToPage(currToPage);
+                } else {
+                    this.jobAttributes.setToPage(currToPage);
+                    this.jobAttributes.setFromPage(currFromPage);
                 }
-
+            }
             printerJob.setPrintable(this, pageFormat);
 
         }
@@ -987,7 +1008,8 @@
     }
 
     private void startPrinterJobThread() {
-        printerJobThread = new ManagedLocalsThread(this, "printerJobThread");
+        printerJobThread =
+            new Thread(null, this, "printerJobThread", 0, false);
         printerJobThread.start();
     }
 
--- a/jdk/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1388,6 +1388,8 @@
         Doc doc = new PageableDoc(getPageable());
         if (attributes == null) {
             attributes = new HashPrintRequestAttributeSet();
+            attributes.add(new Copies(getCopies()));
+            attributes.add(new JobName(getJobName(), null));
         }
         try {
             job.print(doc, attributes);
--- a/jdk/src/java.desktop/share/classes/sun/print/ServiceDialog.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/print/ServiceDialog.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1402,8 +1402,8 @@
             format.setParseIntegerOnly(false);
             format.setDecimalSeparatorAlwaysShown(true);
             NumberFormatter nf = new NumberFormatter(format);
-            nf.setMinimum(new Float(0.0f));
-            nf.setMaximum(new Float(999.0f));
+            nf.setMinimum(Float.valueOf(0.0f));
+            nf.setMaximum(Float.valueOf(999.0f));
             nf.setAllowsInvalid(true);
             nf.setCommitsOnValidEdit(true);
 
@@ -1422,13 +1422,13 @@
             topMargin.addActionListener(this);
             topMargin.getAccessibleContext().setAccessibleName(
                                               getMsg("label.topmargin"));
-            topMargin = new JFormattedTextField(nf);
+
             bottomMargin = new JFormattedTextField(nf);
             bottomMargin.addFocusListener(this);
             bottomMargin.addActionListener(this);
             bottomMargin.getAccessibleContext().setAccessibleName(
                                               getMsg("label.bottommargin"));
-            topMargin = new JFormattedTextField(nf);
+
             c.gridwidth = GridBagConstraints.RELATIVE;
             lblLeft = new JLabel(getMsg("label.leftmargin") + " " + unitsMsg,
                                  JLabel.LEADING);
@@ -1836,10 +1836,10 @@
             rmVal = mediaSize.getX(units) - pax - paw;
             bmVal = mediaSize.getY(units) - pay - pah;
 
-            lmObj = new Float(lmVal);
-            rmObj = new Float(rmVal);
-            tmObj = new Float(tmVal);
-            bmObj = new Float(bmVal);
+            lmObj = lmVal;
+            rmObj = rmVal;
+            tmObj = tmVal;
+            bmObj = bmVal;
 
             /* Now we know the values to use, we need to assign them
              * to the fields appropriate for the orientation.
--- a/jdk/src/java.desktop/share/classes/sun/print/ServiceNotifier.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/print/ServiceNotifier.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,8 +25,6 @@
 
 package sun.print;
 
-import sun.misc.ManagedLocalsThread;
-
 import java.util.Vector;
 
 import javax.print.PrintService;
@@ -42,15 +40,19 @@
  * to obtain the state of the attributes and notifies the listeners of
  * any changes.
  */
-class ServiceNotifier extends ManagedLocalsThread {
+class ServiceNotifier extends Thread {
 
     private PrintService service;
     private Vector<PrintServiceAttributeListener> listeners;
     private boolean stop = false;
     private PrintServiceAttributeSet lastSet;
 
+    /*
+     * If adding any other constructors, always call the 5-args
+     * super-class constructor passing "false" for inherit-locals.
+     */
     ServiceNotifier(PrintService service) {
-        super(service.getName() + " notifier");
+        super(null, null, service.getName() + " notifier", 0, false);
         this.service = service;
         listeners = new Vector<>();
         try {
@@ -70,7 +72,7 @@
         }
     }
 
-    void removeListener(PrintServiceAttributeListener listener) {
+   void removeListener(PrintServiceAttributeListener listener) {
          synchronized (this) {
             if (listener == null || listeners == null) {
                 return;
--- a/jdk/src/java.desktop/share/classes/sun/swing/StringUIClientPropertyKey.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/swing/StringUIClientPropertyKey.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016, 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,6 +25,8 @@
 
 package sun.swing;
 
+import javax.swing.UIClientPropertyKey;
+
 /**
  * An implementation of {@code UIClientPropertyKey} that wraps a {@code String}.
  *
--- a/jdk/src/java.desktop/share/classes/sun/swing/UIClientPropertyKey.java	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.swing;
-
-/**
- * This interface is used only for tagging keys for client properties
- * for {@code JComponent} set by UI which needs to be cleared on {@literal L&F}
- * change and serialization.
- *
- * All such keys are removed from client properties in {@code
- * JComponent.setUI()} method after uninstalling old UI and before
- * intalling the new one. They are also removed prior to serialization.
- *
- * @author Igor Kushnirskiy
- */
-public interface UIClientPropertyKey {
-}
--- a/jdk/src/java.desktop/share/classes/sun/swing/plaf/synth/DefaultSynthStyle.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/swing/plaf/synth/DefaultSynthStyle.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, 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
@@ -645,16 +645,7 @@
                     // StateInfo match, otherwise a StateInfo with
                     // SELECTED | ENABLED would match ENABLED, which we
                     // don't want.
-
-                    // This comes from BigInteger.bitCnt
-                    int bitCount = oState;
-                    bitCount -= (0xaaaaaaaa & bitCount) >>> 1;
-                    bitCount = (bitCount & 0x33333333) + ((bitCount >>> 2) &
-                                                      0x33333333);
-                    bitCount = bitCount + (bitCount >>> 4) & 0x0f0f0f0f;
-                    bitCount += bitCount >>> 8;
-                    bitCount += bitCount >>> 16;
-                    bitCount = bitCount & 0xff;
+                    int bitCount = Integer.bitCount(oState);
                     if (bitCount > bestCount) {
                         bestIndex = counter;
                         bestCount = bitCount;
@@ -883,21 +874,6 @@
         }
 
         /**
-         * Returns the number of states that are similar between the
-         * ComponentState this StateInfo represents and val.
-         */
-        private int getMatchCount(int val) {
-            // This comes from BigInteger.bitCnt
-            val &= state;
-            val -= (0xaaaaaaaa & val) >>> 1;
-            val = (val & 0x33333333) + ((val >>> 2) & 0x33333333);
-            val = val + (val >>> 4) & 0x0f0f0f0f;
-            val += val >>> 8;
-            val += val >>> 16;
-            return val & 0xff;
-        }
-
-        /**
          * Creates and returns a copy of this StateInfo.
          *
          * @return Copy of this StateInfo.
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/DeviceTables.cpp	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/DeviceTables.cpp	Thu Apr 28 23:08:16 2016 -0700
@@ -45,9 +45,12 @@
 
 le_int16 DeviceTable::getAdjustment(const LEReferenceTo<DeviceTable>&base, le_uint16 ppem, LEErrorCode &success) const
 {
+    le_int16 result = 0;
+    if (LE_FAILURE(success)) {
+        return result;
+    }
     le_uint16 start = SWAPW(startSize);
     le_uint16 format = SWAPW(deltaFormat) - 1;
-    le_int16 result = 0;
 
     if (ppem >= start && ppem <= SWAPW(endSize) && format < FORMAT_COUNT) {
         le_uint16 sizeIndex = ppem - start;
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc.cpp	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc.cpp	Thu Apr 28 23:08:16 2016 -0700
@@ -71,6 +71,10 @@
 {
   LEErrorCode success = LE_NO_ERROR;
   const LigatureSubstitutionStateEntry *entry = entryTable.getAlias(index, success);
+  if (LE_FAILURE(success)) {
+      currGlyph++;
+      return 0;
+  }
 
     ByteOffset newState = SWAPW(entry->newStateOffset);
     le_uint16 flags = SWAPW(entry->flags);
@@ -91,6 +95,10 @@
 
     if (actionOffset != 0) {
       LEReferenceTo<LigatureActionEntry> ap(stHeader, success, actionOffset);
+      if (LE_FAILURE(success)) {
+          currGlyph++;
+          return newState;
+      }
         LigatureActionEntry action;
         le_int32 offset, i = 0, j = 0;
         le_int32 stack[nComponents];
@@ -101,6 +109,10 @@
 
             if (j++ > 0) {
                 ap.addObject(success);
+                if (LE_FAILURE(success)) {
+                    currGlyph++;
+                    return newState;
+                }
             }
 
             action = SWAPL(*ap.getAlias());
@@ -124,9 +136,17 @@
                 return newState; // get out! bad font
               }
               i += SWAPW(offsetTable.getObject(LE_GET_GLYPH(glyphStorage[componentGlyph]), success));
+              if (LE_FAILURE(success)) {
+                  currGlyph++;
+                  return newState;
+              }
 
                 if (action & (lafLast | lafStore))  {
                   LEReferenceTo<TTGlyphID> ligatureOffset(stHeader, success, i);
+                  if (LE_FAILURE(success)) {
+                      currGlyph++;
+                      return newState;
+                  }
                   TTGlyphID ligatureGlyph = SWAPW(*ligatureOffset.getAlias());
 
                   glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph);
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc2.cpp	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc2.cpp	Thu Apr 28 23:08:16 2016 -0700
@@ -95,6 +95,10 @@
 
     if (actionOffset != 0) {
         LEReferenceTo<LigatureActionEntry> ap(stHeader, success, ligActionOffset); // byte offset
+        if (LE_FAILURE(success)) {
+            currGlyph+= dir;
+            return nextStateIndex;
+        }
         ap.addObject(ligActionIndex, success);
         LEReferenceToArrayOf<TTGlyphID> ligatureTable(stHeader, success, ligatureOffset, LE_UNBOUNDED_ARRAY);
         LigatureActionEntry action;
@@ -104,8 +108,8 @@
 
         LEReferenceToArrayOf<le_uint16> componentTable(stHeader, success, componentOffset, LE_UNBOUNDED_ARRAY);
         if(LE_FAILURE(success)) {
-          currGlyph+= dir;
-          return nextStateIndex; // get out! bad font
+            currGlyph+= dir;
+            return nextStateIndex; // get out! bad font
         }
 
         do {
@@ -114,6 +118,10 @@
             if (j++ > 0) {
                 ap.addObject(success);
             }
+            if (LE_FAILURE(success)) {
+                currGlyph+= dir;
+                return nextStateIndex;
+            }
 
             action = SWAPL(*ap.getAlias());
 
@@ -129,9 +137,17 @@
                   return nextStateIndex; // get out! bad font
                 }
                 i += SWAPW(componentTable(LE_GET_GLYPH(glyphStorage[componentGlyph]) + (SignExtend(offset, lafComponentOffsetMask)),success));
+                if (LE_FAILURE(success)) {
+                    currGlyph+= dir;
+                    return nextStateIndex;
+                }
 
                 if (action & (lafLast | lafStore))  {
                   TTGlyphID ligatureGlyph = SWAPW(ligatureTable(i,success));
+                  if (LE_FAILURE(success)) {
+                      currGlyph+= dir;
+                      return nextStateIndex;
+                  }
                     glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph);
                     if(mm==nComponents) {
                       LE_DEBUG_BAD_FONT("exceeded nComponents");
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/StateTableProcessor2.cpp	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/StateTableProcessor2.cpp	Thu Apr 28 23:08:16 2016 -0700
@@ -60,6 +60,7 @@
   entryTableOffset = SWAPL(stHeader->entryTableOffset);
 
   classTable = LEReferenceTo<LookupTable>(stHeader, success, classTableOffset);
+  if (LE_FAILURE(success)) return;
   format = SWAPW(classTable->format);
 
   stateArray = LEReferenceToArrayOf<EntryTableIndex2>(stHeader, success, stateArrayOffset, LE_UNBOUNDED_ARRAY);
--- a/jdk/src/java.desktop/unix/classes/sun/awt/UNIXToolkit.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/UNIXToolkit.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2016, 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,12 @@
 import java.awt.color.ColorSpace;
 import java.awt.image.*;
 import java.security.AccessController;
+import java.security.PrivilegedAction;
+
 import sun.security.action.GetIntegerAction;
 import com.sun.java.swing.plaf.gtk.GTKConstants.TextDirection;
 import sun.java2d.opengl.OGLRenderQueue;
+import sun.security.action.GetPropertyAction;
 
 public abstract class UNIXToolkit extends SunToolkit
 {
@@ -42,6 +45,40 @@
     private static final int[] BAND_OFFSETS_ALPHA = { 0, 1, 2, 3 };
     private static final int DEFAULT_DATATRANSFER_TIMEOUT = 10000;
 
+    // Allowed GTK versions
+    public enum GtkVersions {
+        ANY(0),
+        GTK2(Constants.GTK2_MAJOR_NUMBER),
+        GTK3(Constants.GTK3_MAJOR_NUMBER);
+
+        static class Constants {
+            static final int GTK2_MAJOR_NUMBER = 2;
+            static final int GTK3_MAJOR_NUMBER = 3;
+        }
+
+        final int number;
+
+        GtkVersions(int number) {
+            this.number = number;
+        }
+
+        public static GtkVersions getVersion(int number) {
+            switch (number) {
+                case Constants.GTK2_MAJOR_NUMBER:
+                    return GTK2;
+                case Constants.GTK3_MAJOR_NUMBER:
+                    return GTK3;
+                default:
+                    return ANY;
+            }
+        }
+
+        // major GTK version number
+        public int getNumber() {
+            return number;
+        }
+    };
+
     private Boolean nativeGTKAvailable;
     private Boolean nativeGTKLoaded;
     private BufferedImage tmpImage = null;
@@ -79,7 +116,7 @@
                 return nativeGTKAvailable;
 
             } else {
-                boolean success = check_gtk();
+                boolean success = check_gtk(getEnabledGtkVersion().getNumber());
                 nativeGTKAvailable = success;
                 return success;
             }
@@ -97,7 +134,8 @@
     public boolean loadGTK() {
         synchronized (GTK_LOCK) {
             if (nativeGTKLoaded == null) {
-                nativeGTKLoaded = load_gtk();
+                nativeGTKLoaded = load_gtk(getEnabledGtkVersion().getNumber(),
+                                                                isGtkVerbose());
             }
         }
         return nativeGTKLoaded;
@@ -241,14 +279,15 @@
         tmpImage = new BufferedImage(colorModel, raster, false, null);
     }
 
-    private static native boolean check_gtk();
-    private static native boolean load_gtk();
+    private static native boolean check_gtk(int version);
+    private static native boolean load_gtk(int version, boolean verbose);
     private static native boolean unload_gtk();
     private native boolean load_gtk_icon(String filename);
     private native boolean load_stock_icon(int widget_type, String stock_id,
             int iconSize, int textDirection, String detail);
 
     private native void nativeSync();
+    private static native int get_gtk_version();
 
     @Override
     public void sync() {
@@ -338,4 +377,26 @@
         }
         return false;
     }
+
+    public static GtkVersions getEnabledGtkVersion() {
+        String version = AccessController.doPrivileged(
+                new GetPropertyAction("jdk.gtk.version"));
+        if (version == null) {
+            return GtkVersions.ANY;
+        } else if (version.startsWith("2")) {
+            return GtkVersions.GTK2;
+        } else if("3".equals(version) ){
+            return GtkVersions.GTK3;
+        }
+        return GtkVersions.ANY;
+    }
+
+    public static GtkVersions getGtkVersion() {
+        return GtkVersions.getVersion(get_gtk_version());
+    }
+
+    public static boolean isGtkVerbose() {
+        return AccessController.doPrivileged((PrivilegedAction<Boolean>)()
+                -> Boolean.getBoolean("jdk.gtk.verbose"));
+    }
 }
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/GtkFileDialogPeer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/GtkFileDialogPeer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -29,7 +29,6 @@
 import java.io.File;
 import java.io.FilenameFilter;
 import sun.awt.AWTAccessor;
-import sun.misc.ManagedLocalsThread;
 
 /**
  * FileDialogPeer for the GtkFileChooser.
@@ -120,7 +119,7 @@
                     standaloneWindow = 0;
                     fd.setVisible(false);
                 };
-                new ManagedLocalsThread(task).start();
+                new Thread(null, task, "ShowDialog", 0, false).start();
             } else {
                 quit();
                 fd.setVisible(false);
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/InfoWindow.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/InfoWindow.java	Thu Apr 28 23:08:16 2016 -0700
@@ -29,7 +29,6 @@
 import java.awt.event.*;
 import java.awt.peer.TrayIconPeer;
 import sun.awt.*;
-import sun.misc.ManagedLocalsThread;
 
 import java.awt.image.*;
 import java.text.BreakIterator;
@@ -452,7 +451,7 @@
             final Thread thread;
 
             Displayer() {
-                this.thread = new ManagedLocalsThread(this);
+                this.thread = new Thread(null, this, "Displayer", 0, false);
                 this.thread.setDaemon(true);
             }
 
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XBaseMenuWindow.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XBaseMenuWindow.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1087,7 +1087,7 @@
                       }
                   } else {
                       //Invoke action event
-                      item.action(mouseEvent.getWhen());
+                      item.action(mouseEvent.getWhen(), mouseEvent.getModifiers());
                       ungrabInput();
                   }
               } else {
@@ -1200,7 +1200,7 @@
               if (citem instanceof XMenuPeer) {
                   cwnd.selectItem(citem, true);
               } else if (citem != null) {
-                  citem.action(event.getWhen());
+                  citem.action(event.getWhen(), event.getModifiers());
                   ungrabInput();
               }
               break;
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XComponentPeer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XComponentPeer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, 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
@@ -287,7 +287,7 @@
     @SuppressWarnings("deprecation")
     public final boolean requestFocus(Component lightweightChild, boolean temporary,
                                       boolean focusedWindowChangeAllowed, long time,
-                                      CausedFocusEvent.Cause cause)
+                                      FocusEvent.Cause cause)
     {
         if (XKeyboardFocusManagerPeer.
             processSynchronousLightweightTransfer(target, lightweightChild, temporary,
@@ -527,7 +527,7 @@
 //                       WindowEvent wfg = new WindowEvent(parentWindow, WindowEvent.WINDOW_GAINED_FOCUS);
 //                       parentWindow.dispatchEvent(wfg);
 //                   }
-                  XKeyboardFocusManagerPeer.requestFocusFor(target, CausedFocusEvent.Cause.MOUSE_EVENT);
+                  XKeyboardFocusManagerPeer.requestFocusFor(target, FocusEvent.Cause.MOUSE_EVENT);
               }
               break;
         }
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDesktopPeer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDesktopPeer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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 @@
 package sun.awt.X11;
 
 
+import sun.awt.UNIXToolkit;
+
 import java.io.File;
 import java.io.IOException;
 import java.net.MalformedURLException;
@@ -57,7 +59,8 @@
         XToolkit.awtLock();
         try {
             if (!initExecuted) {
-                nativeLibraryLoaded = init();
+                nativeLibraryLoaded = init(UNIXToolkit.getEnabledGtkVersion()
+                        .ordinal(), UNIXToolkit.isGtkVerbose());
             }
         } finally {
             initExecuted = true;
@@ -123,5 +126,5 @@
     }
 
     private native boolean gnome_url_show(byte[] url);
-    private static native boolean init();
+    private static native boolean init(int gtkVersion, boolean verbose);
 }
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XEmbedCanvasPeer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XEmbedCanvasPeer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -430,13 +430,10 @@
         if (isXEmbedActive()) {
             xembedLog.fine("Forwarding FOCUS_GAINED");
             int flavor = XEMBED_FOCUS_CURRENT;
-            if (e instanceof CausedFocusEvent) {
-                CausedFocusEvent ce = (CausedFocusEvent)e;
-                if (ce.getCause() == CausedFocusEvent.Cause.TRAVERSAL_FORWARD) {
-                    flavor = XEMBED_FOCUS_FIRST;
-                } else if (ce.getCause() == CausedFocusEvent.Cause.TRAVERSAL_BACKWARD) {
-                    flavor = XEMBED_FOCUS_LAST;
-                }
+            if (e.getCause() == FocusEvent.Cause.TRAVERSAL_FORWARD) {
+                flavor = XEMBED_FOCUS_FIRST;
+            } else if (e.getCause() == FocusEvent.Cause.TRAVERSAL_BACKWARD) {
+                flavor = XEMBED_FOCUS_LAST;
             }
             xembed.sendMessage(xembed.handle, XEMBED_FOCUS_IN, flavor, 0, 0);
         }
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XEmbedChildProxyPeer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XEmbedChildProxyPeer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -195,7 +195,7 @@
                                 boolean temporary,
                                 boolean focusedWindowChangeAllowed,
                                 long time,
-                                CausedFocusEvent.Cause cause)
+                                FocusEvent.Cause cause)
     {
         int result = XKeyboardFocusManagerPeer
             .shouldNativelyFocusHeavyweight(proxy, lightweightChild,
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XKeyboardFocusManagerPeer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XKeyboardFocusManagerPeer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,7 @@
 import java.awt.Window;
 
 import sun.awt.AWTAccessor;
-import sun.awt.CausedFocusEvent;
+import java.awt.event.FocusEvent;
 import sun.awt.KeyboardFocusManagerPeerImpl;
 import sun.util.logging.PlatformLogger;
 
@@ -101,7 +101,7 @@
                                        boolean temporary,
                                        boolean focusedWindowChangeAllowed,
                                        long time,
-                                       CausedFocusEvent.Cause cause)
+                                       FocusEvent.Cause cause)
     {
         return KeyboardFocusManagerPeerImpl.deliverFocus(lightweightChild,
                                                          target,
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XMenuItemPeer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XMenuItemPeer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -323,11 +323,11 @@
      * on menu item.
      * @param when the timestamp of action event
      */
-    void action(long when) {
+    void action(long when, int modifiers) {
         if (!isSeparator() && isTargetItemEnabled()) {
             XWindow.postEventStatic(new ActionEvent(target, ActionEvent.ACTION_PERFORMED,
                                                     getTargetActionCommand(), when,
-                                                    0));
+                                                    modifiers));
         }
     }
     /************************************************
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTaskbarPeer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTaskbarPeer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -29,7 +29,8 @@
 import java.awt.Taskbar.Feature;
 import java.awt.peer.TaskbarPeer;
 import java.awt.event.ActionEvent;
-import sun.misc.ManagedLocalsThread;
+
+import sun.awt.UNIXToolkit;
 import java.security.AccessController;
 import sun.security.action.GetPropertyAction;
 
@@ -46,12 +47,12 @@
             if (!initExecuted) {
                 String dname = AccessController.doPrivileged(
                                 new GetPropertyAction("java.desktop.appName", ""));
-                nativeLibraryLoaded = init(dname);
+                nativeLibraryLoaded = init(dname,
+                        UNIXToolkit.getEnabledGtkVersion().ordinal(),
+                        UNIXToolkit.isGtkVerbose());
                 if (nativeLibraryLoaded) {
-                    ManagedLocalsThread t
-                            = new ManagedLocalsThread(() -> {
-                                runloop();
-                            });
+                    Thread t = new Thread(null, () -> { runloop(); },
+                                          "TaskBar", 0, false);
                     t.setDaemon(true);
                     t.start();
                 }
@@ -150,7 +151,8 @@
         }
     }
 
-    private static native boolean init(String name);
+    private static native boolean init(String name, int version,
+                                                               boolean verbose);
 
     private static native void runloop();
 
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTextAreaPeer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTextAreaPeer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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,6 @@
 
 import javax.swing.plaf.BorderUIResource;
 import java.awt.im.InputMethodRequests;
-import sun.awt.CausedFocusEvent;
 import sun.awt.AWTAccessor;
 import sun.awt.SunToolkit;
 
@@ -945,14 +944,16 @@
 
         void forwardFocusGained( FocusEvent e) {
             isFocused = true;
-            FocusEvent fe = CausedFocusEvent.retarget(e, this);
+            FocusEvent fe = new FocusEvent(this, e.getID(), e.isTemporary(),
+                    e.getOppositeComponent(), e.getCause());
             super.processFocusEvent(fe);
         }
 
 
         void forwardFocusLost( FocusEvent e) {
             isFocused = false;
-            FocusEvent fe = CausedFocusEvent.retarget(e, this);
+            FocusEvent fe = new FocusEvent(this, e.getID(), e.isTemporary(),
+                    e.getOppositeComponent(), e.getCause());
             super.processFocusEvent(fe);
         }
 
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTextFieldPeer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTextFieldPeer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -54,7 +54,6 @@
 
 import sun.util.logging.PlatformLogger;
 
-import sun.awt.CausedFocusEvent;
 import sun.awt.AWTAccessor;
 
 final class XTextFieldPeer extends XComponentPeer implements TextFieldPeer {
@@ -618,13 +617,15 @@
 
         void forwardFocusGained( FocusEvent e) {
             isFocused = true;
-            FocusEvent fe = CausedFocusEvent.retarget(e, this);
+            FocusEvent fe = new FocusEvent(this, e.getID(), e.isTemporary(),
+                    e.getOppositeComponent(), e.getCause());
             super.processFocusEvent(fe);
         }
 
         void forwardFocusLost( FocusEvent e) {
             isFocused = false;
-            FocusEvent fe = CausedFocusEvent.retarget(e, this);
+            FocusEvent fe = new FocusEvent(this, e.getID(), e.isTemporary(),
+                    e.getOppositeComponent(), e.getCause());
             super.processFocusEvent(fe);
 
         }
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java	Thu Apr 28 23:08:16 2016 -0700
@@ -52,7 +52,6 @@
 import sun.awt.datatransfer.DataTransferer;
 import sun.font.FontConfigManager;
 import sun.java2d.SunGraphicsEnvironment;
-import sun.misc.*;
 import sun.awt.util.PerformanceLogger;
 import sun.awt.util.ThreadGroupUtils;
 import sun.print.PrintJob2D;
@@ -284,8 +283,8 @@
                 }
             };
             String name = "XToolkt-Shutdown-Thread";
-            Thread shutdownThread = new ManagedLocalsThread(
-                    ThreadGroupUtils.getRootThreadGroup(), r, name);
+            Thread shutdownThread = new Thread(
+                    ThreadGroupUtils.getRootThreadGroup(), r, name, 0, false);
             shutdownThread.setContextClassLoader(null);
             Runtime.getRuntime().addShutdownHook(shutdownThread);
             return null;
@@ -332,8 +331,9 @@
 
             toolkitThread = AccessController.doPrivileged((PrivilegedAction<Thread>) () -> {
                 String name = "AWT-XAWT";
-                Thread thread = new ManagedLocalsThread(
-                        ThreadGroupUtils.getRootThreadGroup(), this, name);
+                Thread thread = new Thread(
+                        ThreadGroupUtils.getRootThreadGroup(), this, name,
+                        0, false);
                 thread.setContextClassLoader(null);
                 thread.setPriority(Thread.NORM_PRIORITY + 1);
                 thread.setDaemon(true);
@@ -1143,7 +1143,8 @@
     public FileDialogPeer createFileDialog(FileDialog target) {
         FileDialogPeer peer = null;
         // The current GtkFileChooser is available from GTK+ 2.4
-        if (!getSunAwtDisableGtkFileDialogs() && checkGtkVersion(2, 4, 0)) {
+        if (!getSunAwtDisableGtkFileDialogs() &&
+                      (checkGtkVersion(2, 4, 0) || checkGtkVersion(3, 0, 0))) {
             peer = new GtkFileDialogPeer(target);
         } else {
             peer = new XFileDialogPeer(target);
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java	Thu Apr 28 23:08:16 2016 -0700
@@ -44,7 +44,6 @@
 
 import sun.awt.util.ThreadGroupUtils;
 import sun.java2d.SunGraphicsEnvironment;
-import sun.misc.ManagedLocalsThread;
 
 /**
  * This is an implementation of a GraphicsDevice object for a single
@@ -442,8 +441,8 @@
                     }
                 };
                 String name = "Display-Change-Shutdown-Thread-" + screen;
-                Thread t = new ManagedLocalsThread(
-                        ThreadGroupUtils.getRootThreadGroup(), r, name);
+                Thread t = new Thread(
+                      ThreadGroupUtils.getRootThreadGroup(), r, name, 0, false);
                 t.setContextClassLoader(null);
                 Runtime.getRuntime().addShutdownHook(t);
                 return null;
--- a/jdk/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,8 +25,6 @@
 
 package sun.print;
 
-import sun.misc.ManagedLocalsThread;
-
 import java.io.BufferedReader;
 import java.io.FileInputStream;
 import java.io.InputStream;
@@ -119,7 +117,7 @@
 
         if (refreshTimeStr != null) {
             try {
-                minRefreshTime = (new Integer(refreshTimeStr)).intValue();
+                minRefreshTime = (Integer.valueOf(refreshTimeStr)).intValue();
             } catch (NumberFormatException e) {
             }
             if (minRefreshTime < DEFAULT_MINREFRESH) {
@@ -213,7 +211,8 @@
     public PrintServiceLookupProvider() {
         // start the printer listener thread
         if (pollServices) {
-            Thread thr = new ManagedLocalsThread(new PrinterChangeListener());
+            Thread thr = new Thread(null, new PrinterChangeListener(),
+                                    "PrinterListener", 0, false);
             thr.setDaemon(true);
             thr.start();
             IPPPrintService.debug_println(debugPrefix+"polling turned on");
--- a/jdk/src/java.desktop/unix/native/common/awt/awt.h	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/native/common/awt/awt.h	Thu Apr 28 23:08:16 2016 -0700
@@ -35,7 +35,9 @@
 #include "debug_util.h"
 
 #if !defined(HEADLESS) && !defined(MACOSX)
-#include <X11/Intrinsic.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+typedef char Boolean;
 #endif /* !HEADLESS && !MACOSX */
 
 
--- a/jdk/src/java.desktop/unix/native/common/awt/awt_p.h	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/native/common/awt/awt_p.h	Thu Apr 28 23:08:16 2016 -0700
@@ -41,13 +41,6 @@
 #include <string.h>
 #include <unistd.h>
 #ifndef HEADLESS
-#include <X11/Intrinsic.h>
-#include <X11/IntrinsicP.h>
-#include <X11/Shell.h>
-#include <X11/StringDefs.h>
-#include <X11/Xatom.h>
-#include <X11/keysym.h>
-#include <X11/keysymdef.h>
 #include <X11/extensions/Xrender.h>
 #endif /* !HEADLESS */
 #include "awt.h"
--- a/jdk/src/java.desktop/unix/native/common/awt/extutil.h	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,251 +0,0 @@
-/*
- * 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:
- *
- * $Xorg: extutil.h,v 1.3 2000/08/18 04:05:45 coskrey Exp $
- *
-Copyright 1989, 1998  The Open Group
-
-All Rights Reserved.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
- *
- * Author:  Jim Fulton, MIT The Open Group
- *
- *                     Xlib Extension-Writing Utilities
- *
- * This package contains utilities for writing the client API for various
- * protocol extensions.  THESE INTERFACES ARE NOT PART OF THE X STANDARD AND
- * ARE SUBJECT TO CHANGE!
- */
-/* $XFree86: xc/include/extensions/extutil.h,v 1.5 2001/01/17 17:53:20 dawes Exp $ */
-
-#if defined(__linux__) || defined(MACOSX)
-
-#ifndef _EXTUTIL_H_
-#define _EXTUTIL_H_
-
-/*
- * We need to keep a list of open displays since the Xlib display list isn't
- * public.  We also have to per-display info in a separate block since it isn't
- * stored directly in the Display structure.
- */
-typedef struct _XExtDisplayInfo {
-    struct _XExtDisplayInfo *next;      /* keep a linked list */
-    Display *display;                   /* which display this is */
-    XExtCodes *codes;                   /* the extension protocol codes */
-    XPointer data;                      /* extra data for extension to use */
-} XExtDisplayInfo;
-
-typedef struct _XExtensionInfo {
-    XExtDisplayInfo *head;              /* start of list */
-    XExtDisplayInfo *cur;               /* most recently used */
-    int ndisplays;                      /* number of displays */
-} XExtensionInfo;
-
-typedef struct _XExtensionHooks {
-    int (*create_gc)(
-#if NeedNestedPrototypes
-              Display*                  /* display */,
-              GC                        /* gc */,
-              XExtCodes*                /* codes */
-#endif
-);
-    int (*copy_gc)(
-#if NeedNestedPrototypes
-              Display*                  /* display */,
-              GC                        /* gc */,
-              XExtCodes*                /* codes */
-#endif
-);
-    int (*flush_gc)(
-#if NeedNestedPrototypes
-              Display*                  /* display */,
-              GC                        /* gc */,
-              XExtCodes*                /* codes */
-#endif
-);
-    int (*free_gc)(
-#if NeedNestedPrototypes
-              Display*                  /* display */,
-              GC                        /* gc */,
-              XExtCodes*                /* codes */
-#endif
-);
-    int (*create_font)(
-#if NeedNestedPrototypes
-              Display*                  /* display */,
-              XFontStruct*              /* fs */,
-              XExtCodes*                /* codes */
-#endif
-);
-    int (*free_font)(
-#if NeedNestedPrototypes
-              Display*                  /* display */,
-              XFontStruct*              /* fs */,
-              XExtCodes*                /* codes */
-#endif
-);
-    int (*close_display)(
-#if NeedNestedPrototypes
-              Display*                  /* display */,
-              XExtCodes*                /* codes */
-#endif
-);
-    Bool (*wire_to_event)(
-#if NeedNestedPrototypes
-               Display*                 /* display */,
-               XEvent*                  /* re */,
-               xEvent*                  /* event */
-#endif
-);
-    Status (*event_to_wire)(
-#if NeedNestedPrototypes
-              Display*                  /* display */,
-              XEvent*                   /* re */,
-              xEvent*                   /* event */
-#endif
-);
-    int (*error)(
-#if NeedNestedPrototypes
-              Display*                  /* display */,
-              xError*                   /* err */,
-              XExtCodes*                /* codes */,
-              int*                      /* ret_code */
-#endif
-);
-    char *(*error_string)(
-#if NeedNestedPrototypes
-                Display*                /* display */,
-                int                     /* code */,
-                XExtCodes*              /* codes */,
-                char*                   /* buffer */,
-                int                     /* nbytes */
-#endif
-);
-} XExtensionHooks;
-
-extern XExtensionInfo *XextCreateExtension(
-#if NeedFunctionPrototypes
-    void
-#endif
-);
-extern void XextDestroyExtension(
-#if NeedFunctionPrototypes
-    XExtensionInfo*     /* info */
-#endif
-);
-extern XExtDisplayInfo *XextAddDisplay(
-#if NeedFunctionPrototypes
-    XExtensionInfo*     /* extinfo */,
-    Display*            /* dpy */,
-    char*               /* ext_name */,
-    XExtensionHooks*    /* hooks */,
-    int                 /* nevents */,
-    XPointer            /* data */
-#endif
-);
-extern int XextRemoveDisplay(
-#if NeedFunctionPrototypes
-    XExtensionInfo*     /* extinfo */,
-    Display*            /* dpy */
-#endif
-);
-extern XExtDisplayInfo *XextFindDisplay(
-#if NeedFunctionPrototypes
-    XExtensionInfo*     /* extinfo */,
-    Display*            /* dpy */
-#endif
-);
-
-#define XextHasExtension(i) ((i) && ((i)->codes))
-#define XextCheckExtension(dpy,i,name,val) \
-  if (!XextHasExtension(i)) { XMissingExtension (dpy, name); return val; }
-#define XextSimpleCheckExtension(dpy,i,name) \
-  if (!XextHasExtension(i)) { XMissingExtension (dpy, name); return; }
-
-
-/*
- * helper macros to generate code that is common to all extensions; caller
- * should prefix it with static if extension source is in one file; this
- * could be a utility function, but have to stack 6 unused arguments for
- * something that is called many, many times would be bad.
- */
-#define XEXT_GENERATE_FIND_DISPLAY(proc,extinfo,extname,hooks,nev,data) \
-XExtDisplayInfo *proc (Display *dpy) \
-{ \
-    XExtDisplayInfo *dpyinfo; \
-    if (!extinfo) { if (!(extinfo = XextCreateExtension())) return NULL; } \
-    if (!(dpyinfo = XextFindDisplay (extinfo, dpy))) \
-      dpyinfo = XextAddDisplay (extinfo,dpy,extname,hooks,nev,data); \
-    return dpyinfo; \
-}
-
-#define XEXT_FIND_DISPLAY_PROTO(proc) \
-        XExtDisplayInfo *proc(Display *dpy)
-
-#define XEXT_GENERATE_CLOSE_DISPLAY(proc,extinfo) \
-int proc (Display *dpy, XExtCodes *codes) \
-{ \
-    return XextRemoveDisplay (extinfo, dpy); \
-}
-
-#define XEXT_CLOSE_DISPLAY_PROTO(proc) \
-        int proc(Display *dpy, XExtCodes *codes)
-
-#define XEXT_GENERATE_ERROR_STRING(proc,extname,nerr,errl) \
-char *proc (Display *dpy, int code, XExtCodes *codes, char *buf, int n) \
-{  \
-    code -= codes->first_error;  \
-    if (code >= 0 && code < nerr) { \
-        char tmp[256]; \
-        sprintf (tmp, "%s.%d", extname, code); \
-        XGetErrorDatabaseText (dpy, "XProtoError", tmp, errl[code], buf, n); \
-        return buf; \
-    } \
-    return (char *)0; \
-}
-
-#define XEXT_ERROR_STRING_PROTO(proc) \
-        char *proc(Display *dpy, int code, XExtCodes *codes, char *buf, int n)
-#endif
-
-#endif /* __linux__ || MACOSX */
--- a/jdk/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.c	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.c	Thu Apr 28 23:08:16 2016 -0700
@@ -270,7 +270,6 @@
     xsdo->sdOps.Dispose = X11SD_Dispose;
     xsdo->GetPixmapWithBg = X11SD_GetPixmapWithBg;
     xsdo->ReleasePixmapWithBg = X11SD_ReleasePixmapWithBg;
-    xsdo->widget = NULL;
     if (peer != NULL) {
         xsdo->drawable = JNU_CallMethodByName(env, &hasException, peer, "getWindow", "()J").j;
         if (hasException) {
@@ -1087,7 +1086,7 @@
 X11SD_ClipToRoot(SurfaceDataBounds *b, SurfaceDataBounds *bounds,
                  X11SDOps *xsdo)
 {
-    Position x1=0, y1=0, x2=0, y2=0;
+    short x1=0, y1=0, x2=0, y2=0;
     int tmpx, tmpy;
     Window tmpchild;
 
--- a/jdk/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.h	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.h	Thu Apr 28 23:08:16 2016 -0700
@@ -101,7 +101,6 @@
     jboolean            isPixmap;
     jobject             peer;
     Drawable            drawable;
-    Widget              widget;
     GC                  javaGC;        /* used for Java-level GC validation */
     GC                  cachedGC;      /* cached for use in X11SD_Unlock() */
     jint                depth;
--- a/jdk/src/java.desktop/unix/native/include/jawt_md.h	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/native/include/jawt_md.h	Thu Apr 28 23:08:16 2016 -0700
@@ -28,7 +28,6 @@
 
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
-#include <X11/Intrinsic.h>
 #include "jawt.h"
 
 #ifdef __cplusplus
--- a/jdk/src/java.desktop/unix/native/libawt_headless/awt/VDrawingArea.c	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,344 +0,0 @@
-/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#ifndef HEADLESS
-
-#include <X11/IntrinsicP.h>
-#include "VDrawingAreaP.h"
-
-#endif /* !HEADLESS */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#ifdef __linux__
-/* XXX: Shouldn't be necessary. */
-#include "awt_p.h"
-#endif /* __linux__ */
-
-
-/******************************************************************
- *
- * Provides Canvas widget which allows the X11 visual to be
- * changed (the Motif DrawingArea restricts the visual to that
- * of the parent widget).
- *
- ******************************************************************/
-
-
-/******************************************************************
- *
- * VDrawingArea Widget Resources
- *
- ******************************************************************/
-
-#ifndef HEADLESS
-#define Offset(x)       (XtOffsetOf(VDrawingAreaRec, x))
-static XtResource resources[]=
-{
-        { XtNvisual, XtCVisual, XtRVisual, sizeof(Visual*),
-          Offset(vdrawing_area.visual), XtRImmediate, CopyFromParent}
-};
-
-
-static void Realize();
-static Boolean SetValues();
-static void Destroy ();
-
-static XmBaseClassExtRec baseClassExtRec = {
-    NULL,
-    NULLQUARK,
-    XmBaseClassExtVersion,
-    sizeof(XmBaseClassExtRec),
-    NULL,                               /* InitializePrehook    */
-    NULL,                               /* SetValuesPrehook     */
-    NULL,                               /* InitializePosthook   */
-    NULL,                               /* SetValuesPosthook    */
-    NULL,                               /* secondaryObjectClass */
-    NULL,                               /* secondaryCreate      */
-    NULL,                               /* getSecRes data       */
-    { 0 },                              /* fastSubclass flags   */
-    NULL,                               /* getValuesPrehook     */
-    NULL,                               /* getValuesPosthook    */
-    NULL,                               /* classPartInitPrehook */
-    NULL,                               /* classPartInitPosthook*/
-    NULL,                               /* ext_resources        */
-    NULL,                               /* compiled_ext_resources*/
-    0,                                  /* num_ext_resources    */
-    FALSE,                              /* use_sub_resources    */
-    NULL,                               /* widgetNavigable      */
-    NULL,                               /* focusChange          */
-    NULL                                /* wrapper_data         */
-};
-
-VDrawingAreaClassRec vDrawingAreaClassRec = {
-{
-    /* Core class part */
-
-    /* superclass         */    (WidgetClass)&xmDrawingAreaClassRec,
-    /* class_name         */    "VDrawingArea",
-    /* widget_size        */    sizeof(VDrawingAreaRec),
-    /* class_initialize   */    NULL,
-    /* class_part_initialize*/  NULL,
-    /* class_inited       */    FALSE,
-    /* initialize         */    NULL,
-    /* initialize_hook    */    NULL,
-    /* realize            */    Realize,
-    /* actions            */    NULL,
-    /* num_actions        */    0,
-    /* resources          */    resources,
-    /* num_resources      */    XtNumber(resources),
-    /* xrm_class          */    NULLQUARK,
-    /* compress_motion    */    FALSE,
-    /* compress_exposure  */    FALSE,
-    /* compress_enterleave*/    FALSE,
-    /* visible_interest   */    FALSE,
-    /* destroy            */    Destroy,
-    /* resize             */    XtInheritResize,
-    /* expose             */    XtInheritExpose,
-    /* set_values         */    SetValues,
-    /* set_values_hook    */    NULL,
-    /* set_values_almost  */    XtInheritSetValuesAlmost,
-    /* get_values_hook    */    NULL,
-    /* accept_focus       */    NULL,
-    /* version            */    XtVersion,
-    /* callback_offsets   */    NULL,
-    /* tm_table           */    NULL,
-    /* query_geometry       */  NULL,
-    /* display_accelerator  */  NULL,
-    /* extension            */  NULL
-  },
-
-   {            /* composite_class fields */
-      XtInheritGeometryManager,                 /* geometry_manager   */
-      XtInheritChangeManaged,                   /* change_managed     */
-      XtInheritInsertChild,                     /* insert_child       */
-      XtInheritDeleteChild,                     /* delete_child       */
-      NULL,                                     /* extension          */
-   },
-
-   {            /* constraint_class fields */
-      NULL,                                     /* resource list        */
-      0,                                        /* num resources        */
-      0,                                        /* constraint size      */
-      NULL,                                     /* init proc            */
-      NULL,                                     /* destroy proc         */
-      NULL,                                     /* set values proc      */
-      NULL,                                     /* extension            */
-   },
-
-   {            /* manager_class fields */
-      XtInheritTranslations,                    /* translations           */
-      NULL,                                     /* syn_resources          */
-      0,                                        /* num_get_resources      */
-      NULL,                                     /* syn_cont_resources     */
-      0,                                        /* num_get_cont_resources */
-      XmInheritParentProcess,                   /* parent_process         */
-      NULL,                                     /* extension           */
-   },
-
-   {            /* drawingArea class */
-           /* extension */      NULL
-   },
-
-   /* VDrawingArea class part */
-   {
-        /* extension    */      NULL
-   }
-};
-
-WidgetClass vDrawingAreaClass = (WidgetClass)&vDrawingAreaClassRec;
-
-static Boolean
-SetValues(cw, rw, nw, args, num_args)
-    Widget cw;
-    Widget rw;
-    Widget nw;
-    ArgList args;
-    Cardinal *num_args;
-{
-    VDrawingAreaWidget current = (VDrawingAreaWidget)cw;
-    VDrawingAreaWidget new_w = (VDrawingAreaWidget)nw;
-
-    if (new_w->vdrawing_area.visual != current->vdrawing_area.visual) {
-        new_w->vdrawing_area.visual = current->vdrawing_area.visual;
-#ifdef DEBUG
-        fprintf(stdout, "VDrawingArea.SetValues: can't change visual from: visualID=%ld to visualID=%ld\n",
-                     current->vdrawing_area.visual->visualid,
-                     new_w->vdrawing_area.visual->visualid);
-#endif
-
-    }
-
-    return (False);
-}
-
-int
-FindWindowInList (Window parentWindow, Window *colormap_windows, int count)
-{
-    int i;
-
-    for (i = 0; i < count; i++)
-        if (colormap_windows [i] == parentWindow)
-           return i;
-    return -1;
-}
-
-static void
-Realize(w, value_mask, attributes)
-    Widget               w;
-    XtValueMask          *value_mask;
-    XSetWindowAttributes *attributes;
-{
-    Widget parent;
-    Status status;
-    Window *colormap_windows;
-    Window *new_colormap_windows;
-    int count;
-    int i;
-    VDrawingAreaWidget vd = (VDrawingAreaWidget)w;
-
-#ifdef DEBUG
-    fprintf(stdout, "VDrawingArea.Realize: visualID=%ld, depth=%d\n",
-                        vd->vdrawing_area.visual->visualid, w->core.depth);
-#endif
-
-    /* 4328588:
-     * Since we have our own Realize() function, we don't execute the one for
-     * our super-super class, XmManager, and miss the code which checks that
-     * height and width != 0.  I've added that here.  -bchristi
-     */
-    if (!XtWidth(w)) XtWidth(w) = 1 ;
-    if (!XtHeight(w)) XtHeight(w) = 1 ;
-
-    w->core.window = XCreateWindow (XtDisplay (w), XtWindow (w->core.parent),
-                        w->core.x, w->core.y, w->core.width, w->core.height,
-                        0, w->core.depth, InputOutput,
-                        vd->vdrawing_area.visual,
-                        *value_mask, attributes );
-
-    /* Need to add this window to the list of Colormap windows */
-    parent = XtParent (w);
-    while ((parent != NULL) && (!(XtIsShell (parent))))
-        parent = XtParent (parent);
-    if (parent == NULL) {
-        fprintf (stderr, "NO TopLevel widget?!\n");
-        return;
-    }
-
-    status = XGetWMColormapWindows (XtDisplay (w), XtWindow (parent),
-                                    &colormap_windows, &count);
-
-    /* If status is zero, add this window and shell to the list
-       of colormap Windows */
-    if (status == 0) {
-        new_colormap_windows = (Window *) calloc (2, sizeof (Window));
-        new_colormap_windows [0] = XtWindow (w);
-        new_colormap_windows [1] = XtWindow (parent);
-        XSetWMColormapWindows (XtDisplay (w), XtWindow (parent),
-                               new_colormap_windows, 2);
-        free (new_colormap_windows);
-    } else {
-        /* Check if parent is already in the list */
-        int parent_entry = -1;
-
-        if (count > 0)
-            parent_entry = FindWindowInList (XtWindow (parent),
-                                        colormap_windows, count);
-        if (parent_entry == -1) {  /*  Parent not in list  */
-            new_colormap_windows = (Window *) calloc (count + 2,
-                                                sizeof (Window));
-            new_colormap_windows [0] = XtWindow (w);
-            new_colormap_windows [1] = XtWindow (parent);
-            for (i = 0; i < count; i++)
-                new_colormap_windows [i + 2] = colormap_windows [i];
-            XSetWMColormapWindows (XtDisplay (w), XtWindow (parent),
-                                   new_colormap_windows, count + 2);
-
-        } else {        /* parent already in list, just add new window */
-            new_colormap_windows = (Window *) calloc (count + 1,
-                                                sizeof (Window));
-            new_colormap_windows [0] = XtWindow (w);
-            for (i = 0; i < count; i++)
-                new_colormap_windows [i + 1] = colormap_windows [i];
-            XSetWMColormapWindows (XtDisplay (w), XtWindow (parent),
-                                   new_colormap_windows, count + 1);
-        }
-        free (new_colormap_windows);
-        XFree (colormap_windows);
-    }
-
-
-}
-
-static void
-Destroy(Widget widget)
-{
-    Status status;
-    Widget parent;
-    Window *colormap_windows;
-    Window *new_colormap_windows;
-    int count;
-    int listEntry;
-    int i;
-    int j;
-
-    /* Need to get this window's parent shell first */
-    parent = XtParent (widget);
-    while ((parent != NULL) && (!(XtIsShell (parent))))
-        parent = XtParent (parent);
-    if (parent == NULL) {
-        fprintf (stderr, "NO TopLevel widget?!\n");
-        return;
-    }
-
-    status = XGetWMColormapWindows (XtDisplay (widget), XtWindow (parent),
-                                    &colormap_windows, &count);
-
-    /* If status is zero, then there were no colormap windows for
-       the parent ?? */
-
-    if (status == 0)
-        return;
-
-    /* Remove this window from the list of colormap windows */
-    listEntry = FindWindowInList (XtWindow (widget), colormap_windows,
-                                  count);
-
-    new_colormap_windows = (Window *) calloc (count - 1, sizeof (Window));
-    j = 0;
-    for (i = 0; i < count; i++) {
-        if (i == listEntry)
-           continue;
-        new_colormap_windows [j] = colormap_windows [i];
-        j++;
-    }
-    XSetWMColormapWindows (XtDisplay (widget), XtWindow (parent),
-                           new_colormap_windows, count - 1);
-    free (new_colormap_windows);
-    XFree (colormap_windows);
-
-}
-#endif /* !HEADLESS */
--- a/jdk/src/java.desktop/unix/native/libawt_headless/awt/VDrawingArea.h	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.
- */
-
-#ifndef _VDrawingArea_h_
-#define _VDrawingArea_h_
-
-#ifndef HEADLESS
-extern WidgetClass vDrawingAreaClass;
-
-typedef struct _VDrawingAreaClassRec    *VDrawingAreaWidgetClass;
-typedef struct _VDrawingAreaRec         *VDrawingAreaWidget;
-#endif /* !HEADLESS */
-
-#endif /* !_VDrawingArea_h_ */
--- a/jdk/src/java.desktop/unix/native/libawt_headless/awt/VDrawingAreaP.h	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 1997, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.
- */
-
-#ifndef _VDrawingAreaP_h_
-#define _VDrawingAreaP_h_
-
-#include <Xm/DrawingAP.h>
-#include "VDrawingArea.h"
-
-
-/***************************************************************
- * VDrawingArea Widget Data Structures
- *
- *
- **************************************************************/
-
-/* Define part class structure */
-typedef struct _VDrawingAreaClass {
-        XtPointer                       extension;
-} VDrawingAreaClassPart;
-
-/* Define the full class record */
-typedef struct _VDrawingAreaClassRec {
-        CoreClassPart           core_class;
-        CompositeClassPart      composite_class;
-        ConstraintClassPart     constraint_class;
-        XmManagerClassPart      manager_class;
-        XmDrawingAreaClassPart  drawing_area_class;
-        VDrawingAreaClassPart   vdrawingarea_class;
-} VDrawingAreaClassRec;
-
-/* External definition for class record */
-extern VDrawingAreaClassRec vDrawingAreaClassRec;
-
-typedef struct {
-        Visual *visual;
-} VDrawingAreaPart;
-
-/****************************************************************
- *
- * Full instance record declaration
- *
- ****************************************************************/
-
-typedef struct _VDrawingAreaRec
-{
-        CorePart                core;
-        CompositePart           composite;
-        ConstraintPart          constraint;
-        XmManagerPart           manager;
-        XmDrawingAreaPart       drawing_area;
-        VDrawingAreaPart        vdrawing_area;
-} VDrawingAreaRec;
-
-
-
-#endif /* !_VDrawingAreaP_h_ */
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -1877,31 +1877,34 @@
 
     AWT_LOCK();
 
-    config = awt_XRRGetScreenInfo(awt_display,
-                                  RootWindow(awt_display, screen));
-    if (config != NULL) {
-        Rotation rotation;
-        short curRate;
-        SizeID curSizeIndex;
-        XRRScreenSize *sizes;
-        int nsizes;
+    if (screen < ScreenCount(awt_display)) {
 
-        curSizeIndex = awt_XRRConfigCurrentConfiguration(config, &rotation);
-        sizes = awt_XRRConfigSizes(config, &nsizes);
-        curRate = awt_XRRConfigCurrentRate(config);
+        config = awt_XRRGetScreenInfo(awt_display,
+                                      RootWindow(awt_display, screen));
+        if (config != NULL) {
+            Rotation rotation;
+            short curRate;
+            SizeID curSizeIndex;
+            XRRScreenSize *sizes;
+            int nsizes;
 
-        if ((sizes != NULL) &&
-            (curSizeIndex < nsizes))
-        {
-            XRRScreenSize curSize = sizes[curSizeIndex];
-            displayMode = X11GD_CreateDisplayMode(env,
-                                                  curSize.width,
-                                                  curSize.height,
-                                                  BIT_DEPTH_MULTI,
-                                                  curRate);
+            curSizeIndex = awt_XRRConfigCurrentConfiguration(config, &rotation);
+            sizes = awt_XRRConfigSizes(config, &nsizes);
+            curRate = awt_XRRConfigCurrentRate(config);
+
+            if ((sizes != NULL) &&
+                (curSizeIndex < nsizes))
+            {
+                XRRScreenSize curSize = sizes[curSizeIndex];
+                displayMode = X11GD_CreateDisplayMode(env,
+                                                      curSize.width,
+                                                      curSize.height,
+                                                      BIT_DEPTH_MULTI,
+                                                      curRate);
+            }
+
+            awt_XRRFreeScreenConfigInfo(config);
         }
-
-        awt_XRRFreeScreenConfigInfo(config);
     }
 
     AWT_FLUSH_UNLOCK();
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_InputMethod.c	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_InputMethod.c	Thu Apr 28 23:08:16 2016 -0700
@@ -30,6 +30,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <X11/Xlib.h>
+#include <X11/keysym.h>
 #include <sys/time.h>
 
 #include "awt.h"
@@ -40,7 +41,6 @@
 
 #define THROW_OUT_OF_MEMORY_ERROR() \
         JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2), NULL)
-#define SETARG(name, value)     XtSetArg(args[argc], name, value); argc++
 
 struct X11InputMethodIDs {
   jfieldID pData;
@@ -590,7 +590,7 @@
     char **mclr;
     int  mccr = 0;
     char *dsr;
-    Pixel bg, fg, light, dim;
+    unsigned long bg, fg, light, dim;
     int x, y, off_x, off_y, xx, yy;
     unsigned int w, h, bw, depth;
     XGCValues values;
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_Robot.c	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_Robot.c	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,6 @@
 #include "awt_GraphicsEnv.h"
 #define XK_MISCELLANY
 #include <X11/keysymdef.h>
-#include <X11/Intrinsic.h>
 #include <X11/Xutil.h>
 #include <X11/Xmd.h>
 #include <X11/extensions/xtestext1.h>
@@ -45,7 +44,7 @@
 #include "wsutils.h"
 #include "list.h"
 #include "multiVis.h"
-#include "gtk2_interface.h"
+#include "gtk_interface.h"
 
 #if defined(__linux__) || defined(MACOSX)
 #include <sys/socket.h>
@@ -264,70 +263,10 @@
     int index;
 
     if (isGtkSupported) {
-        GdkPixbuf *pixbuf;
-        (*fp_gdk_threads_enter)();
-        GdkWindow *root = (*fp_gdk_get_default_root_window)();
-
-        pixbuf = (*fp_gdk_pixbuf_get_from_drawable)(NULL, root, NULL,
-                                                    x, y, 0, 0, width, height);
-        if (pixbuf && scale != 1) {
-            GdkPixbuf *scaledPixbuf;
-            x /= scale;
-            y /= scale;
-            width /= scale;
-            height /= scale;
-            dx /= scale;
-            dy /= scale;
-            scaledPixbuf = (*fp_gdk_pixbuf_scale_simple)(pixbuf, width, height,
-                                                         GDK_INTERP_BILINEAR);
-            (*fp_g_object_unref)(pixbuf);
-            pixbuf = scaledPixbuf;
-        }
-
-        if (pixbuf) {
-            int nchan = (*fp_gdk_pixbuf_get_n_channels)(pixbuf);
-            int stride = (*fp_gdk_pixbuf_get_rowstride)(pixbuf);
-
-            if ((*fp_gdk_pixbuf_get_width)(pixbuf) == width
-                    && (*fp_gdk_pixbuf_get_height)(pixbuf) == height
-                    && (*fp_gdk_pixbuf_get_bits_per_sample)(pixbuf) == 8
-                    && (*fp_gdk_pixbuf_get_colorspace)(pixbuf) == GDK_COLORSPACE_RGB
-                    && nchan >= 3
-                    ) {
-                guchar *p, *pix = (*fp_gdk_pixbuf_get_pixels)(pixbuf);
-
-                ary = (*env)->GetPrimitiveArrayCritical(env, pixelArray, NULL);
-                if (!ary) {
-                    (*fp_g_object_unref)(pixbuf);
-                    (*fp_gdk_threads_leave)();
-                    AWT_UNLOCK();
-                    return;
-                }
-
-                for (_y = 0; _y < height; _y++) {
-                    for (_x = 0; _x < width; _x++) {
-                        p = pix + _y * stride + _x * nchan;
-
-                        index = (_y + dy) * jwidth + (_x + dx);
-                        ary[index] = 0xff000000
-                                        | (p[0] << 16)
-                                        | (p[1] << 8)
-                                        | (p[2]);
-
-                    }
-                }
-                (*env)->ReleasePrimitiveArrayCritical(env, pixelArray, ary, 0);
-                if ((*env)->ExceptionCheck(env)) {
-                    (*fp_g_object_unref)(pixbuf);
-                    (*fp_gdk_threads_leave)();
-                    AWT_UNLOCK();
-                    return;
-                }
-                gtk_failed = FALSE;
-            }
-            (*fp_g_object_unref)(pixbuf);
-        }
-        (*fp_gdk_threads_leave)();
+        gtk->gdk_threads_enter();
+        gtk_failed = gtk->get_drawable_data(env, pixelArray, x, y, width,
+                                            height, jwidth, dx, dy, scale);
+        gtk->gdk_threads_leave();
     }
 
     if (gtk_failed) {
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_UNIXToolkit.c	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_UNIXToolkit.c	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2016, 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
@@ -34,7 +34,7 @@
 
 #ifndef HEADLESS
 #include "awt.h"
-#include "gtk2_interface.h"
+#include "gtk_interface.h"
 #endif /* !HEADLESS */
 
 
@@ -45,13 +45,12 @@
 /*
  * Class:     sun_awt_UNIXToolkit
  * Method:    check_gtk
- * Signature: ()Z
+ * Signature: (I)Z
  */
 JNIEXPORT jboolean JNICALL
-Java_sun_awt_UNIXToolkit_check_1gtk(JNIEnv *env, jclass klass)
-{
+Java_sun_awt_UNIXToolkit_check_1gtk(JNIEnv *env, jclass klass, jint version) {
 #ifndef HEADLESS
-    return (jboolean)gtk2_check_version();
+    return (jboolean)gtk_check_version(version);
 #else
     return JNI_FALSE;
 #endif /* !HEADLESS */
@@ -61,13 +60,13 @@
 /*
  * Class:     sun_awt_UNIXToolkit
  * Method:    load_gtk
- * Signature: ()Z
+ * Signature: (I)Z
  */
 JNIEXPORT jboolean JNICALL
-Java_sun_awt_UNIXToolkit_load_1gtk(JNIEnv *env, jclass klass)
-{
+Java_sun_awt_UNIXToolkit_load_1gtk(JNIEnv *env, jclass klass, jint version,
+                                                             jboolean verbose) {
 #ifndef HEADLESS
-    return (jboolean)gtk2_load(env);
+    return (jboolean)gtk_load(env, version, verbose);
 #else
     return JNI_FALSE;
 #endif /* !HEADLESS */
@@ -83,16 +82,14 @@
 Java_sun_awt_UNIXToolkit_unload_1gtk(JNIEnv *env, jclass klass)
 {
 #ifndef HEADLESS
-    return (jboolean)gtk2_unload();
+    return (jboolean)gtk->unload();
 #else
     return JNI_FALSE;
 #endif /* !HEADLESS */
 }
 
-jboolean _icon_upcall(JNIEnv *env, jobject this, GdkPixbuf *pixbuf)
+jboolean init_method(JNIEnv *env, jobject this)
 {
-    jboolean result = JNI_FALSE;
-
     if (this_class == NULL) {
         this_class = (*env)->NewGlobalRef(env,
                                           (*env)->GetObjectClass(env, this));
@@ -100,33 +97,7 @@
                                  "loadIconCallback", "([BIIIIIZ)V");
         CHECK_NULL_RETURN(icon_upcall_method, JNI_FALSE);
     }
-
-    if (pixbuf != NULL)
-    {
-        guchar *pixbuf_data = (*fp_gdk_pixbuf_get_pixels)(pixbuf);
-        int row_stride = (*fp_gdk_pixbuf_get_rowstride)(pixbuf);
-        int width = (*fp_gdk_pixbuf_get_width)(pixbuf);
-        int height = (*fp_gdk_pixbuf_get_height)(pixbuf);
-        int bps = (*fp_gdk_pixbuf_get_bits_per_sample)(pixbuf);
-        int channels = (*fp_gdk_pixbuf_get_n_channels)(pixbuf);
-        gboolean alpha = (*fp_gdk_pixbuf_get_has_alpha)(pixbuf);
-
-        /* Copy the data array into a Java structure so we can pass it back. */
-        jbyteArray data = (*env)->NewByteArray(env, (row_stride * height));
-        JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
-
-        (*env)->SetByteArrayRegion(env, data, 0, (row_stride * height),
-                                   (jbyte *)pixbuf_data);
-
-        /* Release the pixbuf. */
-        (*fp_g_object_unref)(pixbuf);
-
-        /* Call the callback method to create the image on the Java side. */
-        (*env)->CallVoidMethod(env, this, icon_upcall_method, data,
-                width, height, row_stride, bps, channels, alpha);
-        result = JNI_TRUE;
-    }
-    return result;
+    return JNI_TRUE;
 }
 
 /*
@@ -144,7 +115,6 @@
     int len;
     char *filename_str = NULL;
     GError **error = NULL;
-    GdkPixbuf *pixbuf;
 
     if (filename == NULL)
     {
@@ -158,13 +128,17 @@
         JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
         return JNI_FALSE;
     }
+    if (!init_method(env, this) ) {
+        return JNI_FALSE;
+    }
     (*env)->GetStringUTFRegion(env, filename, 0, len, filename_str);
-    pixbuf = (*fp_gdk_pixbuf_new_from_file)(filename_str, error);
+    jboolean result = gtk->get_file_icon_data(env, filename_str, error,
+                                            icon_upcall_method, this);
 
     /* Release the strings we've allocated. */
     free(filename_str);
 
-    return _icon_upcall(env, this, pixbuf);
+    return result;
 #else /* HEADLESS */
     return JNI_FALSE;
 #endif /* !HEADLESS */
@@ -186,7 +160,6 @@
     int len;
     char *stock_id_str = NULL;
     char *detail_str = NULL;
-    GdkPixbuf *pixbuf;
 
     if (stock_id == NULL)
     {
@@ -215,8 +188,12 @@
         (*env)->GetStringUTFRegion(env, detail, 0, len, detail_str);
     }
 
-    pixbuf = gtk2_get_stock_icon(widget_type, stock_id_str, icon_size,
-                                 text_direction, detail_str);
+    if (!init_method(env, this) ) {
+        return JNI_FALSE;
+    }
+    jboolean result = gtk->get_icon_data(env, widget_type, stock_id_str,
+                  icon_size, text_direction, detail_str,
+                  icon_upcall_method, this);
 
     /* Release the strings we've allocated. */
     free(stock_id_str);
@@ -224,8 +201,7 @@
     {
         free(detail_str);
     }
-
-    return _icon_upcall(env, this, pixbuf);
+    return result;
 #else /* HEADLESS */
     return JNI_FALSE;
 #endif /* !HEADLESS */
@@ -279,11 +255,25 @@
 {
     char *ret;
 
-    ret = fp_gtk_check_version(major, minor, micro);
+    ret = gtk->gtk_check_version(major, minor, micro);
     if (ret == NULL) {
         return TRUE;
     }
 
-    free(ret);
     return FALSE;
 }
+
+/*
+ * Class:     sun_awt_UNIXToolkit
+ * Method:    get_gtk_version
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_sun_awt_UNIXToolkit_get_1gtk_1version(JNIEnv *env, jclass klass)
+{
+#ifndef HEADLESS
+    return gtk ? gtk->version : GTK_ANY;
+#else
+    return GTK_ANY;
+#endif /* !HEADLESS */
+}
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_util.c	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_util.c	Thu Apr 28 23:08:16 2016 -0700
@@ -29,7 +29,6 @@
 
 #include "awt_p.h"
 #include "color.h"
-#include <X11/IntrinsicP.h>
 #include <X11/Xatom.h>
 #include <X11/Xmd.h>
 #include <X11/Xutil.h>
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.c	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.c	Thu Apr 28 23:08:16 2016 -0700
@@ -35,52 +35,18 @@
 #include <jni_util.h>
 #include "awt.h"
 
-#define GTK2_LIB_VERSIONED VERSIONED_JNI_LIB_NAME("gtk-x11-2.0", "0")
-#define GTK2_LIB JNI_LIB_NAME("gtk-x11-2.0")
 #define GTHREAD_LIB_VERSIONED VERSIONED_JNI_LIB_NAME("gthread-2.0", "0")
 #define GTHREAD_LIB JNI_LIB_NAME("gthread-2.0")
 
-#define G_TYPE_INVALID                  G_TYPE_MAKE_FUNDAMENTAL (0)
-#define G_TYPE_NONE                     G_TYPE_MAKE_FUNDAMENTAL (1)
-#define G_TYPE_INTERFACE                G_TYPE_MAKE_FUNDAMENTAL (2)
-#define G_TYPE_CHAR                     G_TYPE_MAKE_FUNDAMENTAL (3)
-#define G_TYPE_UCHAR                    G_TYPE_MAKE_FUNDAMENTAL (4)
-#define G_TYPE_BOOLEAN                  G_TYPE_MAKE_FUNDAMENTAL (5)
-#define G_TYPE_INT                      G_TYPE_MAKE_FUNDAMENTAL (6)
-#define G_TYPE_UINT                     G_TYPE_MAKE_FUNDAMENTAL (7)
-#define G_TYPE_LONG                     G_TYPE_MAKE_FUNDAMENTAL (8)
-#define G_TYPE_ULONG                    G_TYPE_MAKE_FUNDAMENTAL (9)
-#define G_TYPE_INT64                    G_TYPE_MAKE_FUNDAMENTAL (10)
-#define G_TYPE_UINT64                   G_TYPE_MAKE_FUNDAMENTAL (11)
-#define G_TYPE_ENUM                     G_TYPE_MAKE_FUNDAMENTAL (12)
-#define G_TYPE_FLAGS                    G_TYPE_MAKE_FUNDAMENTAL (13)
-#define G_TYPE_FLOAT                    G_TYPE_MAKE_FUNDAMENTAL (14)
-#define G_TYPE_DOUBLE                   G_TYPE_MAKE_FUNDAMENTAL (15)
-#define G_TYPE_STRING                   G_TYPE_MAKE_FUNDAMENTAL (16)
-#define G_TYPE_POINTER                  G_TYPE_MAKE_FUNDAMENTAL (17)
-#define G_TYPE_BOXED                    G_TYPE_MAKE_FUNDAMENTAL (18)
-#define G_TYPE_PARAM                    G_TYPE_MAKE_FUNDAMENTAL (19)
-#define G_TYPE_OBJECT                   G_TYPE_MAKE_FUNDAMENTAL (20)
-
 #define GTK_TYPE_BORDER                 ((*fp_gtk_border_get_type)())
 
 #define G_TYPE_FUNDAMENTAL_SHIFT        (2)
 #define G_TYPE_MAKE_FUNDAMENTAL(x)      ((GType) ((x) << G_TYPE_FUNDAMENTAL_SHIFT))
-#define MIN(a, b)  (((a) < (b)) ? (a) : (b))
 
 #define CONV_BUFFER_SIZE 128
 
 #define NO_SYMBOL_EXCEPTION 1
 
-/* SynthConstants */
-const gint ENABLED    = 1 << 0;
-const gint MOUSE_OVER = 1 << 1;
-const gint PRESSED    = 1 << 2;
-const gint DISABLED   = 1 << 3;
-const gint FOCUSED    = 1 << 8;
-const gint SELECTED   = 1 << 9;
-const gint DEFAULT    = 1 << 10;
-
 static void *gtk2_libhandle = NULL;
 static void *gthread_libhandle = NULL;
 
@@ -105,54 +71,6 @@
 static gboolean new_combo = TRUE;
 const char ENV_PREFIX[] = "GTK_MODULES=";
 
-/*******************/
-enum GtkWidgetType
-{
-    _GTK_ARROW_TYPE,
-    _GTK_BUTTON_TYPE,
-    _GTK_CHECK_BUTTON_TYPE,
-    _GTK_CHECK_MENU_ITEM_TYPE,
-    _GTK_COLOR_SELECTION_DIALOG_TYPE,
-    _GTK_COMBO_BOX_TYPE,
-    _GTK_COMBO_BOX_ARROW_BUTTON_TYPE,
-    _GTK_COMBO_BOX_TEXT_FIELD_TYPE,
-    _GTK_CONTAINER_TYPE,
-    _GTK_ENTRY_TYPE,
-    _GTK_FRAME_TYPE,
-    _GTK_HANDLE_BOX_TYPE,
-    _GTK_HPANED_TYPE,
-    _GTK_HPROGRESS_BAR_TYPE,
-    _GTK_HSCALE_TYPE,
-    _GTK_HSCROLLBAR_TYPE,
-    _GTK_HSEPARATOR_TYPE,
-    _GTK_IMAGE_TYPE,
-    _GTK_MENU_TYPE,
-    _GTK_MENU_BAR_TYPE,
-    _GTK_MENU_ITEM_TYPE,
-    _GTK_NOTEBOOK_TYPE,
-    _GTK_LABEL_TYPE,
-    _GTK_RADIO_BUTTON_TYPE,
-    _GTK_RADIO_MENU_ITEM_TYPE,
-    _GTK_SCROLLED_WINDOW_TYPE,
-    _GTK_SEPARATOR_MENU_ITEM_TYPE,
-    _GTK_SEPARATOR_TOOL_ITEM_TYPE,
-    _GTK_SPIN_BUTTON_TYPE,
-    _GTK_TEXT_VIEW_TYPE,
-    _GTK_TOGGLE_BUTTON_TYPE,
-    _GTK_TOOLBAR_TYPE,
-    _GTK_TOOLTIP_TYPE,
-    _GTK_TREE_VIEW_TYPE,
-    _GTK_VIEWPORT_TYPE,
-    _GTK_VPANED_TYPE,
-    _GTK_VPROGRESS_BAR_TYPE,
-    _GTK_VSCALE_TYPE,
-    _GTK_VSCROLLBAR_TYPE,
-    _GTK_VSEPARATOR_TYPE,
-    _GTK_WINDOW_TYPE,
-    _GTK_DIALOG_TYPE,
-    _GTK_WIDGET_TYPE_SIZE
-};
-
 
 static GtkWidget *gtk2_widgets[_GTK_WIDGET_TYPE_SIZE];
 
@@ -359,20 +277,6 @@
 static GtkAdjustment* (*fp_gtk_range_get_adjustment)(GtkRange* range);
 
 /* Method bodies */
-const char *getStrFor(JNIEnv *env, jstring val)
-{
-    int length = (*env)->GetStringLength(env, val);
-    if (length > CONV_BUFFER_SIZE-1)
-    {
-        length = CONV_BUFFER_SIZE-1;
-#ifdef DEBUG
-        fprintf(stderr, "Note: Detail is too long: %d chars\n", length);
-#endif /* DEBUG */
-    }
-
-    (*env)->GetStringUTFRegion(env, val, 0, length, convertionBuffer);
-    return convertionBuffer;
-}
 
 static void throw_exception(JNIEnv *env, const char* name, const char* message)
 {
@@ -408,33 +312,34 @@
     return result;
 }
 
-gboolean gtk2_check_version()
+gboolean gtk2_check(const char* lib_name, int flags)
 {
     if (gtk2_libhandle != NULL) {
         /* We've already successfully opened the GTK libs, so return true. */
         return TRUE;
     } else {
         void *lib = NULL;
-        gboolean result = FALSE;
 
-        lib = dlopen(GTK2_LIB_VERSIONED, RTLD_LAZY | RTLD_LOCAL);
+        lib = dlopen(lib_name, flags);
+
         if (lib == NULL) {
-            lib = dlopen(GTK2_LIB, RTLD_LAZY | RTLD_LOCAL);
-            if (lib == NULL) {
-                return FALSE;
-            }
+            return FALSE;
+        }
+
+        if (flags & RTLD_NOLOAD) {
+            return TRUE;
         }
 
         fp_gtk_check_version = dlsym(lib, "gtk_check_version");
         /* Check for GTK 2.2+ */
         if (!fp_gtk_check_version(2, 2, 0)) {
-            result = TRUE;
+            return TRUE;
         }
 
         // 8048289: workaround for https://bugzilla.gnome.org/show_bug.cgi?id=733065
         // dlclose(lib);
 
-        return result;
+        return FALSE;
     }
 }
 
@@ -450,7 +355,7 @@
 } while(0);
 
 
-void update_supported_actions(JNIEnv *env) {
+static void update_supported_actions(JNIEnv *env) {
     GVfs * (*fp_g_vfs_get_default) (void);
     const gchar * const * (*fp_g_vfs_get_supported_uri_schemes) (GVfs * vfs);
     const gchar * const * schemes = NULL;
@@ -513,7 +418,7 @@
 /**
  * Functions for awt_Desktop.c
  */
-gboolean gtk2_show_uri_load(JNIEnv *env) {
+static gboolean gtk2_show_uri_load(JNIEnv *env) {
      gboolean success = FALSE;
      dlerror();
      const char *gtk_version = fp_gtk_check_version(2, 14, 0);
@@ -537,6 +442,7 @@
              fprintf(stderr, "dlsym(gtk_show_uri) returned NULL\n");
 #endif /* DEBUG */
         } else {
+            gtk->gtk_show_uri = fp_gtk_show_uri;
             update_supported_actions(env);
             success = TRUE;
         }
@@ -547,7 +453,7 @@
 /**
  * Functions for sun_awt_X11_GtkFileDialogPeer.c
  */
-void gtk2_file_chooser_load()
+static void gtk2_file_chooser_load()
 {
     fp_gtk_file_chooser_get_filename = dl_symbol(
             "gtk_file_chooser_get_filename");
@@ -576,7 +482,7 @@
     fp_gdk_x11_drawable_get_xid = dl_symbol("gdk_x11_drawable_get_xid");
 }
 
-gboolean gtk2_load(JNIEnv *env)
+GtkApi* gtk2_load(JNIEnv *env, const char* lib_name)
 {
     gboolean result;
     int i;
@@ -584,11 +490,9 @@
     int (*io_handler)();
     char *gtk_modules_env;
 
-    gtk2_libhandle = dlopen(GTK2_LIB_VERSIONED, RTLD_LAZY | RTLD_LOCAL);
+    gtk2_libhandle = dlopen(lib_name, RTLD_LAZY | RTLD_LOCAL);
     if (gtk2_libhandle == NULL) {
-        gtk2_libhandle = dlopen(GTK2_LIB, RTLD_LAZY | RTLD_LOCAL);
-        if (gtk2_libhandle == NULL)
-            return FALSE;
+        return FALSE;
     }
 
     gthread_libhandle = dlopen(GTHREAD_LIB_VERSIONED, RTLD_LAZY | RTLD_LOCAL);
@@ -962,8 +866,12 @@
     {
         gtk2_widgets[i] = NULL;
     }
-
-    return result;
+    if (result) {
+        GtkApi* gtk = (GtkApi*)malloc(sizeof(GtkApi));
+        gtk2_init(gtk);
+        return gtk;
+    }
+    return NULL;
 }
 
 int gtk2_unload()
@@ -1007,7 +915,7 @@
 /* Dispatch all pending events from the GTK event loop.
  * This is needed to catch theme change and update widgets' style.
  */
-void flush_gtk_event_loop()
+static void flush_gtk_event_loop()
 {
     while( (*fp_g_main_context_iteration)(NULL, FALSE));
 }
@@ -1056,7 +964,7 @@
  * comparing results. This can be optimized by using subclassed pixmap and
  * doing the second drawing only if necessary.
 */
-void gtk2_init_painting(JNIEnv *env, gint width, gint height)
+static void gtk2_init_painting(JNIEnv *env, gint width, gint height)
 {
     GdkGC *gc;
     GdkPixbuf *white, *black;
@@ -1116,7 +1024,7 @@
  * one of java_awt_Transparency_OPAQUE, java_awt_Transparency_BITMASK, and
  * java_awt_Transparency_TRANSLUCENT.
  */
-gint gtk2_copy_image(gint *dst, gint width, gint height)
+static gint gtk2_copy_image(gint *dst, gint width, gint height)
 {
     gint i, j, r, g, b;
     guchar *white, *black;
@@ -1778,7 +1686,7 @@
             x, y, w, h);
 }
 
-void gtk2_paint_box(WidgetType widget_type, GtkStateType state_type,
+static void gtk2_paint_box(WidgetType widget_type, GtkStateType state_type,
                     GtkShadowType shadow_type, const gchar *detail,
                     gint x, gint y, gint width, gint height,
                     gint synth_state, GtkTextDirection dir)
@@ -1948,7 +1856,7 @@
             x, y, width, height, gap_side, gap_x, gap_width);
 }
 
-void gtk2_paint_check(WidgetType widget_type, gint synth_state,
+static void gtk2_paint_check(WidgetType widget_type, gint synth_state,
         const gchar *detail, gint x, gint y, gint width, gint height)
 {
     GtkStateType state_type = get_gtk_state_type(widget_type, synth_state);
@@ -1965,7 +1873,7 @@
             x, y, width, height);
 }
 
-void gtk2_paint_diamond(WidgetType widget_type, GtkStateType state_type,
+static void gtk2_paint_diamond(WidgetType widget_type, GtkStateType state_type,
         GtkShadowType shadow_type, const gchar *detail,
         gint x, gint y, gint width, gint height)
 {
@@ -1978,7 +1886,7 @@
             x, y, width, height);
 }
 
-void gtk2_paint_expander(WidgetType widget_type, GtkStateType state_type,
+static void gtk2_paint_expander(WidgetType widget_type, GtkStateType state_type,
         const gchar *detail, gint x, gint y, gint width, gint height,
         GtkExpanderStyle expander_style)
 {
@@ -1991,7 +1899,7 @@
             x + width / 2, y + height / 2, expander_style);
 }
 
-void gtk2_paint_extension(WidgetType widget_type, GtkStateType state_type,
+static void gtk2_paint_extension(WidgetType widget_type, GtkStateType state_type,
         GtkShadowType shadow_type, const gchar *detail,
         gint x, gint y, gint width, gint height, GtkPositionType gap_side)
 {
@@ -2004,7 +1912,7 @@
             x, y, width, height, gap_side);
 }
 
-void gtk2_paint_flat_box(WidgetType widget_type, GtkStateType state_type,
+static void gtk2_paint_flat_box(WidgetType widget_type, GtkStateType state_type,
         GtkShadowType shadow_type, const gchar *detail,
         gint x, gint y, gint width, gint height, gboolean has_focus)
 {
@@ -2023,7 +1931,7 @@
             x, y, width, height);
 }
 
-void gtk2_paint_focus(WidgetType widget_type, GtkStateType state_type,
+static void gtk2_paint_focus(WidgetType widget_type, GtkStateType state_type,
         const char *detail, gint x, gint y, gint width, gint height)
 {
     gtk2_widget = gtk2_get_widget(widget_type);
@@ -2033,7 +1941,7 @@
             NULL, gtk2_widget, detail, x, y, width, height);
 }
 
-void gtk2_paint_handle(WidgetType widget_type, GtkStateType state_type,
+static void gtk2_paint_handle(WidgetType widget_type, GtkStateType state_type,
         GtkShadowType shadow_type, const gchar *detail,
         gint x, gint y, gint width, gint height, GtkOrientation orientation)
 {
@@ -2046,7 +1954,7 @@
             x, y, width, height, orientation);
 }
 
-void gtk2_paint_hline(WidgetType widget_type, GtkStateType state_type,
+static void gtk2_paint_hline(WidgetType widget_type, GtkStateType state_type,
         const gchar *detail, gint x, gint y, gint width, gint height)
 {
     gtk2_widget = gtk2_get_widget(widget_type);
@@ -2056,7 +1964,7 @@
             NULL, gtk2_widget, detail, x, x + width, y);
 }
 
-void gtk2_paint_option(WidgetType widget_type, gint synth_state,
+static void gtk2_paint_option(WidgetType widget_type, gint synth_state,
         const gchar *detail, gint x, gint y, gint width, gint height)
 {
     GtkStateType state_type = get_gtk_state_type(widget_type, synth_state);
@@ -2073,7 +1981,7 @@
             x, y, width, height);
 }
 
-void gtk2_paint_shadow(WidgetType widget_type, GtkStateType state_type,
+static void gtk2_paint_shadow(WidgetType widget_type, GtkStateType state_type,
                        GtkShadowType shadow_type, const gchar *detail,
                        gint x, gint y, gint width, gint height,
                        gint synth_state, GtkTextDirection dir)
@@ -2123,9 +2031,10 @@
     gtk2_set_direction(gtk2_widget, GTK_TEXT_DIR_LTR);
 }
 
-void gtk2_paint_slider(WidgetType widget_type, GtkStateType state_type,
+static void gtk2_paint_slider(WidgetType widget_type, GtkStateType state_type,
         GtkShadowType shadow_type, const gchar *detail,
-        gint x, gint y, gint width, gint height, GtkOrientation orientation)
+        gint x, gint y, gint width, gint height, GtkOrientation orientation,
+        gboolean has_focus)
 {
     gtk2_widget = gtk2_get_widget(widget_type);
     (*fp_gtk_paint_slider)(gtk2_widget->style, gtk2_white_pixmap, state_type,
@@ -2136,7 +2045,7 @@
             x, y, width, height, orientation);
 }
 
-void gtk2_paint_vline(WidgetType widget_type, GtkStateType state_type,
+static void gtk2_paint_vline(WidgetType widget_type, GtkStateType state_type,
         const gchar *detail, gint x, gint y, gint width, gint height)
 {
     gtk2_widget = gtk2_get_widget(widget_type);
@@ -2146,7 +2055,7 @@
             NULL, gtk2_widget, detail, y, y + height, x);
 }
 
-void gtk_paint_background(WidgetType widget_type, GtkStateType state_type,
+static void gtk_paint_background(WidgetType widget_type, GtkStateType state_type,
         gint x, gint y, gint width, gint height)
 {
     gtk2_widget = gtk2_get_widget(widget_type);
@@ -2156,7 +2065,7 @@
             gtk2_black_pixmap, TRUE, state_type, NULL, x, y, width, height);
 }
 
-GdkPixbuf *gtk2_get_stock_icon(gint widget_type, const gchar *stock_id,
+static GdkPixbuf *gtk2_get_stock_icon(gint widget_type, const gchar *stock_id,
         GtkIconSize size, GtkTextDirection direction, const char *detail)
 {
     init_containers();
@@ -2166,8 +2075,52 @@
     return (*fp_gtk_widget_render_icon)(gtk2_widget, stock_id, size, detail);
 }
 
+static jboolean gtk2_get_pixbuf_data(JNIEnv *env, GdkPixbuf* pixbuf,
+                              jmethodID icon_upcall_method, jobject this) {
+    if (!pixbuf) {
+        return JNI_FALSE;
+    }
+    guchar *pixbuf_data = (*fp_gdk_pixbuf_get_pixels)(pixbuf);
+    if (pixbuf_data) {
+        int row_stride = (*fp_gdk_pixbuf_get_rowstride)(pixbuf);
+        int width = (*fp_gdk_pixbuf_get_width)(pixbuf);
+        int height = (*fp_gdk_pixbuf_get_height)(pixbuf);
+        int bps = (*fp_gdk_pixbuf_get_bits_per_sample)(pixbuf);
+        int channels = (*fp_gdk_pixbuf_get_n_channels)(pixbuf);
+        gboolean alpha = (*fp_gdk_pixbuf_get_has_alpha)(pixbuf);
+
+        jbyteArray data = (*env)->NewByteArray(env, (row_stride * height));
+        JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
+
+        (*env)->SetByteArrayRegion(env, data, 0, (row_stride * height),
+                                   (jbyte *)pixbuf_data);
+        (*fp_g_object_unref)(pixbuf);
+
+        /* Call the callback method to create the image on the Java side. */
+        (*env)->CallVoidMethod(env, this, icon_upcall_method, data,
+                width, height, row_stride, bps, channels, alpha);
+        return JNI_TRUE;
+    }
+    return JNI_FALSE;
+}
+
+static jboolean gtk2_get_file_icon_data(JNIEnv *env, const char *filename,
+                 GError **error, jmethodID icon_upcall_method, jobject this) {
+    GdkPixbuf* pixbuf = fp_gdk_pixbuf_new_from_file(filename, error);
+    return gtk2_get_pixbuf_data(env, pixbuf, icon_upcall_method, this);
+}
+
+static jboolean gtk2_get_icon_data(JNIEnv *env, gint widget_type,
+                              const gchar *stock_id, GtkIconSize size,
+                              GtkTextDirection direction, const char *detail,
+                              jmethodID icon_upcall_method, jobject this) {
+    GdkPixbuf* pixbuf = gtk2_get_stock_icon(widget_type, stock_id, size,
+                                       direction, detail);
+    return gtk2_get_pixbuf_data(env, pixbuf, icon_upcall_method, this);
+}
+
 /*************************************************/
-gint gtk2_get_xthickness(JNIEnv *env, WidgetType widget_type)
+static gint gtk2_get_xthickness(JNIEnv *env, WidgetType widget_type)
 {
     init_containers();
 
@@ -2176,7 +2129,7 @@
     return style->xthickness;
 }
 
-gint gtk2_get_ythickness(JNIEnv *env, WidgetType widget_type)
+static gint gtk2_get_ythickness(JNIEnv *env, WidgetType widget_type)
 {
     init_containers();
 
@@ -2186,12 +2139,12 @@
 }
 
 /*************************************************/
-guint8 recode_color(guint16 channel)
+static guint8 recode_color(guint16 channel)
 {
     return (guint8)(channel>>8);
 }
 
-gint gtk2_get_color_for_state(JNIEnv *env, WidgetType widget_type,
+static gint gtk2_get_color_for_state(JNIEnv *env, WidgetType widget_type,
                               GtkStateType state_type, ColorType color_type)
 {
     gint result = 0;
@@ -2243,19 +2196,19 @@
 }
 
 /*************************************************/
-jobject create_Boolean(JNIEnv *env, jboolean boolean_value);
-jobject create_Integer(JNIEnv *env, jint int_value);
-jobject create_Long(JNIEnv *env, jlong long_value);
-jobject create_Float(JNIEnv *env, jfloat float_value);
-jobject create_Double(JNIEnv *env, jdouble double_value);
-jobject create_Character(JNIEnv *env, jchar char_value);
-jobject create_Insets(JNIEnv *env, GtkBorder *border);
+static jobject create_Boolean(JNIEnv *env, jboolean boolean_value);
+static jobject create_Integer(JNIEnv *env, jint int_value);
+static jobject create_Long(JNIEnv *env, jlong long_value);
+static jobject create_Float(JNIEnv *env, jfloat float_value);
+static jobject create_Double(JNIEnv *env, jdouble double_value);
+static jobject create_Character(JNIEnv *env, jchar char_value);
+static jobject create_Insets(JNIEnv *env, GtkBorder *border);
 
-jobject gtk2_get_class_value(JNIEnv *env, WidgetType widget_type, jstring jkey)
+static jobject gtk2_get_class_value(JNIEnv *env, WidgetType widget_type,
+                              const char* key)
 {
     init_containers();
 
-    const char* key = getStrFor(env, jkey);
     gtk2_widget = gtk2_get_widget(widget_type);
 
     GValue value;
@@ -2376,7 +2329,7 @@
     return NULL;
 }
 
-void gtk2_set_range_value(WidgetType widget_type, jdouble value,
+static void gtk2_set_range_value(WidgetType widget_type, jdouble value,
                           jdouble min, jdouble max, jdouble visible)
 {
     GtkAdjustment *adj;
@@ -2391,7 +2344,7 @@
 }
 
 /*************************************************/
-jobject create_Object(JNIEnv *env, jmethodID *cid,
+static jobject create_Object(JNIEnv *env, jmethodID *cid,
                              const char* class_name,
                              const char* signature,
                              jvalue* value)
@@ -2494,7 +2447,7 @@
 }
 
 /*********************************************/
-jstring gtk2_get_pango_font_name(JNIEnv *env, WidgetType widget_type)
+static jstring gtk2_get_pango_font_name(JNIEnv *env, WidgetType widget_type)
 {
     init_containers();
 
@@ -2513,7 +2466,7 @@
 }
 
 /***********************************************/
-jobject get_string_property(JNIEnv *env, GtkSettings* settings, const gchar* key)
+static jobject get_string_property(JNIEnv *env, GtkSettings* settings, const gchar* key)
 {
     jobject result = NULL;
     gchar*  strval = NULL;
@@ -2525,21 +2478,21 @@
     return result;
 }
 
-jobject get_integer_property(JNIEnv *env, GtkSettings* settings, const gchar* key)
+static jobject get_integer_property(JNIEnv *env, GtkSettings* settings, const gchar* key)
 {
     gint intval = NULL;
     (*fp_g_object_get)(settings, key, &intval, NULL);
     return create_Integer(env, intval);
 }
 
-jobject get_boolean_property(JNIEnv *env, GtkSettings* settings, const gchar* key)
+static jobject get_boolean_property(JNIEnv *env, GtkSettings* settings, const gchar* key)
 {
     gint intval = NULL;
     (*fp_g_object_get)(settings, key, &intval, NULL);
     return create_Boolean(env, intval);
 }
 
-jobject gtk2_get_setting(JNIEnv *env, Setting property)
+static jobject gtk2_get_setting(JNIEnv *env, Setting property)
 {
     GtkSettings* settings = (*fp_gtk_settings_get_default)();
 
@@ -2557,3 +2510,148 @@
 
     return NULL;
 }
+
+static gboolean gtk2_get_drawable_data(JNIEnv *env, jintArray pixelArray, jint x,
+     jint y, jint width, jint height, jint jwidth, int dx, int dy, jint scale) {
+    GdkPixbuf *pixbuf;
+    jint *ary;
+
+    GdkWindow *root = (*fp_gdk_get_default_root_window)();
+
+    pixbuf = (*fp_gdk_pixbuf_get_from_drawable)(NULL, root, NULL, x, y,
+                                                    0, 0, width, height);
+    if (pixbuf && scale != 1) {
+        GdkPixbuf *scaledPixbuf;
+        x /= scale;
+        y /= scale;
+        width /= scale;
+        height /= scale;
+        dx /= scale;
+        dy /= scale;
+        scaledPixbuf = (*fp_gdk_pixbuf_scale_simple)(pixbuf, width, height,
+                                                     GDK_INTERP_BILINEAR);
+        (*fp_g_object_unref)(pixbuf);
+        pixbuf = scaledPixbuf;
+    }
+
+    if (pixbuf) {
+        int nchan = (*fp_gdk_pixbuf_get_n_channels)(pixbuf);
+        int stride = (*fp_gdk_pixbuf_get_rowstride)(pixbuf);
+
+        if ((*fp_gdk_pixbuf_get_width)(pixbuf) == width
+                && (*fp_gdk_pixbuf_get_height)(pixbuf) == height
+                && (*fp_gdk_pixbuf_get_bits_per_sample)(pixbuf) == 8
+                && (*fp_gdk_pixbuf_get_colorspace)(pixbuf) == GDK_COLORSPACE_RGB
+                && nchan >= 3
+                ) {
+            guchar *p, *pix = (*fp_gdk_pixbuf_get_pixels)(pixbuf);
+
+            ary = (*env)->GetPrimitiveArrayCritical(env, pixelArray, NULL);
+            if (ary) {
+                jint _x, _y;
+                int index;
+                for (_y = 0; _y < height; _y++) {
+                    for (_x = 0; _x < width; _x++) {
+                        p = pix + _y * stride + _x * nchan;
+
+                        index = (_y + dy) * jwidth + (_x + dx);
+                        ary[index] = 0xff000000
+                                        | (p[0] << 16)
+                                        | (p[1] << 8)
+                                        | (p[2]);
+
+                    }
+                }
+                (*env)->ReleasePrimitiveArrayCritical(env, pixelArray, ary, 0);
+            }
+        }
+        (*fp_g_object_unref)(pixbuf);
+    }
+    return JNI_FALSE;
+}
+
+static GdkWindow* gtk2_get_window(void *widget) {
+    return ((GtkWidget*)widget)->window;
+}
+
+void gtk2_init(GtkApi* gtk) {
+    gtk->version = GTK_2;
+
+    gtk->show_uri_load = &gtk2_show_uri_load;
+    gtk->unload = &gtk2_unload;
+    gtk->flush_event_loop = &flush_gtk_event_loop;
+    gtk->gtk_check_version = fp_gtk_check_version;
+    gtk->get_setting = &gtk2_get_setting;
+
+    gtk->paint_arrow = &gtk2_paint_arrow;
+    gtk->paint_box = &gtk2_paint_box;
+    gtk->paint_box_gap = &gtk2_paint_box_gap;
+    gtk->paint_expander = &gtk2_paint_expander;
+    gtk->paint_extension = &gtk2_paint_extension;
+    gtk->paint_flat_box = &gtk2_paint_flat_box;
+    gtk->paint_focus = &gtk2_paint_focus;
+    gtk->paint_handle = &gtk2_paint_handle;
+    gtk->paint_hline = &gtk2_paint_hline;
+    gtk->paint_vline = &gtk2_paint_vline;
+    gtk->paint_option = &gtk2_paint_option;
+    gtk->paint_shadow = &gtk2_paint_shadow;
+    gtk->paint_slider = &gtk2_paint_slider;
+    gtk->paint_background = &gtk_paint_background;
+    gtk->paint_check = &gtk2_paint_check;
+    gtk->set_range_value = &gtk2_set_range_value;
+
+    gtk->init_painting = &gtk2_init_painting;
+    gtk->copy_image = &gtk2_copy_image;
+
+    gtk->get_xthickness = &gtk2_get_xthickness;
+    gtk->get_ythickness = &gtk2_get_ythickness;
+    gtk->get_color_for_state = &gtk2_get_color_for_state;
+    gtk->get_class_value = &gtk2_get_class_value;
+
+    gtk->get_pango_font_name = &gtk2_get_pango_font_name;
+    gtk->get_icon_data = &gtk2_get_icon_data;
+    gtk->get_file_icon_data = &gtk2_get_file_icon_data;
+    gtk->gdk_threads_enter = fp_gdk_threads_enter;
+    gtk->gdk_threads_leave = fp_gdk_threads_leave;
+    gtk->gtk_show_uri = fp_gtk_show_uri;
+    gtk->get_drawable_data = &gtk2_get_drawable_data;
+    gtk->g_free = fp_g_free;
+
+    gtk->gtk_file_chooser_get_filename = fp_gtk_file_chooser_get_filename;
+    gtk->gtk_widget_hide = fp_gtk_widget_hide;
+    gtk->gtk_main_quit = fp_gtk_main_quit;
+    gtk->gtk_file_chooser_dialog_new = fp_gtk_file_chooser_dialog_new;
+    gtk->gtk_file_chooser_set_current_folder =
+                          fp_gtk_file_chooser_set_current_folder;
+    gtk->gtk_file_chooser_set_filename = fp_gtk_file_chooser_set_filename;
+    gtk->gtk_file_chooser_set_current_name =
+                          fp_gtk_file_chooser_set_current_name;
+    gtk->gtk_file_filter_add_custom = fp_gtk_file_filter_add_custom;
+    gtk->gtk_file_chooser_set_filter = fp_gtk_file_chooser_set_filter;
+    gtk->gtk_file_chooser_get_type = fp_gtk_file_chooser_get_type;
+    gtk->gtk_file_filter_new = fp_gtk_file_filter_new;
+    gtk->gtk_file_chooser_set_do_overwrite_confirmation =
+                          fp_gtk_file_chooser_set_do_overwrite_confirmation;
+    gtk->gtk_file_chooser_set_select_multiple =
+                          fp_gtk_file_chooser_set_select_multiple;
+    gtk->gtk_file_chooser_get_current_folder =
+                          fp_gtk_file_chooser_get_current_folder;
+    gtk->gtk_file_chooser_get_filenames = fp_gtk_file_chooser_get_filenames;
+    gtk->gtk_g_slist_length = fp_gtk_g_slist_length;
+    gtk->g_signal_connect_data = fp_g_signal_connect_data;
+    gtk->gtk_widget_show = fp_gtk_widget_show;
+    gtk->gtk_main = fp_gtk_main;
+    gtk->gtk_main_level = fp_gtk_main_level;
+    gtk->g_path_get_dirname = fp_g_path_get_dirname;
+    gtk->gdk_x11_drawable_get_xid = fp_gdk_x11_drawable_get_xid;
+    gtk->gtk_widget_destroy = fp_gtk_widget_destroy;
+    gtk->gtk_window_present = fp_gtk_window_present;
+    gtk->gtk_window_move = fp_gtk_window_move;
+    gtk->gtk_window_resize = fp_gtk_window_resize;
+    gtk->get_window = &gtk2_get_window;
+
+    gtk->g_object_unref = fp_g_object_unref;
+    gtk->g_list_append = fp_g_list_append;
+    gtk->g_list_free = fp_g_list_free;
+    gtk->g_list_free_full = fp_g_list_free_full;
+}
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h	Thu Apr 28 23:08:16 2016 -0700
@@ -28,232 +28,11 @@
 #include <stdlib.h>
 #include <jni.h>
 #include <X11/X.h>
-
-#define _G_TYPE_CIC(ip, gt, ct)       ((ct*) ip)
-#define G_TYPE_CHECK_INSTANCE_CAST(instance, g_type, c_type)    (_G_TYPE_CIC ((instance), (g_type), c_type))
-#define GTK_TYPE_FILE_CHOOSER             (fp_gtk_file_chooser_get_type ())
-#define GTK_FILE_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FILE_CHOOSER, GtkFileChooser))
-#define fp_g_signal_connect(instance, detailed_signal, c_handler, data) \
-    fp_g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0)
-#define G_CALLBACK(f) ((GCallback) (f))
-#define G_TYPE_FUNDAMENTAL_SHIFT (2)
-#define G_TYPE_MAKE_FUNDAMENTAL(x) ((GType) ((x) << G_TYPE_FUNDAMENTAL_SHIFT))
-#define G_TYPE_OBJECT G_TYPE_MAKE_FUNDAMENTAL (20)
-#define G_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), G_TYPE_OBJECT, GObject))
-#define GTK_STOCK_CANCEL           "gtk-cancel"
-#define GTK_STOCK_SAVE             "gtk-save"
-#define GTK_STOCK_OPEN             "gtk-open"
-#define GDK_CURRENT_TIME           0L
-
-typedef enum _WidgetType
-{
-    BUTTON,                     /* GtkButton */
-    CHECK_BOX,                  /* GtkCheckButton */
-    CHECK_BOX_MENU_ITEM,        /* GtkCheckMenuItem */
-    COLOR_CHOOSER,              /* GtkColorSelectionDialog */
-    COMBO_BOX,                  /* GtkComboBox */
-    COMBO_BOX_ARROW_BUTTON,     /* GtkComboBoxEntry */
-    COMBO_BOX_TEXT_FIELD,       /* GtkComboBoxEntry */
-    DESKTOP_ICON,               /* GtkLabel */
-    DESKTOP_PANE,               /* GtkContainer */
-    EDITOR_PANE,                /* GtkTextView */
-    FORMATTED_TEXT_FIELD,       /* GtkEntry */
-    HANDLE_BOX,                 /* GtkHandleBox */
-    HPROGRESS_BAR,              /* GtkProgressBar */
-    HSCROLL_BAR,                /* GtkHScrollbar */
-    HSCROLL_BAR_BUTTON_LEFT,    /* GtkHScrollbar */
-    HSCROLL_BAR_BUTTON_RIGHT,   /* GtkHScrollbar */
-    HSCROLL_BAR_TRACK,          /* GtkHScrollbar */
-    HSCROLL_BAR_THUMB,          /* GtkHScrollbar */
-    HSEPARATOR,                 /* GtkHSeparator */
-    HSLIDER,                    /* GtkHScale */
-    HSLIDER_TRACK,              /* GtkHScale */
-    HSLIDER_THUMB,              /* GtkHScale */
-    HSPLIT_PANE_DIVIDER,        /* GtkHPaned */
-    INTERNAL_FRAME,             /* GtkWindow */
-    INTERNAL_FRAME_TITLE_PANE,  /* GtkLabel */
-    IMAGE,                      /* GtkImage */
-    LABEL,                      /* GtkLabel */
-    LIST,                       /* GtkTreeView */
-    MENU,                       /* GtkMenu */
-    MENU_BAR,                   /* GtkMenuBar */
-    MENU_ITEM,                  /* GtkMenuItem */
-    MENU_ITEM_ACCELERATOR,      /* GtkLabel */
-    OPTION_PANE,                /* GtkMessageDialog */
-    PANEL,                      /* GtkContainer */
-    PASSWORD_FIELD,             /* GtkEntry */
-    POPUP_MENU,                 /* GtkMenu */
-    POPUP_MENU_SEPARATOR,       /* GtkSeparatorMenuItem */
-    RADIO_BUTTON,               /* GtkRadioButton */
-    RADIO_BUTTON_MENU_ITEM,     /* GtkRadioMenuItem */
-    ROOT_PANE,                  /* GtkContainer */
-    SCROLL_PANE,                /* GtkScrolledWindow */
-    SPINNER,                    /* GtkSpinButton */
-    SPINNER_ARROW_BUTTON,       /* GtkSpinButton */
-    SPINNER_TEXT_FIELD,         /* GtkSpinButton */
-    SPLIT_PANE,                 /* GtkPaned */
-    TABBED_PANE,                /* GtkNotebook */
-    TABBED_PANE_TAB_AREA,       /* GtkNotebook */
-    TABBED_PANE_CONTENT,        /* GtkNotebook */
-    TABBED_PANE_TAB,            /* GtkNotebook */
-    TABLE,                      /* GtkTreeView */
-    TABLE_HEADER,               /* GtkButton */
-    TEXT_AREA,                  /* GtkTextView */
-    TEXT_FIELD,                 /* GtkEntry */
-    TEXT_PANE,                  /* GtkTextView */
-    TITLED_BORDER,              /* GtkFrame */
-    TOGGLE_BUTTON,              /* GtkToggleButton */
-    TOOL_BAR,                   /* GtkToolbar */
-    TOOL_BAR_DRAG_WINDOW,       /* GtkToolbar */
-    TOOL_BAR_SEPARATOR,         /* GtkSeparatorToolItem */
-    TOOL_TIP,                   /* GtkWindow */
-    TREE,                       /* GtkTreeView */
-    TREE_CELL,                  /* GtkTreeView */
-    VIEWPORT,                   /* GtkViewport */
-    VPROGRESS_BAR,              /* GtkProgressBar */
-    VSCROLL_BAR,                /* GtkVScrollbar */
-    VSCROLL_BAR_BUTTON_UP,      /* GtkVScrollbar */
-    VSCROLL_BAR_BUTTON_DOWN,    /* GtkVScrollbar */
-    VSCROLL_BAR_TRACK,          /* GtkVScrollbar */
-    VSCROLL_BAR_THUMB,          /* GtkVScrollbar */
-    VSEPARATOR,                 /* GtkVSeparator */
-    VSLIDER,                    /* GtkVScale */
-    VSLIDER_TRACK,              /* GtkVScale */
-    VSLIDER_THUMB,              /* GtkVScale */
-    VSPLIT_PANE_DIVIDER,        /* GtkVPaned */
-    WIDGET_TYPE_SIZE
-} WidgetType;
-
-typedef enum _ColorType
-{
-    FOREGROUND,
-    BACKGROUND,
-    TEXT_FOREGROUND,
-    TEXT_BACKGROUND,
-    FOCUS,
-    LIGHT,
-    DARK,
-    MID,
-    BLACK,
-    WHITE
-} ColorType;
-
-typedef enum _Setting
-{
-    GTK_FONT_NAME,
-    GTK_ICON_SIZES,
-    GTK_CURSOR_BLINK,
-    GTK_CURSOR_BLINK_TIME
-} Setting;
-
-/* GTK types, here to eliminate need for GTK headers at compile time */
-
-#ifndef FALSE
-#define FALSE           (0)
-#define TRUE            (!FALSE)
-#endif
+#include "gtk_interface.h"
 
 #define GTK_HAS_FOCUS   (1 << 12)
 #define GTK_HAS_DEFAULT (1 << 14)
 
-
-/* basic types */
-typedef char    gchar;
-typedef short   gshort;
-typedef int     gint;
-typedef long    glong;
-typedef float   gfloat;
-typedef double  gdouble;
-typedef void*   gpointer;
-typedef gint    gboolean;
-
-typedef signed char  gint8;
-typedef signed short gint16;
-typedef signed int   gint32;
-
-typedef unsigned char  guchar;
-typedef unsigned char  guint8;
-typedef unsigned short gushort;
-typedef unsigned short guint16;
-typedef unsigned int   guint;
-typedef unsigned int   guint32;
-typedef unsigned int   gsize;
-typedef unsigned long  gulong;
-
-typedef signed long long   gint64;
-typedef unsigned long long guint64;
-
-/* enumerated constants */
-typedef enum
-{
-  GTK_ARROW_UP,
-  GTK_ARROW_DOWN,
-  GTK_ARROW_LEFT,
-  GTK_ARROW_RIGHT
-} GtkArrowType;
-
-typedef enum {
-  GDK_COLORSPACE_RGB
-} GdkColorspace;
-
-typedef enum
-{
-  GTK_EXPANDER_COLLAPSED,
-  GTK_EXPANDER_SEMI_COLLAPSED,
-  GTK_EXPANDER_SEMI_EXPANDED,
-  GTK_EXPANDER_EXPANDED
-} GtkExpanderStyle;
-
-typedef enum
-{
-  GTK_ICON_SIZE_INVALID,
-  GTK_ICON_SIZE_MENU,
-  GTK_ICON_SIZE_SMALL_TOOLBAR,
-  GTK_ICON_SIZE_LARGE_TOOLBAR,
-  GTK_ICON_SIZE_BUTTON,
-  GTK_ICON_SIZE_DND,
-  GTK_ICON_SIZE_DIALOG
-} GtkIconSize;
-
-typedef enum
-{
-  GTK_ORIENTATION_HORIZONTAL,
-  GTK_ORIENTATION_VERTICAL
-} GtkOrientation;
-
-typedef enum
-{
-  GTK_POS_LEFT,
-  GTK_POS_RIGHT,
-  GTK_POS_TOP,
-  GTK_POS_BOTTOM
-} GtkPositionType;
-
-typedef enum
-{
-  GTK_SHADOW_NONE,
-  GTK_SHADOW_IN,
-  GTK_SHADOW_OUT,
-  GTK_SHADOW_ETCHED_IN,
-  GTK_SHADOW_ETCHED_OUT
-} GtkShadowType;
-
-typedef enum
-{
-  GTK_STATE_NORMAL,
-  GTK_STATE_ACTIVE,
-  GTK_STATE_PRELIGHT,
-  GTK_STATE_SELECTED,
-  GTK_STATE_INSENSITIVE
-} GtkStateType;
-
-typedef enum
-{
-  GTK_TEXT_DIR_NONE,
-  GTK_TEXT_DIR_LTR,
-  GTK_TEXT_DIR_RTL
-} GtkTextDirection;
-
 typedef enum
 {
   GTK_WINDOW_TOPLEVEL,
@@ -270,41 +49,15 @@
   G_PARAM_PRIVATE             = 1 << 5
 } GParamFlags;
 
-typedef enum {
-    GDK_INTERP_NEAREST,
-    GDK_INTERP_TILES,
-    GDK_INTERP_BILINEAR,
-    GDK_INTERP_HYPER
-} GdkInterpType;
-
 /* We define all structure pointers to be void* */
-typedef void GError;
 typedef void GMainContext;
 typedef void GVfs;
 
-typedef struct _GSList GSList;
-struct _GSList
-{
-  gpointer data;
-  GSList *next;
-};
-
-typedef struct _GList GList;
-
-struct _GList
-{
-  gpointer data;
-  GList *next;
-  GList *prev;
-};
-
 typedef void GdkColormap;
 typedef void GdkDrawable;
 typedef void GdkGC;
-typedef void GdkScreen;
 typedef void GdkPixbuf;
 typedef void GdkPixmap;
-typedef void GdkWindow;
 
 typedef void GtkFixed;
 typedef void GtkMenuItem;
@@ -364,7 +117,6 @@
  * structures. This is a place where getting rid of gtk
  * headers may be dangerous.
  ******************************************************/
-typedef gulong         GType;
 
 typedef struct
 {
@@ -599,70 +351,9 @@
   guint ellipsize : 3;
 };
 
-typedef enum {
-  GTK_RESPONSE_NONE = -1,
-  GTK_RESPONSE_REJECT = -2,
-  GTK_RESPONSE_ACCEPT = -3,
-  GTK_RESPONSE_DELETE_EVENT = -4,
-  GTK_RESPONSE_OK = -5,
-  GTK_RESPONSE_CANCEL = -6,
-  GTK_RESPONSE_CLOSE = -7,
-  GTK_RESPONSE_YES = -8,
-  GTK_RESPONSE_NO = -9,
-  GTK_RESPONSE_APPLY = -10,
-  GTK_RESPONSE_HELP = -11
-} GtkResponseType;
-
-typedef struct _GtkWindow GtkWindow;
-
-typedef struct _GtkFileChooser GtkFileChooser;
-
-typedef enum {
-  GTK_FILE_CHOOSER_ACTION_OPEN,
-  GTK_FILE_CHOOSER_ACTION_SAVE,
-  GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-  GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
-} GtkFileChooserAction;
-
-typedef struct _GtkFileFilter GtkFileFilter;
-
-typedef enum {
-  GTK_FILE_FILTER_FILENAME = 1 << 0,
-  GTK_FILE_FILTER_URI = 1 << 1,
-  GTK_FILE_FILTER_DISPLAY_NAME = 1 << 2,
-  GTK_FILE_FILTER_MIME_TYPE = 1 << 3
-} GtkFileFilterFlags;
-
-typedef struct {
-  GtkFileFilterFlags contains;
-  const gchar *filename;
-  const gchar *uri;
-  const gchar *display_name;
-  const gchar *mime_type;
-} GtkFileFilterInfo;
-
-typedef gboolean (*GtkFileFilterFunc)(const GtkFileFilterInfo *filter_info,
-    gpointer data);
-
-typedef void (*GDestroyNotify)(gpointer data);
-
-typedef void (*GCallback)(void);
-
-typedef struct _GClosure GClosure;
-
-typedef void (*GClosureNotify)(gpointer data, GClosure *closure);
-
-typedef enum {
-  G_CONNECT_AFTER = 1 << 0, G_CONNECT_SWAPPED = 1 << 1
-} GConnectFlags;
 
 typedef struct _GThreadFunctions GThreadFunctions;
 
-/*
- * Converts java.lang.String object to UTF-8 character string.
- */
-const char *getStrFor(JNIEnv *env, jstring value);
-
 /**
  * Returns :
  * NULL if the GLib library is compatible with the given version, or a string
@@ -670,7 +361,7 @@
  * Please note that the glib_check_version() is available since 2.6,
  * so you should use GLIB_CHECK_VERSION macro instead.
  */
-gchar* (*fp_glib_check_version)(guint required_major, guint required_minor,
+static gchar* (*fp_glib_check_version)(guint required_major, guint required_minor,
                        guint required_micro);
 
 /**
@@ -680,193 +371,96 @@
 #define GLIB_CHECK_VERSION(major, minor, micro) \
     (fp_glib_check_version && fp_glib_check_version(major, minor, micro) == NULL)
 
-/*
- * Check whether the gtk2 library is available and meets the minimum
- * version requirement.  If the library is already loaded this method has no
- * effect and returns success.
- * Returns FALSE on failure and TRUE on success.
- */
-gboolean gtk2_check_version();
-
 /**
  * Returns :
  * NULL if the GTK+ library is compatible with the given version, or a string
  * describing the version mismatch.
  */
-gchar* (*fp_gtk_check_version)(guint required_major, guint required_minor,
+static gchar* (*fp_gtk_check_version)(guint required_major, guint required_minor,
                        guint required_micro);
-/*
- * Load the gtk2 library.  If the library is already loaded this method has no
- * effect and returns success.
- * Returns FALSE on failure and TRUE on success.
- */
-gboolean gtk2_load(JNIEnv *env);
 
-/*
- * Loads fp_gtk_show_uri function pointer. This initialization is
- * separated because the function is required only
- * for java.awt.Desktop API. The function relies on initialization in
- * gtk2_load, so it must be invoked only after a successful gtk2_load
- * invocation
- */
-gboolean gtk2_show_uri_load(JNIEnv *env);
+static void gtk2_init(GtkApi* gtk);
 
-/*
- * Unload the gtk2 library.  If the library is already unloaded this method has
- * no effect and returns success.
- * Returns FALSE on failure and TRUE on success.
- */
-gboolean gtk2_unload();
+static void (*fp_g_free)(gpointer mem);
+static void (*fp_g_object_unref)(gpointer object);
+static GdkWindow *(*fp_gdk_get_default_root_window) (void);
 
-void gtk2_paint_arrow(WidgetType widget_type, GtkStateType state_type,
-        GtkShadowType shadow_type, const gchar *detail,
-        gint x, gint y, gint width, gint height,
-        GtkArrowType arrow_type, gboolean fill);
-void gtk2_paint_box(WidgetType widget_type, GtkStateType state_type,
-        GtkShadowType shadow_type, const gchar *detail,
-        gint x, gint y, gint width, gint height,
-        gint synth_state, GtkTextDirection dir);
-void gtk2_paint_box_gap(WidgetType widget_type, GtkStateType state_type,
-        GtkShadowType shadow_type, const gchar *detail,
-        gint x, gint y, gint width, gint height,
-        GtkPositionType gap_side, gint gap_x, gint gap_width);
-void gtk2_paint_check(WidgetType widget_type, gint synth_state,
-        const gchar *detail, gint x, gint y, gint width, gint height);
-void gtk2_paint_diamond(WidgetType widget_type, GtkStateType state_type,
-        GtkShadowType shadow_type, const gchar *detail,
-        gint x, gint y, gint width, gint height);
-void gtk2_paint_expander(WidgetType widget_type, GtkStateType state_type,
-        const gchar *detail, gint x, gint y, gint width, gint height,
-        GtkExpanderStyle expander_style);
-void gtk2_paint_extension(WidgetType widget_type, GtkStateType state_type,
-        GtkShadowType shadow_type, const gchar *detail,
-        gint x, gint y, gint width, gint height, GtkPositionType gap_side);
-void gtk2_paint_flat_box(WidgetType widget_type, GtkStateType state_type,
-        GtkShadowType shadow_type, const gchar *detail,
-        gint x, gint y, gint width, gint height, gboolean has_focus);
-void gtk2_paint_focus(WidgetType widget_type, GtkStateType state_type,
-        const char *detail, gint x, gint y, gint width, gint height);
-void gtk2_paint_handle(WidgetType widget_type, GtkStateType state_type,
-        GtkShadowType shadow_type, const gchar *detail,
-        gint x, gint y, gint width, gint height, GtkOrientation orientation);
-void gtk2_paint_hline(WidgetType widget_type, GtkStateType state_type,
-        const gchar *detail, gint x, gint y, gint width, gint height);
-void gtk2_paint_option(WidgetType widget_type, gint synth_state,
-        const gchar *detail, gint x, gint y, gint width, gint height);
-void gtk2_paint_shadow(WidgetType widget_type, GtkStateType state_type,
-        GtkShadowType shadow_type, const gchar *detail,
-        gint x, gint y, gint width, gint height,
-        gint synth_state, GtkTextDirection dir);
-void gtk2_paint_slider(WidgetType widget_type, GtkStateType state_type,
-        GtkShadowType shadow_type, const gchar *detail,
-        gint x, gint y, gint width, gint height, GtkOrientation orientation);
-void gtk2_paint_vline(WidgetType widget_type, GtkStateType state_type,
-        const gchar *detail, gint x, gint y, gint width, gint height);
-void gtk_paint_background(WidgetType widget_type, GtkStateType state_type,
-        gint x, gint y, gint width, gint height);
+static int (*fp_gdk_pixbuf_get_bits_per_sample)(const GdkPixbuf *pixbuf);
+static guchar *(*fp_gdk_pixbuf_get_pixels)(const GdkPixbuf *pixbuf);
+static gboolean (*fp_gdk_pixbuf_get_has_alpha)(const GdkPixbuf *pixbuf);
+static int (*fp_gdk_pixbuf_get_height)(const GdkPixbuf *pixbuf);
+static int (*fp_gdk_pixbuf_get_n_channels)(const GdkPixbuf *pixbuf);
+static int (*fp_gdk_pixbuf_get_rowstride)(const GdkPixbuf *pixbuf);
+static int (*fp_gdk_pixbuf_get_width)(const GdkPixbuf *pixbuf);
+static GdkPixbuf *(*fp_gdk_pixbuf_new_from_file)(const char *filename, GError **error);
+static GdkColorspace (*fp_gdk_pixbuf_get_colorspace)(const GdkPixbuf *pixbuf);
 
-void gtk2_init_painting(JNIEnv *env, gint w, gint h);
-gint gtk2_copy_image(gint *dest, gint width, gint height);
-
-gint gtk2_get_xthickness(JNIEnv *env, WidgetType widget_type);
-gint gtk2_get_ythickness(JNIEnv *env, WidgetType widget_type);
-gint gtk2_get_color_for_state(JNIEnv *env, WidgetType widget_type,
-                              GtkStateType state_type, ColorType color_type);
-jobject gtk2_get_class_value(JNIEnv *env, WidgetType widget_type, jstring key);
-
-GdkPixbuf *gtk2_get_stock_icon(gint widget_type, const gchar *stock_id,
-        GtkIconSize size, GtkTextDirection direction, const char *detail);
-GdkPixbuf *gtk2_get_icon(const gchar *filename, gint size);
-jstring gtk2_get_pango_font_name(JNIEnv *env, WidgetType widget_type);
-
-void flush_gtk_event_loop();
-
-jobject gtk2_get_setting(JNIEnv *env, Setting property);
-
-void gtk2_set_range_value(WidgetType widget_type, jdouble value,
-                          jdouble min, jdouble max, jdouble visible);
-
-void (*fp_g_free)(gpointer mem);
-void (*fp_g_object_unref)(gpointer object);
-GdkWindow *(*fp_gdk_get_default_root_window) (void);
-
-int (*fp_gdk_pixbuf_get_bits_per_sample)(const GdkPixbuf *pixbuf);
-guchar *(*fp_gdk_pixbuf_get_pixels)(const GdkPixbuf *pixbuf);
-gboolean (*fp_gdk_pixbuf_get_has_alpha)(const GdkPixbuf *pixbuf);
-int (*fp_gdk_pixbuf_get_height)(const GdkPixbuf *pixbuf);
-int (*fp_gdk_pixbuf_get_n_channels)(const GdkPixbuf *pixbuf);
-int (*fp_gdk_pixbuf_get_rowstride)(const GdkPixbuf *pixbuf);
-int (*fp_gdk_pixbuf_get_width)(const GdkPixbuf *pixbuf);
-GdkPixbuf *(*fp_gdk_pixbuf_new_from_file)(const char *filename, GError **error);
-GdkColorspace (*fp_gdk_pixbuf_get_colorspace)(const GdkPixbuf *pixbuf);
-
-GdkPixbuf *(*fp_gdk_pixbuf_get_from_drawable)(GdkPixbuf *dest,
+static GdkPixbuf *(*fp_gdk_pixbuf_get_from_drawable)(GdkPixbuf *dest,
         GdkDrawable *src, GdkColormap *cmap, int src_x, int src_y,
         int dest_x, int dest_y, int width, int height);
-GdkPixbuf *(*fp_gdk_pixbuf_scale_simple)(GdkPixbuf *src,
+static GdkPixbuf *(*fp_gdk_pixbuf_scale_simple)(GdkPixbuf *src,
         int dest_width, int dest_heigh, GdkInterpType interp_type);
 
 
-void (*fp_gtk_widget_destroy)(GtkWidget *widget);
-void (*fp_gtk_window_present)(GtkWindow *window);
-void (*fp_gtk_window_move)(GtkWindow *window, gint x, gint y);
-void (*fp_gtk_window_resize)(GtkWindow *window, gint width, gint height);
+static void (*fp_gtk_widget_destroy)(void *widget);
+static void (*fp_gtk_window_present)(GtkWindow *window);
+static void (*fp_gtk_window_move)(GtkWindow *window, gint x, gint y);
+static void (*fp_gtk_window_resize)(GtkWindow *window, gint width, gint height);
 
 /**
  * Function Pointers for GtkFileChooser
  */
-gchar* (*fp_gtk_file_chooser_get_filename)(GtkFileChooser *chooser);
-void (*fp_gtk_widget_hide)(GtkWidget *widget);
-void (*fp_gtk_main_quit)(void);
-GtkWidget* (*fp_gtk_file_chooser_dialog_new)(const gchar *title,
+static gchar* (*fp_gtk_file_chooser_get_filename)(GtkFileChooser *chooser);
+static void (*fp_gtk_widget_hide)(void *widget);
+static void (*fp_gtk_main_quit)(void);
+static void* (*fp_gtk_file_chooser_dialog_new)(const gchar *title,
     GtkWindow *parent, GtkFileChooserAction action,
     const gchar *first_button_text, ...);
-gboolean (*fp_gtk_file_chooser_set_current_folder)(GtkFileChooser *chooser,
+static gboolean (*fp_gtk_file_chooser_set_current_folder)(GtkFileChooser *chooser,
     const gchar *filename);
-gboolean (*fp_gtk_file_chooser_set_filename)(GtkFileChooser *chooser,
+static gboolean (*fp_gtk_file_chooser_set_filename)(GtkFileChooser *chooser,
     const char *filename);
-void (*fp_gtk_file_chooser_set_current_name)(GtkFileChooser *chooser,
+static void (*fp_gtk_file_chooser_set_current_name)(GtkFileChooser *chooser,
     const gchar *name);
-void (*fp_gtk_file_filter_add_custom)(GtkFileFilter *filter,
+static void (*fp_gtk_file_filter_add_custom)(GtkFileFilter *filter,
     GtkFileFilterFlags needed, GtkFileFilterFunc func, gpointer data,
     GDestroyNotify notify);
-void (*fp_gtk_file_chooser_set_filter)(GtkFileChooser *chooser,
+static void (*fp_gtk_file_chooser_set_filter)(GtkFileChooser *chooser,
     GtkFileFilter *filter);
-GType (*fp_gtk_file_chooser_get_type)(void);
-GtkFileFilter* (*fp_gtk_file_filter_new)(void);
-void (*fp_gtk_file_chooser_set_do_overwrite_confirmation)(
+static GType (*fp_gtk_file_chooser_get_type)(void);
+static GtkFileFilter* (*fp_gtk_file_filter_new)(void);
+static void (*fp_gtk_file_chooser_set_do_overwrite_confirmation)(
     GtkFileChooser *chooser, gboolean do_overwrite_confirmation);
-void (*fp_gtk_file_chooser_set_select_multiple)(
+static void (*fp_gtk_file_chooser_set_select_multiple)(
     GtkFileChooser *chooser, gboolean select_multiple);
-gchar* (*fp_gtk_file_chooser_get_current_folder)(GtkFileChooser *chooser);
-GSList* (*fp_gtk_file_chooser_get_filenames)(GtkFileChooser *chooser);
-guint (*fp_gtk_g_slist_length)(GSList *list);
-gulong (*fp_g_signal_connect_data)(gpointer instance,
+static gchar* (*fp_gtk_file_chooser_get_current_folder)(GtkFileChooser *chooser);
+static GSList* (*fp_gtk_file_chooser_get_filenames)(GtkFileChooser *chooser);
+static guint (*fp_gtk_g_slist_length)(GSList *list);
+static gulong (*fp_g_signal_connect_data)(gpointer instance,
     const gchar *detailed_signal, GCallback c_handler, gpointer data,
     GClosureNotify destroy_data, GConnectFlags connect_flags);
-void (*fp_gtk_widget_show)(GtkWidget *widget);
-void (*fp_gtk_main)(void);
-guint (*fp_gtk_main_level)(void);
-gchar* (*fp_g_path_get_dirname) (const gchar *file_name);
-XID (*fp_gdk_x11_drawable_get_xid) (GdkWindow *drawable);
+static void (*fp_gtk_widget_show)(void *widget);
+static void (*fp_gtk_main)(void);
+static guint (*fp_gtk_main_level)(void);
+static gchar* (*fp_g_path_get_dirname) (const gchar *file_name);
+static XID (*fp_gdk_x11_drawable_get_xid) (GdkWindow *drawable);
 
-
-GList* (*fp_g_list_append) (GList *list, gpointer data);
-void (*fp_g_list_free) (GList *list);
-void (*fp_g_list_free_full) (GList *list, GDestroyNotify free_func);
+static GList* (*fp_g_list_append) (GList *list, gpointer data);
+static void (*fp_g_list_free) (GList *list);
+static void (*fp_g_list_free_full) (GList *list, GDestroyNotify free_func);
 
 /**
  * This function is available for GLIB > 2.20, so it MUST be
  * called within GLIB_CHECK_VERSION(2, 20, 0) check.
  */
-gboolean (*fp_g_thread_get_initialized)(void);
+static gboolean (*fp_g_thread_get_initialized)(void);
 
-void (*fp_g_thread_init)(GThreadFunctions *vtable);
-void (*fp_gdk_threads_init)(void);
-void (*fp_gdk_threads_enter)(void);
-void (*fp_gdk_threads_leave)(void);
+static void (*fp_g_thread_init)(GThreadFunctions *vtable);
+static void (*fp_gdk_threads_init)(void);
+static void (*fp_gdk_threads_enter)(void);
+static void (*fp_gdk_threads_leave)(void);
 
-gboolean (*fp_gtk_show_uri)(GdkScreen *screen, const gchar *uri,
+static gboolean (*fp_gtk_show_uri)(GdkScreen *screen, const gchar *uri,
     guint32 timestamp, GError **error);
 
 #endif /* !_GTK2_INTERFACE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,2882 @@
+/*
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+#include <dlfcn.h>
+#include <setjmp.h>
+#include <X11/Xlib.h>
+#include <limits.h>
+#include <string.h>
+#include "gtk3_interface.h"
+#include "java_awt_Transparency.h"
+#include "sizecalc.h"
+#include <jni_util.h>
+#include <stdio.h>
+#include "awt.h"
+
+static void *gtk3_libhandle = NULL;
+
+static jmp_buf j;
+
+/* Widgets */
+static GtkWidget *gtk3_widget = NULL;
+static GtkWidget *gtk3_window = NULL;
+static GtkFixed  *gtk3_fixed  = NULL;
+static GtkStyleProvider *gtk3_css = NULL;
+
+/* Paint system */
+static cairo_surface_t *surface = NULL;
+static cairo_t *cr = NULL;
+
+static const char ENV_PREFIX[] = "GTK_MODULES=";
+
+static GtkWidget *gtk3_widgets[_GTK_WIDGET_TYPE_SIZE];
+
+static void throw_exception(JNIEnv *env, const char* name, const char* message)
+{
+    jclass class = (*env)->FindClass(env, name);
+
+    if (class != NULL)
+        (*env)->ThrowNew(env, class, message);
+
+    (*env)->DeleteLocalRef(env, class);
+}
+
+static void gtk3_add_state(GtkWidget *widget, GtkStateType state) {
+    GtkStateType old_state = fp_gtk_widget_get_state(widget);
+    fp_gtk_widget_set_state(widget, old_state | state);
+}
+
+static void gtk3_remove_state(GtkWidget *widget, GtkStateType state) {
+    GtkStateType old_state = fp_gtk_widget_get_state(widget);
+    fp_gtk_widget_set_state(widget, old_state & ~state);
+}
+
+/* This is a workaround for the bug:
+ * http://sourceware.org/bugzilla/show_bug.cgi?id=1814
+ * (dlsym/dlopen clears dlerror state)
+ * This bug is specific to Linux, but there is no harm in
+ * applying this workaround on Solaris as well.
+ */
+static void* dl_symbol(const char* name)
+{
+    void* result = dlsym(gtk3_libhandle, name);
+    if (!result)
+        longjmp(j, NO_SYMBOL_EXCEPTION);
+
+    return result;
+}
+
+gboolean gtk3_check(const char* lib_name, int flags)
+{
+    if (gtk3_libhandle != NULL) {
+        /* We've already successfully opened the GTK libs, so return true. */
+        return TRUE;
+    } else {
+        return dlopen(lib_name, flags) != NULL;
+    }
+}
+
+#define ADD_SUPPORTED_ACTION(actionStr)                                        \
+do {                                                                           \
+    jfieldID fld_action = (*env)->GetStaticFieldID(env, cls_action, actionStr, \
+                                                 "Ljava/awt/Desktop$Action;"); \
+    if (!(*env)->ExceptionCheck(env)) {                                        \
+        jobject action = (*env)->GetStaticObjectField(env, cls_action,         \
+                                                                  fld_action); \
+        (*env)->CallBooleanMethod(env, supportedActions, mid_arrayListAdd,     \
+                                                                      action); \
+    } else {                                                                   \
+        (*env)->ExceptionClear(env);                                           \
+    }                                                                          \
+} while(0);
+
+
+static void update_supported_actions(JNIEnv *env) {
+    GVfs * (*fp_g_vfs_get_default) (void);
+    const gchar * const * (*fp_g_vfs_get_supported_uri_schemes) (GVfs * vfs);
+    const gchar * const * schemes = NULL;
+
+    jclass cls_action = (*env)->FindClass(env, "java/awt/Desktop$Action");
+    CHECK_NULL(cls_action);
+    jclass cls_xDesktopPeer = (*env)->
+                                     FindClass(env, "sun/awt/X11/XDesktopPeer");
+    CHECK_NULL(cls_xDesktopPeer);
+    jfieldID fld_supportedActions = (*env)->GetStaticFieldID(env,
+                      cls_xDesktopPeer, "supportedActions", "Ljava/util/List;");
+    CHECK_NULL(fld_supportedActions);
+    jobject supportedActions = (*env)->GetStaticObjectField(env,
+                                        cls_xDesktopPeer, fld_supportedActions);
+
+    jclass cls_arrayList = (*env)->FindClass(env, "java/util/ArrayList");
+    CHECK_NULL(cls_arrayList);
+    jmethodID mid_arrayListAdd = (*env)->GetMethodID(env, cls_arrayList, "add",
+                                                       "(Ljava/lang/Object;)Z");
+    CHECK_NULL(mid_arrayListAdd);
+    jmethodID mid_arrayListClear = (*env)->GetMethodID(env, cls_arrayList,
+                                                                "clear", "()V");
+    CHECK_NULL(mid_arrayListClear);
+
+    (*env)->CallVoidMethod(env, supportedActions, mid_arrayListClear);
+
+    ADD_SUPPORTED_ACTION("OPEN");
+
+    /**
+     * gtk_show_uri() documentation says:
+     *
+     * > you need to install gvfs to get support for uri schemes such as http://
+     * > or ftp://, as only local files are handled by GIO itself.
+     *
+     * So OPEN action was safely added here.
+     * However, it looks like Solaris 11 have gvfs support only for 32-bit
+     * applications only by default.
+     */
+
+    fp_g_vfs_get_default = dl_symbol("g_vfs_get_default");
+    fp_g_vfs_get_supported_uri_schemes =
+                           dl_symbol("g_vfs_get_supported_uri_schemes");
+    dlerror();
+
+    if (fp_g_vfs_get_default && fp_g_vfs_get_supported_uri_schemes) {
+        GVfs * vfs = fp_g_vfs_get_default();
+        schemes = vfs ? fp_g_vfs_get_supported_uri_schemes(vfs) : NULL;
+        if (schemes) {
+            int i = 0;
+            while (schemes[i]) {
+                if (strcmp(schemes[i], "http") == 0) {
+                    ADD_SUPPORTED_ACTION("BROWSE");
+                    ADD_SUPPORTED_ACTION("MAIL");
+                    break;
+                }
+                i++;
+            }
+        }
+    } else {
+#ifdef DEBUG
+        fprintf(stderr, "Cannot load g_vfs_get_supported_uri_schemes\n");
+#endif /* DEBUG */
+    }
+
+}
+/**
+ * Functions for awt_Desktop.c
+ */
+static gboolean gtk3_show_uri_load(JNIEnv *env) {
+    gboolean success = FALSE;
+    dlerror();
+    fp_gtk_show_uri = dl_symbol("gtk_show_uri");
+    const char *dlsym_error = dlerror();
+    if (dlsym_error) {
+#ifdef DEBUG
+        fprintf (stderr, "Cannot load symbol: %s \n", dlsym_error);
+#endif /* DEBUG */
+    } else if (fp_gtk_show_uri == NULL) {
+#ifdef DEBUG
+        fprintf(stderr, "dlsym(gtk_show_uri) returned NULL\n");
+#endif /* DEBUG */
+    } else {
+        gtk->gtk_show_uri = fp_gtk_show_uri;
+        update_supported_actions(env);
+        success = TRUE;
+    }
+    return success;
+}
+
+/**
+ * Functions for sun_awt_X11_GtkFileDialogPeer.c
+ */
+static void gtk3_file_chooser_load()
+{
+    fp_gtk_file_chooser_get_filename = dl_symbol(
+            "gtk_file_chooser_get_filename");
+    fp_gtk_file_chooser_dialog_new = dl_symbol("gtk_file_chooser_dialog_new");
+    fp_gtk_file_chooser_set_current_folder = dl_symbol(
+            "gtk_file_chooser_set_current_folder");
+    fp_gtk_file_chooser_set_filename = dl_symbol(
+            "gtk_file_chooser_set_filename");
+    fp_gtk_file_chooser_set_current_name = dl_symbol(
+            "gtk_file_chooser_set_current_name");
+    fp_gtk_file_filter_add_custom = dl_symbol("gtk_file_filter_add_custom");
+    fp_gtk_file_chooser_set_filter = dl_symbol("gtk_file_chooser_set_filter");
+    fp_gtk_file_chooser_get_type = dl_symbol("gtk_file_chooser_get_type");
+    fp_gtk_file_filter_new = dl_symbol("gtk_file_filter_new");
+    fp_gtk_file_chooser_set_do_overwrite_confirmation = dl_symbol(
+                "gtk_file_chooser_set_do_overwrite_confirmation");
+    fp_gtk_file_chooser_set_select_multiple = dl_symbol(
+            "gtk_file_chooser_set_select_multiple");
+    fp_gtk_file_chooser_get_current_folder = dl_symbol(
+            "gtk_file_chooser_get_current_folder");
+    fp_gtk_file_chooser_get_filenames = dl_symbol(
+            "gtk_file_chooser_get_filenames");
+    fp_gtk_g_slist_length = dl_symbol("g_slist_length");
+    fp_gdk_x11_drawable_get_xid = dl_symbol("gdk_x11_window_get_xid");
+}
+
+static void empty() {}
+
+static gboolean gtk3_version_3_10 = TRUE;
+static gboolean gtk3_version_3_14 = FALSE;
+
+GtkApi* gtk3_load(JNIEnv *env, const char* lib_name)
+{
+    gboolean result;
+    int i;
+    int (*handler)();
+    int (*io_handler)();
+    char *gtk_modules_env;
+    gtk3_libhandle = dlopen(lib_name, RTLD_LAZY | RTLD_LOCAL);
+    if (gtk3_libhandle == NULL) {
+        return FALSE;
+    }
+
+    if (setjmp(j) == 0)
+    {
+        fp_gtk_check_version = dl_symbol("gtk_check_version");
+
+        /* GLib */
+        fp_glib_check_version = dlsym(gtk3_libhandle, "glib_check_version");
+        if (!fp_glib_check_version) {
+            dlerror();
+        }
+        fp_g_free = dl_symbol("g_free");
+        fp_g_object_unref = dl_symbol("g_object_unref");
+
+        fp_g_main_context_iteration =
+            dl_symbol("g_main_context_iteration");
+
+        fp_g_value_init = dl_symbol("g_value_init");
+        fp_g_type_is_a = dl_symbol("g_type_is_a");
+        fp_g_value_get_boolean = dl_symbol("g_value_get_boolean");
+        fp_g_value_get_char = dl_symbol("g_value_get_char");
+        fp_g_value_get_uchar = dl_symbol("g_value_get_uchar");
+        fp_g_value_get_int = dl_symbol("g_value_get_int");
+        fp_g_value_get_uint = dl_symbol("g_value_get_uint");
+        fp_g_value_get_long = dl_symbol("g_value_get_long");
+        fp_g_value_get_ulong = dl_symbol("g_value_get_ulong");
+        fp_g_value_get_int64 = dl_symbol("g_value_get_int64");
+        fp_g_value_get_uint64 = dl_symbol("g_value_get_uint64");
+        fp_g_value_get_float = dl_symbol("g_value_get_float");
+        fp_g_value_get_double = dl_symbol("g_value_get_double");
+        fp_g_value_get_string = dl_symbol("g_value_get_string");
+        fp_g_value_get_enum = dl_symbol("g_value_get_enum");
+        fp_g_value_get_flags = dl_symbol("g_value_get_flags");
+        fp_g_value_get_param = dl_symbol("g_value_get_param");
+        fp_g_value_get_boxed = dl_symbol("g_value_get_boxed");
+        fp_g_value_get_pointer = dl_symbol("g_value_get_pointer");
+
+        fp_g_object_get = dl_symbol("g_object_get");
+        fp_g_object_set = dl_symbol("g_object_set");
+
+        fp_g_str_has_prefix = dl_symbol("g_str_has_prefix");
+        fp_g_strsplit = dl_symbol("g_strsplit");
+        fp_g_strfreev = dl_symbol("g_strfreev");
+
+        /* GDK */
+        fp_gdk_get_default_root_window =
+            dl_symbol("gdk_get_default_root_window");
+
+        /* Pixbuf */
+        fp_gdk_pixbuf_new = dl_symbol("gdk_pixbuf_new");
+        fp_gdk_pixbuf_new_from_file =
+                dl_symbol("gdk_pixbuf_new_from_file");
+        fp_gdk_pixbuf_get_from_drawable =
+                    dl_symbol("gdk_pixbuf_get_from_window");
+        fp_gdk_pixbuf_get_width = dl_symbol("gdk_pixbuf_get_width");
+        fp_gdk_pixbuf_get_height = dl_symbol("gdk_pixbuf_get_height");
+        fp_gdk_pixbuf_get_pixels = dl_symbol("gdk_pixbuf_get_pixels");
+        fp_gdk_pixbuf_get_rowstride =
+                dl_symbol("gdk_pixbuf_get_rowstride");
+        fp_gdk_pixbuf_get_has_alpha =
+                dl_symbol("gdk_pixbuf_get_has_alpha");
+        fp_gdk_pixbuf_get_bits_per_sample =
+                dl_symbol("gdk_pixbuf_get_bits_per_sample");
+        fp_gdk_pixbuf_get_n_channels =
+                dl_symbol("gdk_pixbuf_get_n_channels");
+        fp_gdk_pixbuf_get_colorspace =
+                dl_symbol("gdk_pixbuf_get_colorspace");
+
+        fp_cairo_image_surface_create = dl_symbol("cairo_image_surface_create");
+        fp_cairo_surface_destroy = dl_symbol("cairo_surface_destroy");
+        fp_cairo_create = dl_symbol("cairo_create");
+        fp_cairo_destroy = dl_symbol("cairo_destroy");
+        fp_cairo_fill = dl_symbol("cairo_fill");
+        fp_cairo_rectangle = dl_symbol("cairo_rectangle");
+        fp_cairo_set_source_rgb = dl_symbol("cairo_set_source_rgb");
+        fp_cairo_set_source_rgba = dl_symbol("cairo_set_source_rgba");
+        fp_cairo_surface_flush = dl_symbol("cairo_surface_flush");
+        fp_cairo_paint = dl_symbol("cairo_paint");
+        fp_cairo_clip = dl_symbol("cairo_clip");
+        fp_cairo_image_surface_get_data =
+                       dl_symbol("cairo_image_surface_get_data");
+        fp_cairo_image_surface_get_stride =
+                       dl_symbol("cairo_image_surface_get_stride");
+
+        fp_gdk_pixbuf_get_from_surface =
+                       dl_symbol("gdk_pixbuf_get_from_surface");
+
+        fp_gtk_widget_get_state = dl_symbol("gtk_widget_get_state");
+        fp_gtk_widget_set_state = dl_symbol("gtk_widget_set_state");
+
+        fp_gtk_widget_is_focus = dl_symbol("gtk_widget_is_focus");
+        fp_gtk_widget_set_allocation = dl_symbol("gtk_widget_set_allocation");
+        fp_gtk_widget_get_parent = dl_symbol("gtk_widget_get_parent");
+        fp_gtk_widget_get_window = dl_symbol("gtk_widget_get_window");
+
+        fp_gtk_widget_get_style_context =
+                       dl_symbol("gtk_widget_get_style_context");
+        fp_gtk_style_context_get_color =
+                       dl_symbol("gtk_style_context_get_color");
+        fp_gtk_style_context_get_background_color =
+                       dl_symbol("gtk_style_context_get_background_color");
+        fp_gtk_widget_get_state_flags = dl_symbol("gtk_widget_get_state_flags");
+        fp_gtk_style_context_set_state =
+                       dl_symbol("gtk_style_context_set_state");
+        fp_gtk_style_context_add_class =
+                       dl_symbol("gtk_style_context_add_class");
+        fp_gtk_style_context_save = dl_symbol("gtk_style_context_save");
+        fp_gtk_style_context_restore = dl_symbol("gtk_style_context_restore");
+        fp_gtk_render_check = dl_symbol("gtk_render_check");
+        fp_gtk_render_option = dl_symbol("gtk_render_option");
+        fp_gtk_render_extension = dl_symbol("gtk_render_extension");
+        fp_gtk_render_expander = dl_symbol("gtk_render_expander");
+        fp_gtk_render_frame_gap = dl_symbol("gtk_render_frame_gap");
+        fp_gtk_render_line = dl_symbol("gtk_render_line");
+        fp_gtk_widget_render_icon_pixbuf =
+                      dl_symbol("gtk_widget_render_icon_pixbuf");
+        if (fp_gtk_check_version(3, 10, 0)) {
+            gtk3_version_3_10 = FALSE;
+        } else {
+            fp_gdk_window_create_similar_image_surface =
+                       dl_symbol("gdk_window_create_similar_image_surface");
+        }
+        gtk3_version_3_14 = !fp_gtk_check_version(3, 14, 0);
+
+        fp_gdk_window_create_similar_surface =
+                      dl_symbol("gdk_window_create_similar_surface");
+        fp_gtk_settings_get_for_screen =
+                      dl_symbol("gtk_settings_get_for_screen");
+        fp_gtk_widget_get_screen = dl_symbol("gtk_widget_get_screen");
+        fp_gtk_css_provider_get_named = dl_symbol("gtk_css_provider_get_named");
+        fp_gtk_style_context_add_provider =
+                      dl_symbol("gtk_style_context_add_provider");
+        fp_gtk_render_frame = dl_symbol("gtk_render_frame");
+        fp_gtk_render_focus = dl_symbol("gtk_render_focus");
+        fp_gtk_render_handle = dl_symbol("gtk_render_handle");
+        fp_gtk_render_arrow = dl_symbol("gtk_render_arrow");
+
+        fp_gtk_style_context_get_property =
+                      dl_symbol("gtk_style_context_get_property");
+        fp_gtk_scrolled_window_set_shadow_type =
+                      dl_symbol("gtk_scrolled_window_set_shadow_type");
+        fp_gtk_render_slider = dl_symbol("gtk_render_slider");
+        fp_gtk_style_context_get_padding =
+                      dl_symbol("gtk_style_context_get_padding");
+        fp_gtk_range_set_inverted = dl_symbol("gtk_range_set_inverted");
+        fp_gtk_style_context_get_font = dl_symbol("gtk_style_context_get_font");
+        fp_gtk_widget_get_allocated_width =
+                      dl_symbol("gtk_widget_get_allocated_width");
+        fp_gtk_widget_get_allocated_height =
+                      dl_symbol("gtk_widget_get_allocated_height");
+        fp_gtk_icon_theme_get_default = dl_symbol("gtk_icon_theme_get_default");
+        fp_gtk_icon_theme_load_icon = dl_symbol("gtk_icon_theme_load_icon");
+
+        fp_gtk_adjustment_set_lower = dl_symbol("gtk_adjustment_set_lower");
+        fp_gtk_adjustment_set_page_increment =
+                      dl_symbol("gtk_adjustment_set_page_increment");
+        fp_gtk_adjustment_set_page_size =
+                      dl_symbol("gtk_adjustment_set_page_size");
+        fp_gtk_adjustment_set_step_increment =
+                      dl_symbol("gtk_adjustment_set_step_increment");
+        fp_gtk_adjustment_set_upper = dl_symbol("gtk_adjustment_set_upper");
+        fp_gtk_adjustment_set_value = dl_symbol("gtk_adjustment_set_value");
+
+        fp_gtk_render_activity = dl_symbol("gtk_render_activity");
+        fp_gtk_render_background = dl_symbol("gtk_render_background");
+        fp_gtk_style_context_has_class =
+                      dl_symbol("gtk_style_context_has_class");
+
+        fp_gtk_style_context_set_junction_sides =
+                      dl_symbol("gtk_style_context_set_junction_sides");
+        fp_gtk_style_context_add_region =
+                      dl_symbol("gtk_style_context_add_region");
+
+        fp_gtk_init_check = dl_symbol("gtk_init_check");
+
+        /* GTK widgets */
+        fp_gtk_arrow_new = dl_symbol("gtk_arrow_new");
+        fp_gtk_button_new = dl_symbol("gtk_button_new");
+        fp_gtk_spin_button_new = dl_symbol("gtk_spin_button_new");
+        fp_gtk_check_button_new = dl_symbol("gtk_check_button_new");
+        fp_gtk_check_menu_item_new =
+                dl_symbol("gtk_check_menu_item_new");
+        fp_gtk_color_selection_dialog_new =
+                dl_symbol("gtk_color_selection_dialog_new");
+        fp_gtk_entry_new = dl_symbol("gtk_entry_new");
+        fp_gtk_fixed_new = dl_symbol("gtk_fixed_new");
+        fp_gtk_handle_box_new = dl_symbol("gtk_handle_box_new");
+        fp_gtk_image_new = dl_symbol("gtk_image_new");
+        fp_gtk_hpaned_new = dl_symbol("gtk_hpaned_new");
+        fp_gtk_vpaned_new = dl_symbol("gtk_vpaned_new");
+        fp_gtk_scale_new = dl_symbol("gtk_scale_new");
+        fp_gtk_hscrollbar_new = dl_symbol("gtk_hscrollbar_new");
+        fp_gtk_vscrollbar_new = dl_symbol("gtk_vscrollbar_new");
+        fp_gtk_hseparator_new = dl_symbol("gtk_hseparator_new");
+        fp_gtk_vseparator_new = dl_symbol("gtk_vseparator_new");
+        fp_gtk_label_new = dl_symbol("gtk_label_new");
+        fp_gtk_menu_new = dl_symbol("gtk_menu_new");
+        fp_gtk_menu_bar_new = dl_symbol("gtk_menu_bar_new");
+        fp_gtk_menu_item_new = dl_symbol("gtk_menu_item_new");
+        fp_gtk_menu_item_set_submenu =
+                dl_symbol("gtk_menu_item_set_submenu");
+        fp_gtk_notebook_new = dl_symbol("gtk_notebook_new");
+        fp_gtk_progress_bar_new =
+            dl_symbol("gtk_progress_bar_new");
+        fp_gtk_progress_bar_set_orientation =
+            dl_symbol("gtk_orientable_set_orientation");
+        fp_gtk_radio_button_new =
+            dl_symbol("gtk_radio_button_new");
+        fp_gtk_radio_menu_item_new =
+            dl_symbol("gtk_radio_menu_item_new");
+        fp_gtk_scrolled_window_new =
+            dl_symbol("gtk_scrolled_window_new");
+        fp_gtk_separator_menu_item_new =
+            dl_symbol("gtk_separator_menu_item_new");
+        fp_gtk_text_view_new = dl_symbol("gtk_text_view_new");
+        fp_gtk_toggle_button_new =
+            dl_symbol("gtk_toggle_button_new");
+        fp_gtk_toolbar_new = dl_symbol("gtk_toolbar_new");
+        fp_gtk_tree_view_new = dl_symbol("gtk_tree_view_new");
+        fp_gtk_viewport_new = dl_symbol("gtk_viewport_new");
+        fp_gtk_window_new = dl_symbol("gtk_window_new");
+        fp_gtk_window_present = dl_symbol("gtk_window_present");
+        fp_gtk_window_move = dl_symbol("gtk_window_move");
+        fp_gtk_window_resize = dl_symbol("gtk_window_resize");
+
+          fp_gtk_dialog_new = dl_symbol("gtk_dialog_new");
+        fp_gtk_frame_new = dl_symbol("gtk_frame_new");
+
+        fp_gtk_adjustment_new = dl_symbol("gtk_adjustment_new");
+        fp_gtk_container_add = dl_symbol("gtk_container_add");
+        fp_gtk_menu_shell_append =
+            dl_symbol("gtk_menu_shell_append");
+        fp_gtk_widget_realize = dl_symbol("gtk_widget_realize");
+        fp_gtk_widget_destroy = dl_symbol("gtk_widget_destroy");
+        fp_gtk_widget_render_icon =
+            dl_symbol("gtk_widget_render_icon");
+        fp_gtk_widget_set_name =
+            dl_symbol("gtk_widget_set_name");
+        fp_gtk_widget_set_parent =
+            dl_symbol("gtk_widget_set_parent");
+        fp_gtk_widget_set_direction =
+            dl_symbol("gtk_widget_set_direction");
+        fp_gtk_widget_style_get =
+            dl_symbol("gtk_widget_style_get");
+        fp_gtk_widget_class_install_style_property =
+            dl_symbol("gtk_widget_class_install_style_property");
+        fp_gtk_widget_class_find_style_property =
+            dl_symbol("gtk_widget_class_find_style_property");
+        fp_gtk_widget_style_get_property =
+            dl_symbol("gtk_widget_style_get_property");
+        fp_pango_font_description_to_string =
+            dl_symbol("pango_font_description_to_string");
+        fp_gtk_settings_get_default =
+            dl_symbol("gtk_settings_get_default");
+        fp_gtk_widget_get_settings =
+            dl_symbol("gtk_widget_get_settings");
+        fp_gtk_border_get_type =  dl_symbol("gtk_border_get_type");
+        fp_gtk_arrow_set = dl_symbol("gtk_arrow_set");
+        fp_gtk_widget_size_request =
+            dl_symbol("gtk_widget_size_request");
+        fp_gtk_range_get_adjustment =
+            dl_symbol("gtk_range_get_adjustment");
+
+        fp_gtk_widget_hide = dl_symbol("gtk_widget_hide");
+        fp_gtk_main_quit = dl_symbol("gtk_main_quit");
+        fp_g_signal_connect_data = dl_symbol("g_signal_connect_data");
+        fp_gtk_widget_show = dl_symbol("gtk_widget_show");
+        fp_gtk_main = dl_symbol("gtk_main");
+
+        fp_g_path_get_dirname = dl_symbol("g_path_get_dirname");
+
+        fp_gdk_threads_enter = &empty;
+        fp_gdk_threads_leave = &empty;
+
+        /**
+         * Functions for sun_awt_X11_GtkFileDialogPeer.c
+         */
+        gtk3_file_chooser_load();
+
+        fp_gtk_combo_box_new = dlsym(gtk3_libhandle, "gtk_combo_box_new");
+        fp_gtk_combo_box_entry_new = dlsym(gtk3_libhandle,
+                                                "gtk_combo_box_new_with_entry");
+        fp_gtk_separator_tool_item_new = dlsym(gtk3_libhandle,
+                                                 "gtk_separator_tool_item_new");
+
+        fp_g_list_append = dl_symbol("g_list_append");
+        fp_g_list_free = dl_symbol("g_list_free");
+        fp_g_list_free_full = dl_symbol("g_list_free_full");
+    }
+    /* Now we have only one kind of exceptions: NO_SYMBOL_EXCEPTION
+     * Otherwise we can check the return value of setjmp method.
+     */
+    else
+    {
+        dlclose(gtk3_libhandle);
+        gtk3_libhandle = NULL;
+
+        return NULL;
+    }
+
+    /*
+     * Strip the AT-SPI GTK_MODULEs if present
+     */
+    gtk_modules_env = getenv ("GTK_MODULES");
+    if (gtk_modules_env && strstr (gtk_modules_env, "atk-bridge") ||
+        gtk_modules_env && strstr (gtk_modules_env, "gail"))
+    {
+        /* the new env will be smaller than the old one */
+        gchar *s, *new_env = SAFE_SIZE_STRUCT_ALLOC(malloc,
+                sizeof(ENV_PREFIX), 1, strlen (gtk_modules_env));
+
+        if (new_env != NULL )
+        {
+            /* careful, strtok modifies its args */
+            gchar *tmp_env = strdup (gtk_modules_env);
+            strcpy(new_env, ENV_PREFIX);
+
+            /* strip out 'atk-bridge' and 'gail' */
+            size_t PREFIX_LENGTH = strlen(ENV_PREFIX);
+            while (s = strtok(tmp_env, ":"))
+            {
+                if ((!strstr (s, "atk-bridge")) && (!strstr (s, "gail")))
+                {
+                    if (strlen (new_env) > PREFIX_LENGTH) {
+                        new_env = strcat (new_env, ":");
+                    }
+                    new_env = strcat(new_env, s);
+                }
+                if (tmp_env)
+                {
+                    free (tmp_env);
+                    tmp_env = NULL; /* next call to strtok arg1==NULL */
+                }
+            }
+            putenv (new_env);
+            free (new_env);
+            free (tmp_env);
+        }
+    }
+    /*
+     * GTK should be initialized with gtk_init_check() before use.
+     *
+     * gtk_init_check installs its own error handlers. It is critical that
+     * we preserve error handler set from AWT. Otherwise we'll crash on
+     * BadMatch errors which we would normally ignore. The IO error handler
+     * is preserved here, too, just for consistency.
+    */
+    AWT_LOCK();
+    handler = XSetErrorHandler(NULL);
+    io_handler = XSetIOErrorHandler(NULL);
+    result = (*fp_gtk_init_check)(NULL, NULL);
+    XSetErrorHandler(handler);
+    XSetIOErrorHandler(io_handler);
+    AWT_UNLOCK();
+    /* Initialize widget array. */
+    for (i = 0; i < _GTK_WIDGET_TYPE_SIZE; i++)
+    {
+        gtk3_widgets[i] = NULL;
+    }
+    if (result) {
+        GtkApi* gtk = (GtkApi*)malloc(sizeof(GtkApi));
+        gtk3_init(gtk);
+        return gtk;
+    }
+    return NULL;
+}
+
+static int gtk3_unload()
+{
+    int i;
+    char *gtk3_error;
+
+    if (!gtk3_libhandle)
+        return TRUE;
+
+    /* Release painting objects */
+    if (surface != NULL) {
+        fp_cairo_destroy(cr);
+        fp_cairo_surface_destroy(surface);
+        surface = NULL;
+    }
+
+    if (gtk3_window != NULL) {
+        /* Destroying toplevel widget will destroy all contained widgets */
+        (*fp_gtk_widget_destroy)(gtk3_window);
+
+        /* Unset some static data so they get reinitialized on next load */
+        gtk3_window = NULL;
+    }
+
+    dlerror();
+    dlclose(gtk3_libhandle);
+    if ((gtk3_error = dlerror()) != NULL)
+    {
+        return FALSE;
+    }
+    return TRUE;
+}
+
+/* Dispatch all pending events from the GTK event loop.
+ * This is needed to catch theme change and update widgets' style.
+ */
+static void flush_gtk_event_loop()
+{
+    while((*fp_g_main_context_iteration)(NULL));
+}
+
+/*
+ * Initialize components of containment hierarchy. This creates a GtkFixed
+ * inside a GtkWindow. All widgets get realized.
+ */
+static void init_containers()
+{
+    if (gtk3_window == NULL)
+    {
+        gtk3_window = (*fp_gtk_window_new)(GTK_WINDOW_TOPLEVEL);
+        gtk3_fixed = (GtkFixed *)(*fp_gtk_fixed_new)();
+        (*fp_gtk_container_add)((GtkContainer*)gtk3_window,
+                                (GtkWidget *)gtk3_fixed);
+        (*fp_gtk_widget_realize)(gtk3_window);
+        (*fp_gtk_widget_realize)((GtkWidget *)gtk3_fixed);
+
+        GtkSettings* settings = fp_gtk_settings_get_for_screen(
+                                         fp_gtk_widget_get_screen(gtk3_window));
+        gchar*  strval = NULL;
+        fp_g_object_get(settings, "gtk-theme-name", &strval, NULL);
+        gtk3_css = fp_gtk_css_provider_get_named(strval, NULL);
+    }
+}
+
+/*
+ * Ensure everything is ready for drawing an element of the specified width
+ * and height.
+ *
+ * We should somehow handle translucent images. GTK can draw to X Drawables
+ * only, which don't support alpha. When we retrieve the image back from
+ * the server, translucency information is lost. There're several ways to
+ * work around this:
+ * 1) Subclass GdkPixmap and cache translucent objects on client side. This
+ * requires us to implement parts of X server drawing logic on client side.
+ * Many X requests can potentially be "translucent"; e.g. XDrawLine with
+ * fill=tile and a translucent tile is a "translucent" operation, whereas
+ * XDrawLine with fill=solid is an "opaque" one. Moreover themes can (and some
+ * do) intermix transparent and opaque operations which makes caching even
+ * more problematic.
+ * 2) Use Xorg 32bit ARGB visual when available. GDK has no native support
+ * for it (as of version 2.6). Also even in JDS 3 Xorg does not support
+ * these visuals by default, which makes optimizing for them pointless.
+ * We can consider doing this at a later point when ARGB visuals become more
+ * popular.
+ * 3') GTK has plans to use Cairo as its graphical backend (presumably in
+ * 2.8), and Cairo supports alpha. With it we could also get rid of the
+ * unnecessary round trip to server and do all the drawing on client side.
+ * 4) For now we draw to two different pixmaps and restore alpha channel by
+ * comparing results. This can be optimized by using subclassed pixmap and
+*/
+static void gtk3_init_painting(JNIEnv *env, gint width, gint height)
+{
+    init_containers();
+
+    if (cr) {
+        fp_cairo_destroy(cr);
+    }
+
+    if (surface != NULL) {
+        /* free old stuff */
+        fp_cairo_surface_destroy(surface);
+
+    }
+
+    if (gtk3_version_3_10) {
+        surface = fp_gdk_window_create_similar_image_surface(
+                           fp_gtk_widget_get_window(gtk3_window),
+                                         CAIRO_FORMAT_ARGB32, width, height, 1);
+    } else {
+        surface = fp_cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
+                                                                 width, height);
+    }
+
+    cr = fp_cairo_create(surface);
+}
+
+/*
+ * Restore image from white and black pixmaps and copy it into destination
+ * buffer. This method compares two pixbufs taken from white and black
+ * pixmaps and decodes color and alpha components. Pixbufs are RGB without
+ * alpha, destination buffer is ABGR.
+ *
+ * The return value is the transparency type of the resulting image, either
+ * one of java_awt_Transparency_OPAQUE, java_awt_Transparency_BITMASK, and
+ * java_awt_Transparency_TRANSLUCENT.
+ */
+static gint gtk3_copy_image(gint *dst, gint width, gint height)
+{
+    gint i, j, r, g, b;
+    guchar *data;
+    gint stride, padding;
+
+    fp_cairo_surface_flush(surface);
+    data = (*fp_cairo_image_surface_get_data)(surface);
+    stride = (*fp_cairo_image_surface_get_stride)(surface);
+    padding = stride - width * 4;
+
+    for (i = 0; i < height; i++) {
+        for (j = 0; j < width; j++) {
+            int r = *data++;
+            int g = *data++;
+            int b = *data++;
+            int a = *data++;
+            *dst++ = (a << 24 | b << 16 | g << 8 | r);
+        }
+        data += padding;
+    }
+    return java_awt_Transparency_TRANSLUCENT;
+}
+
+static void gtk3_set_direction(GtkWidget *widget, GtkTextDirection dir)
+{
+    /*
+     * Some engines (inexplicably) look at the direction of the widget's
+     * parent, so we need to set the direction of both the widget and its
+     * parent.
+     */
+    (*fp_gtk_widget_set_direction)(widget, dir);
+    GtkWidget* parent = fp_gtk_widget_get_parent(widget);
+    if (parent != NULL) {
+        fp_gtk_widget_set_direction(parent, dir);
+    }
+}
+
+/* GTK state_type filter */
+static GtkStateType get_gtk_state_type(WidgetType widget_type, gint synth_state)
+{
+    GtkStateType result = GTK_STATE_NORMAL;
+
+    if ((synth_state & DISABLED) != 0) {
+        result = GTK_STATE_INSENSITIVE;
+    } else if ((synth_state & PRESSED) != 0) {
+        result = GTK_STATE_ACTIVE;
+    } else if ((synth_state & MOUSE_OVER) != 0) {
+        result = GTK_STATE_PRELIGHT;
+    }
+    return result;
+}
+
+static GtkStateFlags get_gtk_state_flags(gint synth_state)
+{
+    GtkStateFlags flags = 0;
+
+    if ((synth_state & DISABLED) != 0) {
+        flags |= GTK_STATE_FLAG_INSENSITIVE;
+    }
+    if (((synth_state & PRESSED) != 0 || (synth_state & SELECTED) != 0)) {
+        flags |= GTK_STATE_FLAG_ACTIVE;
+    }
+    if ((synth_state & MOUSE_OVER) != 0) {
+        flags |= GTK_STATE_FLAG_PRELIGHT;
+    }
+    if ((synth_state & FOCUSED) != 0) {
+        flags |= GTK_STATE_FLAG_FOCUSED;
+    }
+    return flags;
+}
+
+static GtkStateFlags get_gtk_flags(GtkStateType state_type) {
+    GtkStateFlags flags = 0;
+    switch (state_type)
+    {
+        case GTK_STATE_PRELIGHT:
+          flags |= GTK_STATE_FLAG_PRELIGHT;
+          break;
+        case GTK_STATE_SELECTED:
+          flags |= GTK_STATE_FLAG_SELECTED;
+          break;
+        case GTK_STATE_INSENSITIVE:
+          flags |= GTK_STATE_FLAG_INSENSITIVE;
+          break;
+        case GTK_STATE_ACTIVE:
+          flags |= GTK_STATE_FLAG_ACTIVE;
+          break;
+        case GTK_STATE_FOCUSED:
+          flags |= GTK_STATE_FLAG_FOCUSED;
+          break;
+        default:
+          break;
+    }
+    return flags;
+}
+
+/* GTK shadow_type filter */
+static GtkShadowType get_gtk_shadow_type(WidgetType widget_type,
+                                                               gint synth_state)
+{
+    GtkShadowType result = GTK_SHADOW_OUT;
+
+    if ((synth_state & SELECTED) != 0) {
+        result = GTK_SHADOW_IN;
+    }
+    return result;
+}
+
+
+static GtkWidget* gtk3_get_arrow(GtkArrowType arrow_type,
+                                                      GtkShadowType shadow_type)
+{
+    GtkWidget *arrow = NULL;
+    if (NULL == gtk3_widgets[_GTK_ARROW_TYPE])
+    {
+        gtk3_widgets[_GTK_ARROW_TYPE] = (*fp_gtk_arrow_new)(arrow_type,
+                                                                   shadow_type);
+        (*fp_gtk_container_add)((GtkContainer *)gtk3_fixed,
+                                                 gtk3_widgets[_GTK_ARROW_TYPE]);
+        (*fp_gtk_widget_realize)(gtk3_widgets[_GTK_ARROW_TYPE]);
+    }
+    arrow = gtk3_widgets[_GTK_ARROW_TYPE];
+
+    (*fp_gtk_arrow_set)(arrow, arrow_type, shadow_type);
+    return arrow;
+}
+
+static GtkAdjustment* create_adjustment()
+{
+    return (GtkAdjustment *)
+            (*fp_gtk_adjustment_new)(50.0, 0.0, 100.0, 10.0, 20.0, 20.0);
+}
+
+/**
+ * Returns a pointer to the cached native widget for the specified widget
+ * type.
+ */
+static GtkWidget *gtk3_get_widget(WidgetType widget_type)
+{
+    gboolean init_result = FALSE;
+    GtkWidget *result = NULL;
+    switch (widget_type)
+    {
+        case BUTTON:
+        case TABLE_HEADER:
+            if (init_result = (NULL == gtk3_widgets[_GTK_BUTTON_TYPE]))
+            {
+                gtk3_widgets[_GTK_BUTTON_TYPE] = (*fp_gtk_button_new)();
+            }
+            result = gtk3_widgets[_GTK_BUTTON_TYPE];
+            break;
+        case CHECK_BOX:
+            if (init_result = (NULL == gtk3_widgets[_GTK_CHECK_BUTTON_TYPE]))
+            {
+                gtk3_widgets[_GTK_CHECK_BUTTON_TYPE] =
+                    (*fp_gtk_check_button_new)();
+            }
+            result = gtk3_widgets[_GTK_CHECK_BUTTON_TYPE];
+            break;
+        case CHECK_BOX_MENU_ITEM:
+            if (init_result = (NULL == gtk3_widgets[_GTK_CHECK_MENU_ITEM_TYPE]))
+            {
+                gtk3_widgets[_GTK_CHECK_MENU_ITEM_TYPE] =
+                    (*fp_gtk_check_menu_item_new)();
+            }
+            result = gtk3_widgets[_GTK_CHECK_MENU_ITEM_TYPE];
+            break;
+        /************************************************************
+         *    Creation a dedicated color chooser is dangerous because
+         * it deadlocks the EDT
+         ************************************************************/
+/*        case COLOR_CHOOSER:
+            if (init_result =
+                    (NULL == gtk3_widgets[_GTK_COLOR_SELECTION_DIALOG_TYPE]))
+            {
+                gtk3_widgets[_GTK_COLOR_SELECTION_DIALOG_TYPE] =
+                    (*fp_gtk_color_selection_dialog_new)(NULL);
+            }
+            result = gtk3_widgets[_GTK_COLOR_SELECTION_DIALOG_TYPE];
+            break;*/
+        case COMBO_BOX:
+            if (init_result = (NULL == gtk3_widgets[_GTK_COMBO_BOX_TYPE]))
+            {
+                gtk3_widgets[_GTK_COMBO_BOX_TYPE] =
+                    (*fp_gtk_combo_box_new)();
+            }
+            result = gtk3_widgets[_GTK_COMBO_BOX_TYPE];
+            break;
+        case COMBO_BOX_ARROW_BUTTON:
+            if (init_result =
+                    (NULL == gtk3_widgets[_GTK_COMBO_BOX_ARROW_BUTTON_TYPE]))
+            {
+                gtk3_widgets[_GTK_COMBO_BOX_ARROW_BUTTON_TYPE] =
+                     (*fp_gtk_toggle_button_new)();
+            }
+            result = gtk3_widgets[_GTK_COMBO_BOX_ARROW_BUTTON_TYPE];
+            break;
+        case COMBO_BOX_TEXT_FIELD:
+            if (init_result =
+                    (NULL == gtk3_widgets[_GTK_COMBO_BOX_TEXT_FIELD_TYPE]))
+            {
+                result = gtk3_widgets[_GTK_COMBO_BOX_TEXT_FIELD_TYPE] =
+                     (*fp_gtk_entry_new)();
+            }
+            result = gtk3_widgets[_GTK_COMBO_BOX_TEXT_FIELD_TYPE];
+            break;
+        case DESKTOP_ICON:
+        case INTERNAL_FRAME_TITLE_PANE:
+        case LABEL:
+            if (init_result = (NULL == gtk3_widgets[_GTK_LABEL_TYPE]))
+            {
+                gtk3_widgets[_GTK_LABEL_TYPE] =
+                    (*fp_gtk_label_new)(NULL);
+            }
+            result = gtk3_widgets[_GTK_LABEL_TYPE];
+            break;
+        case DESKTOP_PANE:
+        case PANEL:
+        case ROOT_PANE:
+            if (init_result = (NULL == gtk3_widgets[_GTK_CONTAINER_TYPE]))
+            {
+                /* There is no constructor for a container type.  I've
+                 * chosen GtkFixed container since it has a default
+                 * constructor.
+                 */
+                gtk3_widgets[_GTK_CONTAINER_TYPE] =
+                    (*fp_gtk_fixed_new)();
+            }
+            result = gtk3_widgets[_GTK_CONTAINER_TYPE];
+            break;
+        case EDITOR_PANE:
+        case TEXT_AREA:
+        case TEXT_PANE:
+            if (init_result = (NULL == gtk3_widgets[_GTK_TEXT_VIEW_TYPE]))
+            {
+                gtk3_widgets[_GTK_TEXT_VIEW_TYPE] =
+                    (*fp_gtk_text_view_new)();
+            }
+            result = gtk3_widgets[_GTK_TEXT_VIEW_TYPE];
+            break;
+        case FORMATTED_TEXT_FIELD:
+        case PASSWORD_FIELD:
+        case TEXT_FIELD:
+            if (init_result = (NULL == gtk3_widgets[_GTK_ENTRY_TYPE]))
+            {
+                gtk3_widgets[_GTK_ENTRY_TYPE] =
+                    (*fp_gtk_entry_new)();
+            }
+            result = gtk3_widgets[_GTK_ENTRY_TYPE];
+            break;
+        case HANDLE_BOX:
+            if (init_result = (NULL == gtk3_widgets[_GTK_HANDLE_BOX_TYPE]))
+            {
+                gtk3_widgets[_GTK_HANDLE_BOX_TYPE] =
+                    (*fp_gtk_handle_box_new)();
+            }
+            result = gtk3_widgets[_GTK_HANDLE_BOX_TYPE];
+            break;
+        case HSCROLL_BAR:
+        case HSCROLL_BAR_BUTTON_LEFT:
+        case HSCROLL_BAR_BUTTON_RIGHT:
+        case HSCROLL_BAR_TRACK:
+        case HSCROLL_BAR_THUMB:
+            if (init_result = (NULL == gtk3_widgets[_GTK_HSCROLLBAR_TYPE]))
+            {
+                gtk3_widgets[_GTK_HSCROLLBAR_TYPE] =
+                    (*fp_gtk_hscrollbar_new)(create_adjustment());
+            }
+            result = gtk3_widgets[_GTK_HSCROLLBAR_TYPE];
+            break;
+        case HSEPARATOR:
+            if (init_result = (NULL == gtk3_widgets[_GTK_HSEPARATOR_TYPE]))
+            {
+                gtk3_widgets[_GTK_HSEPARATOR_TYPE] =
+                    (*fp_gtk_hseparator_new)();
+            }
+            result = gtk3_widgets[_GTK_HSEPARATOR_TYPE];
+            break;
+        case HSLIDER:
+        case HSLIDER_THUMB:
+        case HSLIDER_TRACK:
+            if (init_result = (NULL == gtk3_widgets[_GTK_HSCALE_TYPE]))
+            {
+                gtk3_widgets[_GTK_HSCALE_TYPE] =
+                    (*fp_gtk_scale_new)(GTK_ORIENTATION_HORIZONTAL, NULL);
+            }
+            result = gtk3_widgets[_GTK_HSCALE_TYPE];
+            break;
+        case HSPLIT_PANE_DIVIDER:
+        case SPLIT_PANE:
+            if (init_result = (NULL == gtk3_widgets[_GTK_HPANED_TYPE]))
+            {
+                gtk3_widgets[_GTK_HPANED_TYPE] = (*fp_gtk_hpaned_new)();
+            }
+            result = gtk3_widgets[_GTK_HPANED_TYPE];
+            break;
+        case IMAGE:
+            if (init_result = (NULL == gtk3_widgets[_GTK_IMAGE_TYPE]))
+            {
+                gtk3_widgets[_GTK_IMAGE_TYPE] = (*fp_gtk_image_new)();
+            }
+            result = gtk3_widgets[_GTK_IMAGE_TYPE];
+            break;
+        case INTERNAL_FRAME:
+            if (init_result = (NULL == gtk3_widgets[_GTK_WINDOW_TYPE]))
+            {
+                gtk3_widgets[_GTK_WINDOW_TYPE] =
+                    (*fp_gtk_window_new)(GTK_WINDOW_TOPLEVEL);
+            }
+            result = gtk3_widgets[_GTK_WINDOW_TYPE];
+            break;
+        case TOOL_TIP:
+            if (init_result = (NULL == gtk3_widgets[_GTK_TOOLTIP_TYPE]))
+            {
+                result = (*fp_gtk_window_new)(GTK_WINDOW_TOPLEVEL);
+                gtk3_widgets[_GTK_TOOLTIP_TYPE] = result;
+            }
+            result = gtk3_widgets[_GTK_TOOLTIP_TYPE];
+            break;
+        case LIST:
+        case TABLE:
+        case TREE:
+        case TREE_CELL:
+            if (init_result = (NULL == gtk3_widgets[_GTK_TREE_VIEW_TYPE]))
+            {
+                gtk3_widgets[_GTK_TREE_VIEW_TYPE] =
+                    (*fp_gtk_tree_view_new)();
+            }
+            result = gtk3_widgets[_GTK_TREE_VIEW_TYPE];
+            break;
+        case TITLED_BORDER:
+            if (init_result = (NULL == gtk3_widgets[_GTK_FRAME_TYPE]))
+            {
+                gtk3_widgets[_GTK_FRAME_TYPE] = fp_gtk_frame_new(NULL);
+            }
+            result = gtk3_widgets[_GTK_FRAME_TYPE];
+            break;
+        case POPUP_MENU:
+            if (init_result = (NULL == gtk3_widgets[_GTK_MENU_TYPE]))
+            {
+                gtk3_widgets[_GTK_MENU_TYPE] =
+                    (*fp_gtk_menu_new)();
+            }
+            result = gtk3_widgets[_GTK_MENU_TYPE];
+            break;
+        case MENU:
+        case MENU_ITEM:
+        case MENU_ITEM_ACCELERATOR:
+            if (init_result = (NULL == gtk3_widgets[_GTK_MENU_ITEM_TYPE]))
+            {
+                gtk3_widgets[_GTK_MENU_ITEM_TYPE] =
+                    (*fp_gtk_menu_item_new)();
+            }
+            result = gtk3_widgets[_GTK_MENU_ITEM_TYPE];
+            break;
+        case MENU_BAR:
+            if (init_result = (NULL == gtk3_widgets[_GTK_MENU_BAR_TYPE]))
+            {
+                gtk3_widgets[_GTK_MENU_BAR_TYPE] =
+                    (*fp_gtk_menu_bar_new)();
+            }
+            result = gtk3_widgets[_GTK_MENU_BAR_TYPE];
+            break;
+        case COLOR_CHOOSER:
+        case OPTION_PANE:
+            if (init_result = (NULL == gtk3_widgets[_GTK_DIALOG_TYPE]))
+            {
+                gtk3_widgets[_GTK_DIALOG_TYPE] =
+                    (*fp_gtk_dialog_new)();
+            }
+            result = gtk3_widgets[_GTK_DIALOG_TYPE];
+            break;
+        case POPUP_MENU_SEPARATOR:
+            if (init_result =
+                    (NULL == gtk3_widgets[_GTK_SEPARATOR_MENU_ITEM_TYPE]))
+            {
+                gtk3_widgets[_GTK_SEPARATOR_MENU_ITEM_TYPE] =
+                    (*fp_gtk_separator_menu_item_new)();
+            }
+            result = gtk3_widgets[_GTK_SEPARATOR_MENU_ITEM_TYPE];
+            break;
+        case HPROGRESS_BAR:
+            if (init_result = (NULL == gtk3_widgets[_GTK_HPROGRESS_BAR_TYPE]))
+            {
+                gtk3_widgets[_GTK_HPROGRESS_BAR_TYPE] =
+                    (*fp_gtk_progress_bar_new)();
+            }
+            result = gtk3_widgets[_GTK_HPROGRESS_BAR_TYPE];
+            break;
+        case VPROGRESS_BAR:
+            if (init_result = (NULL == gtk3_widgets[_GTK_VPROGRESS_BAR_TYPE]))
+            {
+                gtk3_widgets[_GTK_VPROGRESS_BAR_TYPE] =
+                    (*fp_gtk_progress_bar_new)();
+                /*
+                 * Vertical JProgressBars always go bottom-to-top,
+                 * regardless of the ComponentOrientation.
+                 */
+                (*fp_gtk_progress_bar_set_orientation)(
+                    (GtkProgressBar *)gtk3_widgets[_GTK_VPROGRESS_BAR_TYPE],
+                    GTK_PROGRESS_BOTTOM_TO_TOP);
+            }
+            result = gtk3_widgets[_GTK_VPROGRESS_BAR_TYPE];
+            break;
+        case RADIO_BUTTON:
+            if (init_result = (NULL == gtk3_widgets[_GTK_RADIO_BUTTON_TYPE]))
+            {
+                gtk3_widgets[_GTK_RADIO_BUTTON_TYPE] =
+                    (*fp_gtk_radio_button_new)(NULL);
+            }
+            result = gtk3_widgets[_GTK_RADIO_BUTTON_TYPE];
+            break;
+        case RADIO_BUTTON_MENU_ITEM:
+            if (init_result =
+                    (NULL == gtk3_widgets[_GTK_RADIO_MENU_ITEM_TYPE]))
+            {
+                gtk3_widgets[_GTK_RADIO_MENU_ITEM_TYPE] =
+                    (*fp_gtk_radio_menu_item_new)(NULL);
+            }
+            result = gtk3_widgets[_GTK_RADIO_MENU_ITEM_TYPE];
+            break;
+        case SCROLL_PANE:
+            if (init_result =
+                    (NULL == gtk3_widgets[_GTK_SCROLLED_WINDOW_TYPE]))
+            {
+                gtk3_widgets[_GTK_SCROLLED_WINDOW_TYPE] =
+                    (*fp_gtk_scrolled_window_new)(NULL, NULL);
+            }
+            result = gtk3_widgets[_GTK_SCROLLED_WINDOW_TYPE];
+            break;
+        case SPINNER:
+        case SPINNER_ARROW_BUTTON:
+        case SPINNER_TEXT_FIELD:
+            if (init_result = (NULL == gtk3_widgets[_GTK_SPIN_BUTTON_TYPE]))
+            {
+                result = gtk3_widgets[_GTK_SPIN_BUTTON_TYPE] =
+                    (*fp_gtk_spin_button_new)(NULL, 0, 0);
+            }
+            result = gtk3_widgets[_GTK_SPIN_BUTTON_TYPE];
+            break;
+        case TABBED_PANE:
+        case TABBED_PANE_TAB_AREA:
+        case TABBED_PANE_CONTENT:
+        case TABBED_PANE_TAB:
+            if (init_result = (NULL == gtk3_widgets[_GTK_NOTEBOOK_TYPE]))
+            {
+                gtk3_widgets[_GTK_NOTEBOOK_TYPE] =
+                    (*fp_gtk_notebook_new)(NULL);
+            }
+            result = gtk3_widgets[_GTK_NOTEBOOK_TYPE];
+            break;
+        case TOGGLE_BUTTON:
+            if (init_result = (NULL == gtk3_widgets[_GTK_TOGGLE_BUTTON_TYPE]))
+            {
+                gtk3_widgets[_GTK_TOGGLE_BUTTON_TYPE] =
+                    (*fp_gtk_toggle_button_new)(NULL);
+            }
+            result = gtk3_widgets[_GTK_TOGGLE_BUTTON_TYPE];
+            break;
+        case TOOL_BAR:
+        case TOOL_BAR_DRAG_WINDOW:
+            if (init_result = (NULL == gtk3_widgets[_GTK_TOOLBAR_TYPE]))
+            {
+                gtk3_widgets[_GTK_TOOLBAR_TYPE] =
+                    (*fp_gtk_toolbar_new)(NULL);
+            }
+            result = gtk3_widgets[_GTK_TOOLBAR_TYPE];
+            break;
+        case TOOL_BAR_SEPARATOR:
+            if (init_result =
+                    (NULL == gtk3_widgets[_GTK_SEPARATOR_TOOL_ITEM_TYPE]))
+            {
+                gtk3_widgets[_GTK_SEPARATOR_TOOL_ITEM_TYPE] =
+                    (*fp_gtk_separator_tool_item_new)();
+            }
+            result = gtk3_widgets[_GTK_SEPARATOR_TOOL_ITEM_TYPE];
+            break;
+        case VIEWPORT:
+            if (init_result = (NULL == gtk3_widgets[_GTK_VIEWPORT_TYPE]))
+            {
+                GtkAdjustment *adjustment = create_adjustment();
+                gtk3_widgets[_GTK_VIEWPORT_TYPE] =
+                    (*fp_gtk_viewport_new)(adjustment, adjustment);
+            }
+            result = gtk3_widgets[_GTK_VIEWPORT_TYPE];
+            break;
+        case VSCROLL_BAR:
+        case VSCROLL_BAR_BUTTON_UP:
+        case VSCROLL_BAR_BUTTON_DOWN:
+        case VSCROLL_BAR_TRACK:
+        case VSCROLL_BAR_THUMB:
+            if (init_result = (NULL == gtk3_widgets[_GTK_VSCROLLBAR_TYPE]))
+            {
+                gtk3_widgets[_GTK_VSCROLLBAR_TYPE] =
+                    (*fp_gtk_vscrollbar_new)(create_adjustment());
+            }
+            result = gtk3_widgets[_GTK_VSCROLLBAR_TYPE];
+            break;
+        case VSEPARATOR:
+            if (init_result = (NULL == gtk3_widgets[_GTK_VSEPARATOR_TYPE]))
+            {
+                gtk3_widgets[_GTK_VSEPARATOR_TYPE] =
+                    (*fp_gtk_vseparator_new)();
+            }
+            result = gtk3_widgets[_GTK_VSEPARATOR_TYPE];
+            break;
+        case VSLIDER:
+        case VSLIDER_THUMB:
+        case VSLIDER_TRACK:
+            if (init_result = (NULL == gtk3_widgets[_GTK_VSCALE_TYPE]))
+            {
+                gtk3_widgets[_GTK_VSCALE_TYPE] =
+                    (*fp_gtk_scale_new)(GTK_ORIENTATION_VERTICAL, NULL);
+            }
+            result = gtk3_widgets[_GTK_VSCALE_TYPE];
+            /*
+             * Vertical JSliders start at the bottom, while vertical
+             * GtkVScale widgets start at the top (by default), so to fix
+             * this we set the "inverted" flag to get the Swing behavior.
+             */
+             fp_gtk_range_set_inverted((GtkRange*)result, TRUE);
+            break;
+        case VSPLIT_PANE_DIVIDER:
+            if (init_result = (NULL == gtk3_widgets[_GTK_VPANED_TYPE]))
+            {
+                gtk3_widgets[_GTK_VPANED_TYPE] = (*fp_gtk_vpaned_new)();
+            }
+            result = gtk3_widgets[_GTK_VPANED_TYPE];
+            break;
+        default:
+            result = NULL;
+            break;
+    }
+
+    if (result != NULL && init_result)
+    {
+        if (widget_type == RADIO_BUTTON_MENU_ITEM ||
+                widget_type == CHECK_BOX_MENU_ITEM ||
+                widget_type == MENU_ITEM ||
+                widget_type == MENU ||
+                widget_type == POPUP_MENU_SEPARATOR)
+        {
+            GtkWidget *menu = gtk3_get_widget(POPUP_MENU);
+            (*fp_gtk_menu_shell_append)((GtkMenuShell *)menu, result);
+        }
+        else if (widget_type == POPUP_MENU)
+        {
+            GtkWidget *menu_bar = gtk3_get_widget(MENU_BAR);
+            GtkWidget *root_menu = (*fp_gtk_menu_item_new)();
+            (*fp_gtk_menu_item_set_submenu)((GtkMenuItem*)root_menu, result);
+            (*fp_gtk_menu_shell_append)((GtkMenuShell *)menu_bar, root_menu);
+        }
+        else if (widget_type == COMBO_BOX_TEXT_FIELD )
+        {
+            GtkWidget* combo = gtk3_get_widget(COMBO_BOX);
+
+            /*
+            * We add a regular GtkButton/GtkEntry to a GtkComboBoxEntry
+            * in order to trick engines into thinking it's a real combobox
+            * arrow button/text field.
+            */
+
+            fp_gtk_container_add ((GtkContainer*)(combo), result);
+            GtkStyleContext* context = fp_gtk_widget_get_style_context (combo);
+            fp_gtk_style_context_add_class (context, "combobox-entry");
+            context = fp_gtk_widget_get_style_context (result);
+            fp_gtk_style_context_add_class (context, "combobox");
+            fp_gtk_style_context_add_class (context, "entry");
+        }
+        else if (widget_type == COMBO_BOX_ARROW_BUTTON )
+        {
+            GtkWidget* combo = gtk3_get_widget(COMBO_BOX);
+            fp_gtk_widget_set_parent(result, combo);
+        }
+        else if (widget_type != TOOL_TIP &&
+                 widget_type != INTERNAL_FRAME &&
+                 widget_type != OPTION_PANE)
+        {
+            (*fp_gtk_container_add)((GtkContainer *)gtk3_fixed, result);
+        }
+        (*fp_gtk_widget_realize)(result);
+    }
+    return result;
+}
+
+static void gtk3_paint_arrow(WidgetType widget_type, GtkStateType state_type,
+        GtkShadowType shadow_type, const gchar *detail,
+        gint x, gint y, gint width, gint height,
+        GtkArrowType arrow_type, gboolean fill)
+{
+    gdouble xx, yy, a = G_PI;
+    int s = width;
+    gtk3_widget = gtk3_get_arrow(arrow_type, shadow_type);
+
+    switch (widget_type)
+    {
+        case SPINNER_ARROW_BUTTON:
+            s = (int)(0.4 * width + 0.5) + 1;
+            if (arrow_type == GTK_ARROW_UP) {
+                a = 0;
+            } else if (arrow_type == GTK_ARROW_DOWN) {
+                a = G_PI;
+            }
+            break;
+
+        case HSCROLL_BAR_BUTTON_LEFT:
+            s = (int)(0.5 * MIN(height, width * 2) + 0.5) + 1;
+            a = 3 * G_PI / 2;
+            break;
+
+        case HSCROLL_BAR_BUTTON_RIGHT:
+            s = (int)(0.5 * MIN(height, width * 2) + 0.5) + 1;
+            a = G_PI / 2;
+            break;
+
+        case VSCROLL_BAR_BUTTON_UP:
+            s = (int)(0.5 * MIN(height * 2, width) + 0.5) + 1;
+            a = 0;
+            break;
+
+        case VSCROLL_BAR_BUTTON_DOWN:
+            s = (int)(0.5 * MIN(height * 2, width) + 0.5) + 1;
+            a = G_PI;
+            break;
+
+        case COMBO_BOX_ARROW_BUTTON:
+            s = (int)(0.3 * height + 0.5) + 1;
+            a = G_PI;
+            break;
+
+        case TABLE:
+            s = (int)(0.8 * height + 0.5) + 1;
+            if (arrow_type == GTK_ARROW_UP) {
+                a = G_PI;
+            } else if (arrow_type == GTK_ARROW_DOWN) {
+                a = 0;
+            }
+            break;
+
+        case MENU_ITEM:
+            if (arrow_type == GTK_ARROW_UP) {
+                a = G_PI;
+            } else if (arrow_type == GTK_ARROW_DOWN) {
+                a = 0;
+            } else if (arrow_type == GTK_ARROW_RIGHT) {
+                a = G_PI / 2;
+            } else if (arrow_type == GTK_ARROW_LEFT) {
+                a = 3 * G_PI / 2;
+            }
+            break;
+
+        default:
+            if (arrow_type == GTK_ARROW_UP) {
+                a = G_PI;
+            } else if (arrow_type == GTK_ARROW_DOWN) {
+                a = 0;
+            } else if (arrow_type == GTK_ARROW_RIGHT) {
+                a = G_PI / 2;
+            } else if (arrow_type == GTK_ARROW_LEFT) {
+                a = 3 * G_PI / 2;
+            }
+            break;
+    }
+
+    if (s < width && s < height) {
+        xx = x + (0.5 * (width - s) + 0.5);
+        yy = y + (0.5 * (height - s) + 0.5);
+    } else {
+        xx = x;
+        yy = y;
+    }
+
+    GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
+    fp_gtk_style_context_save (context);
+
+
+    if (detail != NULL) {
+        transform_detail_string(detail, context);
+    }
+
+    GtkStateFlags flags = get_gtk_flags(state_type);
+
+    fp_gtk_style_context_set_state (context, flags);
+
+    (*fp_gtk_render_arrow)(context, cr, a, xx, yy, s);
+
+    fp_gtk_style_context_restore (context);
+}
+
+static void gtk3_paint_box(WidgetType widget_type, GtkStateType state_type,
+                    GtkShadowType shadow_type, const gchar *detail,
+                    gint x, gint y, gint width, gint height,
+                    gint synth_state, GtkTextDirection dir)
+{
+    gtk3_widget = gtk3_get_widget(widget_type);
+
+    if (widget_type == HSLIDER_TRACK) {
+        /*
+         * For horizontal JSliders with right-to-left orientation, we need
+         * to set the "inverted" flag to match the native GTK behavior where
+         * the foreground highlight is on the right side of the slider thumb.
+         * This is needed especially for the ubuntulooks engine, which looks
+         * exclusively at the "inverted" flag to determine on which side of
+         * the thumb to paint the highlight...
+         */
+        fp_gtk_range_set_inverted((GtkRange*)gtk3_widget, dir ==
+                                                              GTK_TEXT_DIR_RTL);
+
+        /*
+         * Note however that other engines like clearlooks will look at both
+         * the "inverted" field and the text direction to determine how
+         * the foreground highlight is painted:
+         *     !inverted && ltr --> paint highlight on left side
+         *     !inverted && rtl --> paint highlight on right side
+         *      inverted && ltr --> paint highlight on right side
+         *      inverted && rtl --> paint highlight on left side
+         * So the only way to reliably get the desired results for horizontal
+         * JSlider (i.e., highlight on left side for LTR ComponentOrientation
+         * and highlight on right side for RTL ComponentOrientation) is to
+         * always override text direction as LTR, and then set the "inverted"
+         * flag accordingly (as we have done above).
+         */
+        dir = GTK_TEXT_DIR_LTR;
+    }
+
+    /*
+     * Some engines (e.g. clearlooks) will paint the shadow of certain
+     * widgets (e.g. COMBO_BOX_ARROW_BUTTON) differently depending on the
+     * the text direction.
+     */
+    gtk3_set_direction(gtk3_widget, dir);
+
+    GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
+    fp_gtk_style_context_save (context);
+
+    transform_detail_string(detail, context);
+
+    GtkStateFlags flags = get_gtk_flags(state_type);
+
+    if (shadow_type == GTK_SHADOW_IN && widget_type != COMBO_BOX_ARROW_BUTTON) {
+        flags |= GTK_STATE_FLAG_ACTIVE;
+    }
+
+    if (synth_state & MOUSE_OVER) {
+        flags |= GTK_STATE_FLAG_PRELIGHT;
+    }
+
+    if (synth_state & FOCUSED) {
+        flags |= GTK_STATE_FLAG_FOCUSED;
+    }
+
+    if (synth_state & DEFAULT) {
+        fp_gtk_style_context_add_class (context, "default");
+    }
+
+    fp_gtk_style_context_set_state (context, flags);
+
+    if (fp_gtk_style_context_has_class(context, "progressbar")) {
+        fp_gtk_render_activity (context, cr, x, y, width, height);
+    } else {
+        fp_gtk_render_background (context, cr, x, y, width, height);
+        if (shadow_type != GTK_SHADOW_NONE) {
+            fp_gtk_render_frame(context, cr, x, y, width, height);
+        }
+    }
+
+    fp_gtk_style_context_restore (context);
+    /*
+     * Reset the text direction to the default value so that we don't
+     * accidentally affect other operations and widgets.
+     */
+    gtk3_set_direction(gtk3_widget, GTK_TEXT_DIR_LTR);
+}
+
+static void gtk3_paint_box_gap(WidgetType widget_type, GtkStateType state_type,
+        GtkShadowType shadow_type, const gchar *detail,
+        gint x, gint y, gint width, gint height,
+        GtkPositionType gap_side, gint gap_x, gint gap_width)
+{
+    gtk3_widget = gtk3_get_widget(widget_type);
+
+    GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
+
+    fp_gtk_style_context_save (context);
+
+    GtkStateFlags flags = get_gtk_flags(state_type);
+    fp_gtk_style_context_set_state(context, flags);
+
+    if (detail != 0) {
+        transform_detail_string(detail, context);
+    }
+    fp_gtk_render_background(context, cr, x, y, width, height);
+
+    if (shadow_type != GTK_SHADOW_NONE) {
+        fp_gtk_render_frame_gap(context, cr, x, y, width, height, gap_side,
+                                    (gdouble)gap_x, (gdouble)gap_x + gap_width);
+    }
+    fp_gtk_style_context_restore (context);
+}
+
+static void gtk3_paint_check(WidgetType widget_type, gint synth_state,
+        const gchar *detail, gint x, gint y, gint width, gint height)
+{
+    gtk3_widget = gtk3_get_widget(widget_type);
+
+    GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
+
+    fp_gtk_style_context_save (context);
+
+    GtkStateFlags flags = get_gtk_state_flags(synth_state);
+    if (gtk3_version_3_14 && (synth_state & SELECTED)) {
+        flags = GTK_STATE_FLAG_CHECKED;
+    }
+    fp_gtk_style_context_set_state(context, flags);
+
+    fp_gtk_style_context_add_class (context, "check");
+
+    fp_gtk_render_check (context, cr, x, y, width, height);
+
+    fp_gtk_style_context_restore (context);
+}
+
+
+static void gtk3_paint_expander(WidgetType widget_type, GtkStateType state_type,
+        const gchar *detail, gint x, gint y, gint width, gint height,
+        GtkExpanderStyle expander_style)
+{
+    gtk3_widget = gtk3_get_widget(widget_type);
+
+    GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
+
+    fp_gtk_style_context_save (context);
+
+    GtkStateFlags flags = get_gtk_flags(state_type);
+    fp_gtk_style_context_set_state(context, flags);
+
+    if (detail != 0) {
+        transform_detail_string(detail, context);
+    }
+
+    fp_gtk_render_expander (context, cr, x, y, width, height);
+
+    fp_gtk_style_context_restore (context);
+}
+
+static void gtk3_paint_extension(WidgetType widget_type, GtkStateType state_type,
+        GtkShadowType shadow_type, const gchar *detail,
+        gint x, gint y, gint width, gint height, GtkPositionType gap_side)
+{
+    gtk3_widget = gtk3_get_widget(widget_type);
+
+    GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
+
+    fp_gtk_style_context_save (context);
+
+    GtkStateFlags flags = GTK_STATE_FLAG_NORMAL;
+
+    if (state_type == 0) {
+        flags = GTK_STATE_FLAG_ACTIVE;
+    }
+
+    fp_gtk_style_context_set_state(context, flags);
+
+    if (detail != 0) {
+        transform_detail_string(detail, context);
+    }
+    switch(gap_side) {
+      case GTK_POS_LEFT:
+        fp_gtk_style_context_add_class(context, "right");
+        break;
+      case GTK_POS_RIGHT:
+        fp_gtk_style_context_add_class(context, "left");
+        break;
+      case GTK_POS_TOP:
+        fp_gtk_style_context_add_class(context, "bottom");
+        break;
+      case GTK_POS_BOTTOM:
+        fp_gtk_style_context_add_class(context, "top");
+        break;
+      default:
+        break;
+    }
+
+    fp_gtk_render_extension(context, cr, x, y, width, height, gap_side);
+
+    fp_gtk_style_context_restore (context);
+}
+
+static void gtk3_paint_flat_box(WidgetType widget_type, GtkStateType state_type,
+        GtkShadowType shadow_type, const gchar *detail,
+        gint x, gint y, gint width, gint height, gboolean has_focus)
+{
+    if (state_type == GTK_STATE_PRELIGHT &&
+        (widget_type == CHECK_BOX || widget_type == RADIO_BUTTON)) {
+        return;
+    }
+    gtk3_widget = gtk3_get_widget(widget_type);
+
+    GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
+
+    fp_gtk_style_context_save (context);
+
+    if (detail != 0) {
+        transform_detail_string(detail, context);
+    }
+
+    GtkStateFlags flags = get_gtk_flags(state_type);
+
+    if (has_focus) {
+        flags |= GTK_STATE_FLAG_FOCUSED;
+    }
+
+    fp_gtk_style_context_set_state (context, flags);
+
+    if (widget_type == COMBO_BOX_TEXT_FIELD) {
+        width += height /2;
+    }
+
+    fp_gtk_render_background (context, cr, x, y, width, height);
+
+    fp_gtk_style_context_restore (context);
+}
+
+static void gtk3_paint_focus(WidgetType widget_type, GtkStateType state_type,
+        const char *detail, gint x, gint y, gint width, gint height)
+{
+    gtk3_widget = gtk3_get_widget(widget_type);
+
+    GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
+    fp_gtk_style_context_save (context);
+
+    transform_detail_string(detail, context);
+    fp_gtk_render_focus (context, cr, x, y, width, height);
+
+    fp_gtk_style_context_restore (context);
+
+}
+
+static void gtk3_paint_handle(WidgetType widget_type, GtkStateType state_type,
+        GtkShadowType shadow_type, const gchar *detail,
+        gint x, gint y, gint width, gint height, GtkOrientation orientation)
+{
+    gtk3_widget = gtk3_get_widget(widget_type);
+
+    GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
+
+    fp_gtk_style_context_save (context);
+
+    GtkStateFlags flags = get_gtk_flags(state_type);
+    fp_gtk_style_context_set_state(context, GTK_STATE_FLAG_PRELIGHT);
+
+    if (detail != 0) {
+        transform_detail_string(detail, context);
+        fp_gtk_style_context_add_class (context, "handlebox_bin");
+    }
+
+    fp_gtk_render_handle(context, cr, x, y, width, height);
+    fp_gtk_render_background(context, cr, x, y, width, height);
+
+    fp_gtk_style_context_restore (context);
+}
+
+static void gtk3_paint_hline(WidgetType widget_type, GtkStateType state_type,
+        const gchar *detail, gint x, gint y, gint width, gint height)
+{
+    gtk3_widget = gtk3_get_widget(widget_type);
+
+    GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
+
+    fp_gtk_style_context_save (context);
+
+    if (detail != 0) {
+        transform_detail_string(detail, context);
+    }
+
+    fp_gtk_render_line(context, cr, x, y, x + width, y);
+
+    fp_gtk_style_context_restore (context);
+}
+
+static void gtk3_paint_vline(WidgetType widget_type, GtkStateType state_type,
+        const gchar *detail, gint x, gint y, gint width, gint height)
+{
+    gtk3_widget = gtk3_get_widget(widget_type);
+
+
+    GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
+
+    fp_gtk_style_context_save (context);
+
+    if (detail != 0) {
+        transform_detail_string(detail, context);
+    }
+
+    fp_gtk_render_line(context, cr, x, y, x, y + height);
+
+    fp_gtk_style_context_restore (context);
+}
+
+static void gtk3_paint_option(WidgetType widget_type, gint synth_state,
+        const gchar *detail, gint x, gint y, gint width, gint height)
+{
+     gtk3_widget = gtk3_get_widget(widget_type);
+
+     GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
+
+     fp_gtk_style_context_save (context);
+
+     GtkStateFlags flags = get_gtk_state_flags(synth_state);
+     if (gtk3_version_3_14 && (synth_state & SELECTED)) {
+         flags = GTK_STATE_FLAG_CHECKED;
+     }
+     fp_gtk_style_context_set_state(context, flags);
+
+     if (detail != 0) {
+         transform_detail_string(detail, context);
+     }
+
+     fp_gtk_render_option(context, cr, x, y, width, height);
+
+     fp_gtk_style_context_restore (context);
+}
+
+static void gtk3_paint_shadow(WidgetType widget_type, GtkStateType state_type,
+                       GtkShadowType shadow_type, const gchar *detail,
+                       gint x, gint y, gint width, gint height,
+                       gint synth_state, GtkTextDirection dir)
+{
+    if (shadow_type == GTK_SHADOW_NONE) {
+        return;
+    }
+    gtk3_widget = gtk3_get_widget(widget_type);
+
+    /*
+     * Some engines (e.g. clearlooks) will paint the shadow of certain
+     * widgets (e.g. COMBO_BOX_TEXT_FIELD) differently depending on the
+     * the text direction.
+     */
+    gtk3_set_direction(gtk3_widget, dir);
+
+
+    GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
+    fp_gtk_style_context_save (context);
+
+    if (detail) {
+        transform_detail_string(detail, context);
+    }
+
+    GtkStateFlags flags = get_gtk_flags(state_type);
+
+    if (synth_state & MOUSE_OVER) {
+        flags |= GTK_STATE_FLAG_PRELIGHT;
+    }
+
+    if (synth_state & FOCUSED) {
+        flags |= GTK_STATE_FLAG_FOCUSED;
+    }
+
+    fp_gtk_style_context_set_state (context, flags);
+
+    if (widget_type == COMBO_BOX_TEXT_FIELD) {
+        width += height / 2;
+    }
+    fp_gtk_render_frame(context, cr, x, y, width, height);
+
+    fp_gtk_style_context_restore (context);
+
+    /*
+     * Reset the text direction to the default value so that we don't
+     * accidentally affect other operations and widgets.
+     */
+    gtk3_set_direction(gtk3_widget, GTK_TEXT_DIR_LTR);
+}
+
+static void gtk3_paint_slider(WidgetType widget_type, GtkStateType state_type,
+        GtkShadowType shadow_type, const gchar *detail,
+        gint x, gint y, gint width, gint height, GtkOrientation orientation,
+        gboolean has_focus)
+{
+    gtk3_widget = gtk3_get_widget(widget_type);
+
+    GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
+
+    fp_gtk_style_context_save (context);
+
+    if (detail) {
+       transform_detail_string(detail, context);
+    }
+
+    GtkStateFlags flags = get_gtk_flags(state_type);
+
+    if (state_type == GTK_STATE_ACTIVE) {
+        flags |= GTK_STATE_FLAG_PRELIGHT;
+    }
+
+    if (has_focus) {
+        flags |= GTK_STATE_FLAG_FOCUSED;
+    }
+
+    fp_gtk_style_context_set_state (context, flags);
+
+    (*fp_gtk_render_slider)(context, cr, x, y, width, height, orientation);
+
+    fp_gtk_style_context_restore (context);
+}
+
+static void gtk3_paint_background(WidgetType widget_type,
+             GtkStateType state_type, gint x, gint y, gint width, gint height) {
+    gtk3_widget = gtk3_get_widget(widget_type);
+
+    GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
+    fp_gtk_style_context_save (context);
+
+    GtkStateFlags flags = get_gtk_flags(state_type);
+
+    fp_gtk_style_context_set_state (context, flags);
+
+    fp_gtk_render_background (context, cr, x, y, width, height);
+
+    fp_gtk_style_context_restore (context);
+}
+
+static GdkPixbuf *gtk3_get_stock_icon(gint widget_type, const gchar *stock_id,
+        GtkIconSize size, GtkTextDirection direction, const char *detail)
+{
+    int sz;
+
+    switch(size) {
+      case GTK_ICON_SIZE_MENU:
+        sz = 16;
+        break;
+      case GTK_ICON_SIZE_SMALL_TOOLBAR:
+        sz = 18;
+        break;
+      case GTK_ICON_SIZE_LARGE_TOOLBAR:
+        sz = 24;
+        break;
+      case GTK_ICON_SIZE_BUTTON:
+        sz = 20;
+        break;
+      case GTK_ICON_SIZE_DND:
+        sz = 32;
+        break;
+      case GTK_ICON_SIZE_DIALOG:
+        sz = 48;
+        break;
+      default:
+        sz = 0;
+        break;
+    }
+
+    init_containers();
+    gtk3_widget = gtk3_get_widget((widget_type < 0) ? IMAGE : widget_type);
+    (*fp_gtk_widget_set_direction)(gtk3_widget, direction);
+    GtkIconTheme *icon_theme = fp_gtk_icon_theme_get_default();
+    GdkPixbuf *result = fp_gtk_icon_theme_load_icon(icon_theme, stock_id, sz,
+                                             GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
+    return result;
+}
+
+static jboolean gtk3_get_pixbuf_data(JNIEnv *env, GdkPixbuf* pixbuf,
+                              jmethodID icon_upcall_method, jobject this) {
+    if (!pixbuf) {
+        return JNI_FALSE;
+    }
+    guchar *pixbuf_data = (*fp_gdk_pixbuf_get_pixels)(pixbuf);
+    if (pixbuf_data) {
+        int row_stride = (*fp_gdk_pixbuf_get_rowstride)(pixbuf);
+        int width = (*fp_gdk_pixbuf_get_width)(pixbuf);
+        int height = (*fp_gdk_pixbuf_get_height)(pixbuf);
+        int bps = (*fp_gdk_pixbuf_get_bits_per_sample)(pixbuf);
+        int channels = (*fp_gdk_pixbuf_get_n_channels)(pixbuf);
+        gboolean alpha = (*fp_gdk_pixbuf_get_has_alpha)(pixbuf);
+
+        jbyteArray data = (*env)->NewByteArray(env, (row_stride * height));
+        JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
+
+        (*env)->SetByteArrayRegion(env, data, 0, (row_stride * height),
+                                   (jbyte *)pixbuf_data);
+        (*fp_g_object_unref)(pixbuf);
+
+        /* Call the callback method to create the image on the Java side. */
+        (*env)->CallVoidMethod(env, this, icon_upcall_method, data,
+                width, height, row_stride, bps, channels, alpha);
+        return JNI_TRUE;
+    }
+    return JNI_FALSE;
+}
+
+static jboolean gtk3_get_file_icon_data(JNIEnv *env, const char *filename,
+                 GError **error, jmethodID icon_upcall_method, jobject this) {
+    GdkPixbuf* pixbuf = fp_gdk_pixbuf_new_from_file(filename, error);
+    return gtk3_get_pixbuf_data(env, pixbuf, icon_upcall_method, this);
+}
+
+static jboolean gtk3_get_icon_data(JNIEnv *env, gint widget_type,
+                              const gchar *stock_id, GtkIconSize size,
+                              GtkTextDirection direction, const char *detail,
+                              jmethodID icon_upcall_method, jobject this) {
+    GdkPixbuf* pixbuf = gtk3_get_stock_icon(widget_type, stock_id, size,
+                                       direction, detail);
+    return gtk3_get_pixbuf_data(env, pixbuf, icon_upcall_method, this);
+}
+
+/*************************************************/
+static gint gtk3_get_xthickness(JNIEnv *env, WidgetType widget_type)
+{
+    init_containers();
+
+    gtk3_widget = gtk3_get_widget(widget_type);
+    GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
+    if (context) {
+        GtkBorder padding;
+        fp_gtk_style_context_get_padding(context, 0, &padding);
+        return padding.left + 1;
+    }
+    return 0;
+}
+
+static gint gtk3_get_ythickness(JNIEnv *env, WidgetType widget_type)
+{
+    init_containers();
+
+    gtk3_widget = gtk3_get_widget(widget_type);
+    GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
+    if (context) {
+        GtkBorder padding;
+        fp_gtk_style_context_get_padding(context, 0, &padding);
+        return padding.top + 1;
+    }
+    return 0;
+}
+
+/*************************************************/
+static guint8 recode_color(gdouble channel)
+{
+    guint16 result = (guint16)(channel * 65535);
+    if (result < 0) {
+        result = 0;
+    } else if (result > 65535) {
+        result = 65535;
+    }
+    return (guint8)( result >> 8);
+}
+
+static GtkStateFlags gtk3_get_state_flags(GtkStateType state_type) {
+    switch (state_type)
+    {
+        case GTK_STATE_NORMAL:
+            return GTK_STATE_FLAG_NORMAL;
+        case GTK_STATE_ACTIVE:
+            return GTK_STATE_FLAG_ACTIVE;
+        case GTK_STATE_PRELIGHT:
+            return GTK_STATE_FLAG_PRELIGHT;
+        case GTK_STATE_SELECTED:
+            return GTK_STATE_FLAG_SELECTED;
+        case GTK_STATE_INSENSITIVE:
+            return GTK_STATE_FLAG_INSENSITIVE;
+        case GTK_STATE_INCONSISTENT:
+            return GTK_STATE_FLAG_INCONSISTENT;
+        case GTK_STATE_FOCUSED:
+            return GTK_STATE_FLAG_FOCUSED;
+    }
+    return 0;
+}
+
+
+static void rgb_to_hls (gdouble *r, gdouble *g, gdouble *b) {
+  gdouble min;
+  gdouble max;
+  gdouble red;
+  gdouble green;
+  gdouble blue;
+  gdouble h, l, s;
+  gdouble delta;
+
+  red = *r;
+  green = *g;
+  blue = *b;
+
+  if (red > green)
+    {
+      if (red > blue)
+        max = red;
+      else
+        max = blue;
+
+      if (green < blue)
+        min = green;
+      else
+        min = blue;
+    }
+  else
+    {
+      if (green > blue)
+        max = green;
+      else
+        max = blue;
+
+      if (red < blue)
+        min = red;
+      else
+        min = blue;
+    }
+
+  l = (max + min) / 2;
+  s = 0;
+  h = 0;
+
+  if (max != min)
+    {
+      if (l <= 0.5)
+        s = (max - min) / (max + min);
+      else
+        s = (max - min) / (2 - max - min);
+
+      delta = max -min;
+      if (red == max)
+        h = (green - blue) / delta;
+      else if (green == max)
+        h = 2 + (blue - red) / delta;
+      else if (blue == max)
+        h = 4 + (red - green) / delta;
+
+      h *= 60;
+      if (h < 0.0)
+        h += 360;
+    }
+
+  *r = h;
+  *g = l;
+  *b = s;
+}
+
+static void hls_to_rgb (gdouble *h, gdouble *l, gdouble *s)
+{
+  gdouble hue;
+  gdouble lightness;
+  gdouble saturation;
+  gdouble m1, m2;
+  gdouble r, g, b;
+
+  lightness = *l;
+  saturation = *s;
+
+  if (lightness <= 0.5)
+    m2 = lightness * (1 + saturation);
+  else
+    m2 = lightness + saturation - lightness * saturation;
+  m1 = 2 * lightness - m2;
+
+  if (saturation == 0)
+    {
+      *h = lightness;
+      *l = lightness;
+      *s = lightness;
+    }
+  else
+    {
+      hue = *h + 120;
+      while (hue > 360)
+        hue -= 360;
+      while (hue < 0)
+        hue += 360;
+
+      if (hue < 60)
+        r = m1 + (m2 - m1) * hue / 60;
+      else if (hue < 180)
+        r = m2;
+      else if (hue < 240)
+        r = m1 + (m2 - m1) * (240 - hue) / 60;
+      else
+        r = m1;
+
+      hue = *h;
+      while (hue > 360)
+        hue -= 360;
+      while (hue < 0)
+        hue += 360;
+
+      if (hue < 60)
+        g = m1 + (m2 - m1) * hue / 60;
+      else if (hue < 180)
+        g = m2;
+      else if (hue < 240)
+        g = m1 + (m2 - m1) * (240 - hue) / 60;
+      else
+        g = m1;
+
+      hue = *h - 120;
+      while (hue > 360)
+        hue -= 360;
+      while (hue < 0)
+        hue += 360;
+
+      if (hue < 60)
+        b = m1 + (m2 - m1) * hue / 60;
+      else if (hue < 180)
+        b = m2;
+      else if (hue < 240)
+        b = m1 + (m2 - m1) * (240 - hue) / 60;
+      else
+        b = m1;
+
+      *h = r;
+      *l = g;
+      *s = b;
+    }
+}
+
+
+
+static void gtk3_style_shade (const GdkRGBA *a, GdkRGBA *b, gdouble k) {
+  gdouble red = a->red;
+  gdouble green = a->green;
+  gdouble blue = a->blue;
+
+  rgb_to_hls (&red, &green, &blue);
+
+  green *= k;
+  if (green > 1.0)
+    green = 1.0;
+  else if (green < 0.0)
+    green = 0.0;
+
+  blue *= k;
+  if (blue > 1.0)
+    blue = 1.0;
+  else if (blue < 0.0)
+    blue = 0.0;
+
+  hls_to_rgb (&red, &green, &blue);
+
+  b->red = red;
+  b->green = green;
+  b->blue = blue;
+}
+
+static GdkRGBA gtk3_get_color_for_flags(GtkStyleContext* context,
+                                  GtkStateFlags flags, ColorType color_type) {
+    GdkRGBA c, color;
+
+    switch (color_type)
+    {
+        case FOREGROUND:
+        case TEXT_FOREGROUND:
+            fp_gtk_style_context_get_color(context, flags, &color);
+            break;
+        case BACKGROUND:
+        case TEXT_BACKGROUND:
+            fp_gtk_style_context_get_background_color(context, flags, &color);
+            break;
+        case LIGHT:
+            c = gtk3_get_color_for_flags(context, flags, BACKGROUND);
+            gtk3_style_shade(&c, &color, LIGHTNESS_MULT);
+            break;
+        case DARK:
+            c = gtk3_get_color_for_flags(context, flags, BACKGROUND);
+            gtk3_style_shade (&c, &color, DARKNESS_MULT);
+            break;
+        case MID:
+            {
+                GdkRGBA c1 = gtk3_get_color_for_flags(context, flags, LIGHT);
+                GdkRGBA c2 = gtk3_get_color_for_flags(context, flags, DARK);
+                color.red = (c1.red + c2.red) / 2;
+                color.green = (c1.green + c2.green) / 2;
+                color.blue = (c1.blue + c2.blue) / 2;
+            }
+            break;
+        case FOCUS:
+        case BLACK:
+            color.red = 0;
+            color.green = 0;
+            color.blue = 0;
+            break;
+        case WHITE:
+            color.red = 1;
+            color.green = 1;
+            color.blue = 1;
+            break;
+    }
+    return color;
+}
+
+static gint gtk3_get_color_for_state(JNIEnv *env, WidgetType widget_type,
+                              GtkStateType state_type, ColorType color_type)
+{
+
+    gint result = 0;
+    GdkRGBA color;
+
+    GtkStateFlags flags = gtk3_get_state_flags(state_type);
+
+    init_containers();
+
+    gtk3_widget = gtk3_get_widget(widget_type);
+
+    GtkStyleContext* context = fp_gtk_widget_get_style_context(gtk3_widget);
+
+    if (widget_type == TOOL_TIP) {
+        fp_gtk_style_context_add_class(context, "tooltip");
+    }
+    if (widget_type == CHECK_BOX_MENU_ITEM
+     || widget_type == RADIO_BUTTON_MENU_ITEM) {
+        flags &= GTK_STATE_FLAG_NORMAL | GTK_STATE_FLAG_SELECTED
+                  | GTK_STATE_FLAG_INSENSITIVE | GTK_STATE_FLAG_FOCUSED;
+    }
+
+    color = gtk3_get_color_for_flags(context, flags, color_type);
+
+    if (recode_color(color.alpha) == 0) {
+        color = gtk3_get_color_for_flags(
+        fp_gtk_widget_get_style_context(gtk3_get_widget(INTERNAL_FRAME)),
+        0, BACKGROUND);
+    }
+
+    result = recode_color(color.alpha) << 24 | recode_color(color.red) << 16 |
+             recode_color(color.green) << 8 | recode_color(color.blue);
+
+    return result;
+}
+
+/*************************************************/
+static jobject create_Boolean(JNIEnv *env, jboolean boolean_value);
+static jobject create_Integer(JNIEnv *env, jint int_value);
+static jobject create_Long(JNIEnv *env, jlong long_value);
+static jobject create_Float(JNIEnv *env, jfloat float_value);
+static jobject create_Double(JNIEnv *env, jdouble double_value);
+static jobject create_Character(JNIEnv *env, jchar char_value);
+static jobject create_Insets(JNIEnv *env, GtkBorder *border);
+
+static jobject gtk3_get_class_value(JNIEnv *env, WidgetType widget_type,
+                                                     const char* key)
+{
+    init_containers();
+
+    gtk3_widget = gtk3_get_widget(widget_type);
+
+    GValue value = { 0, { { 0 } } };
+
+    GParamSpec* param = (*fp_gtk_widget_class_find_style_property)(
+                                    ((GTypeInstance*)gtk3_widget)->g_class, key);
+    if ( param )
+    {
+        (*fp_g_value_init)( &value, param->value_type );
+        (*fp_gtk_widget_style_get_property)(gtk3_widget, key, &value);
+
+        if ((*fp_g_type_is_a)( param->value_type, G_TYPE_BOOLEAN ))
+        {
+            gboolean val = (*fp_g_value_get_boolean)(&value);
+            return create_Boolean(env, (jboolean)val);
+        }
+        else if ((*fp_g_type_is_a)( param->value_type, G_TYPE_CHAR ))
+        {
+            gchar val = (*fp_g_value_get_char)(&value);
+            return create_Character(env, (jchar)val);
+        }
+        else if ((*fp_g_type_is_a)( param->value_type, G_TYPE_UCHAR ))
+        {
+            guchar val = (*fp_g_value_get_uchar)(&value);
+            return create_Character(env, (jchar)val);
+        }
+        else if ((*fp_g_type_is_a)( param->value_type, G_TYPE_INT ))
+        {
+            gint val = (*fp_g_value_get_int)(&value);
+            return create_Integer(env, (jint)val);
+        }
+        else if ((*fp_g_type_is_a)( param->value_type, G_TYPE_UINT ))
+        {
+            guint val = (*fp_g_value_get_uint)(&value);
+                    return create_Integer(env, (jint)val);
+        }
+        else if ((*fp_g_type_is_a)( param->value_type, G_TYPE_LONG ))
+        {
+            glong val = (*fp_g_value_get_long)(&value);
+            return create_Long(env, (jlong)val);
+        }
+        else if ((*fp_g_type_is_a)( param->value_type, G_TYPE_ULONG ))
+        {
+            gulong val = (*fp_g_value_get_ulong)(&value);
+            return create_Long(env, (jlong)val);
+        }
+        else if ((*fp_g_type_is_a)( param->value_type, G_TYPE_INT64 ))
+        {
+            gint64 val = (*fp_g_value_get_int64)(&value);
+            return create_Long(env, (jlong)val);
+        }
+        else if ((*fp_g_type_is_a)( param->value_type, G_TYPE_UINT64 ))
+        {
+            guint64 val = (*fp_g_value_get_uint64)(&value);
+            return create_Long(env, (jlong)val);
+        }
+        else if ((*fp_g_type_is_a)( param->value_type, G_TYPE_FLOAT ))
+        {
+            gfloat val = (*fp_g_value_get_float)(&value);
+            return create_Float(env, (jfloat)val);
+        }
+        else if ((*fp_g_type_is_a)( param->value_type, G_TYPE_DOUBLE ))
+        {
+            gdouble val = (*fp_g_value_get_double)(&value);
+            return create_Double(env, (jdouble)val);
+        }
+        else if ((*fp_g_type_is_a)( param->value_type, G_TYPE_ENUM ))
+        {
+            gint val = (*fp_g_value_get_enum)(&value);
+            return create_Integer(env, (jint)val);
+        }
+        else if ((*fp_g_type_is_a)( param->value_type, G_TYPE_FLAGS ))
+        {
+            guint val = (*fp_g_value_get_flags)(&value);
+            return create_Integer(env, (jint)val);
+        }
+        else if ((*fp_g_type_is_a)( param->value_type, G_TYPE_STRING ))
+        {
+            const gchar* val = (*fp_g_value_get_string)(&value);
+
+            /* We suppose that all values come in C locale and
+             * utf-8 representation of a string is the same as
+             * the string itself. If this isn't so we should
+             * use g_convert.
+             */
+            return (*env)->NewStringUTF(env, val);
+        }
+        else if ((*fp_g_type_is_a)( param->value_type, GTK_TYPE_BORDER ))
+        {
+            GtkBorder *border = (GtkBorder*)(*fp_g_value_get_boxed)(&value);
+            return border ? create_Insets(env, border) : NULL;
+        }
+
+        /*      TODO: Other types are not supported yet.*/
+/*        else if((*fp_g_type_is_a)( param->value_type, G_TYPE_PARAM ))
+        {
+            GParamSpec* val = (*fp_g_value_get_param)(&value);
+            printf( "Param: %p\n", val );
+        }
+        else if((*fp_g_type_is_a)( param->value_type, G_TYPE_BOXED ))
+        {
+            gpointer* val = (*fp_g_value_get_boxed)(&value);
+            printf( "Boxed: %p\n", val );
+        }
+        else if((*fp_g_type_is_a)( param->value_type, G_TYPE_POINTER ))
+        {
+            gpointer* val = (*fp_g_value_get_pointer)(&value);
+            printf( "Pointer: %p\n", val );
+        }
+        else if((*fp_g_type_is_a)( param->value_type, G_TYPE_OBJECT ))
+        {
+            GObject* val = (GObject*)(*fp_g_value_get_object)(&value);
+            printf( "Object: %p\n", val );
+        }*/
+    }
+
+    return NULL;
+}
+
+static void gtk3_set_range_value(WidgetType widget_type, jdouble value,
+                          jdouble min, jdouble max, jdouble visible)
+{
+    GtkAdjustment *adj;
+
+    gtk3_widget = gtk3_get_widget(widget_type);
+
+    adj = (*fp_gtk_range_get_adjustment)((GtkRange *)gtk3_widget);
+
+    fp_gtk_adjustment_set_value(adj, value);
+    fp_gtk_adjustment_set_lower(adj, min);
+    fp_gtk_adjustment_set_upper(adj, max);
+    fp_gtk_adjustment_set_page_size(adj, visible);
+}
+
+/*************************************************/
+static jobject create_Object(JNIEnv *env, jmethodID *cid,
+                             const char* class_name,
+                             const char* signature,
+                             jvalue* value)
+{
+    jclass  class;
+    jobject result;
+
+    class = (*env)->FindClass(env, class_name);
+    if (class == NULL)
+        return NULL; /* can't find/load the class, exception thrown */
+
+    if (*cid == NULL)
+    {
+        *cid = (*env)->GetMethodID(env, class, "<init>", signature);
+        if (*cid == NULL)
+        {
+            (*env)->DeleteLocalRef(env, class);
+            return NULL; /* can't find/get the method, exception thrown */
+        }
+    }
+
+    result = (*env)->NewObjectA(env, class, *cid, value);
+
+    (*env)->DeleteLocalRef(env, class);
+    return result;
+}
+
+jobject create_Boolean(JNIEnv *env, jboolean boolean_value)
+{
+    static jmethodID cid = NULL;
+    jvalue value;
+
+    value.z = boolean_value;
+
+    return create_Object(env, &cid, "java/lang/Boolean", "(Z)V", &value);
+}
+
+jobject create_Integer(JNIEnv *env, jint int_value)
+{
+    static jmethodID cid = NULL;
+    jvalue value;
+
+    value.i = int_value;
+
+    return create_Object(env, &cid, "java/lang/Integer", "(I)V", &value);
+}
+
+jobject create_Long(JNIEnv *env, jlong long_value)
+{
+    static jmethodID cid = NULL;
+    jvalue value;
+
+    value.j = long_value;
+
+    return create_Object(env, &cid, "java/lang/Long", "(J)V", &value);
+}
+
+jobject create_Float(JNIEnv *env, jfloat float_value)
+{
+    static jmethodID cid = NULL;
+    jvalue value;
+
+    value.f = float_value;
+
+    return create_Object(env, &cid, "java/lang/Float", "(F)V", &value);
+}
+
+jobject create_Double(JNIEnv *env, jdouble double_value)
+{
+    static jmethodID cid = NULL;
+    jvalue value;
+
+    value.d = double_value;
+
+    return create_Object(env, &cid, "java/lang/Double", "(D)V", &value);
+}
+
+jobject create_Character(JNIEnv *env, jchar char_value)
+{
+    static jmethodID cid = NULL;
+    jvalue value;
+
+    value.c = char_value;
+
+    return create_Object(env, &cid, "java/lang/Character", "(C)V", &value);
+}
+
+
+jobject create_Insets(JNIEnv *env, GtkBorder *border)
+{
+    static jmethodID cid = NULL;
+    jvalue values[4];
+
+    values[0].i = border->top;
+    values[1].i = border->left;
+    values[2].i = border->bottom;
+    values[3].i = border->right;
+
+    return create_Object(env, &cid, "java/awt/Insets", "(IIII)V", values);
+}
+
+/*********************************************/
+static jstring gtk3_get_pango_font_name(JNIEnv *env, WidgetType widget_type)
+{
+    init_containers();
+
+    gtk3_widget = gtk3_get_widget(widget_type);
+    jstring  result = NULL;
+    GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
+    if (context)
+    {
+        PangoFontDescription* fd = fp_gtk_style_context_get_font(context, 0);
+        gchar* val = (*fp_pango_font_description_to_string)(fd);
+        result = (*env)->NewStringUTF(env, val);
+        (*fp_g_free)( val );
+    }
+
+    return result;
+}
+
+/***********************************************/
+static jobject get_string_property(JNIEnv *env, GtkSettings* settings,
+                                                             const gchar* key) {
+    jobject result = NULL;
+    gchar*  strval = NULL;
+
+    (*fp_g_object_get)(settings, key, &strval, NULL);
+    result = (*env)->NewStringUTF(env, strval);
+    (*fp_g_free)(strval);
+
+    return result;
+}
+
+static jobject get_integer_property(JNIEnv *env, GtkSettings* settings,
+                                                             const gchar* key) {
+    gint intval = 0;
+    (*fp_g_object_get)(settings, key, &intval, NULL);
+    return create_Integer(env, intval);
+}
+
+static jobject get_boolean_property(JNIEnv *env, GtkSettings* settings,
+                                                             const gchar* key) {
+    gint intval = 0;
+    (*fp_g_object_get)(settings, key, &intval, NULL);
+    return create_Boolean(env, intval);
+}
+
+static jobject gtk3_get_setting(JNIEnv *env, Setting property)
+{
+    GtkSettings* settings = (*fp_gtk_settings_get_default)();
+
+    switch (property)
+    {
+        case GTK_FONT_NAME:
+            return get_string_property(env, settings, "gtk-font-name");
+        case GTK_ICON_SIZES:
+            return get_string_property(env, settings, "gtk-icon-sizes");
+        case GTK_CURSOR_BLINK:
+            return get_boolean_property(env, settings, "gtk-cursor-blink");
+        case GTK_CURSOR_BLINK_TIME:
+            return get_integer_property(env, settings, "gtk-cursor-blink-time");
+    }
+
+    return NULL;
+}
+
+static void transform_detail_string (const gchar *detail,
+                                                     GtkStyleContext *context) {
+  if (!detail)
+    return;
+
+  if (strcmp (detail, "arrow") == 0)
+    fp_gtk_style_context_add_class (context, "arrow");
+  else if (strcmp (detail, "button") == 0)
+    fp_gtk_style_context_add_class (context, "button");
+  else if (strcmp (detail, "buttondefault") == 0)
+    {
+      fp_gtk_style_context_add_class (context, "button");
+      fp_gtk_style_context_add_class (context, "default");
+    }
+  else if (strcmp (detail, "calendar") == 0)
+    fp_gtk_style_context_add_class (context, "calendar");
+  else if (strcmp (detail, "cellcheck") == 0)
+    {
+      fp_gtk_style_context_add_class (context, "cell");
+      fp_gtk_style_context_add_class (context, "check");
+    }
+  else if (strcmp (detail, "cellradio") == 0)
+    {
+      fp_gtk_style_context_add_class (context, "cell");
+      fp_gtk_style_context_add_class (context, "radio");
+    }
+  else if (strcmp (detail, "checkbutton") == 0)
+    fp_gtk_style_context_add_class (context, "check");
+  else if (strcmp (detail, "check") == 0)
+    {
+      fp_gtk_style_context_add_class (context, "check");
+      fp_gtk_style_context_add_class (context, "menu");
+    }
+  else if (strcmp (detail, "radiobutton") == 0)
+    {
+      fp_gtk_style_context_add_class (context, "radio");
+    }
+  else if (strcmp (detail, "option") == 0)
+    {
+      fp_gtk_style_context_add_class (context, "radio");
+      fp_gtk_style_context_add_class (context, "menu");
+    }
+  else if (strcmp (detail, "entry") == 0 ||
+           strcmp (detail, "entry_bg") == 0)
+    fp_gtk_style_context_add_class (context, "entry");
+  else if (strcmp (detail, "expander") == 0)
+    fp_gtk_style_context_add_class (context, "expander");
+  else if (strcmp (detail, "tooltip") == 0)
+    fp_gtk_style_context_add_class (context, "tooltip");
+  else if (strcmp (detail, "frame") == 0)
+    fp_gtk_style_context_add_class (context, "frame");
+  else if (strcmp (detail, "scrolled_window") == 0)
+    fp_gtk_style_context_add_class (context, "scrolled-window");
+  else if (strcmp (detail, "viewport") == 0 ||
+           strcmp (detail, "viewportbin") == 0)
+    fp_gtk_style_context_add_class (context, "viewport");
+  else if (strncmp (detail, "trough", 6) == 0)
+    fp_gtk_style_context_add_class (context, "trough");
+  else if (strcmp (detail, "spinbutton") == 0)
+    fp_gtk_style_context_add_class (context, "spinbutton");
+  else if (strcmp (detail, "spinbutton_up") == 0)
+    {
+      fp_gtk_style_context_add_class (context, "spinbutton");
+      fp_gtk_style_context_add_class (context, "button");
+      fp_gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
+    }
+  else if (strcmp (detail, "spinbutton_down") == 0)
+    {
+      fp_gtk_style_context_add_class (context, "spinbutton");
+      fp_gtk_style_context_add_class (context, "button");
+      fp_gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
+    }
+  else if ((detail[0] == 'h' || detail[0] == 'v') &&
+           strncmp (&detail[1], "scrollbar_", 9) == 0)
+    {
+      fp_gtk_style_context_add_class (context, "button");
+      fp_gtk_style_context_add_class (context, "scrollbar");
+    }
+  else if (strcmp (detail, "slider") == 0)
+    {
+      fp_gtk_style_context_add_class (context, "slider");
+      fp_gtk_style_context_add_class (context, "scrollbar");
+    }
+  else if (strcmp (detail, "vscale") == 0 ||
+           strcmp (detail, "hscale") == 0)
+    {
+      fp_gtk_style_context_add_class (context, "slider");
+      fp_gtk_style_context_add_class (context, "scale");
+    }
+  else if (strcmp (detail, "menuitem") == 0)
+    {
+      fp_gtk_style_context_add_class (context, "menuitem");
+      fp_gtk_style_context_add_class (context, "menu");
+    }
+  else if (strcmp (detail, "menu") == 0)
+    {
+      fp_gtk_style_context_add_class (context, "popup");
+      fp_gtk_style_context_add_class (context, "menu");
+    }
+  else if (strcmp (detail, "accellabel") == 0)
+    fp_gtk_style_context_add_class (context, "accelerator");
+  else if (strcmp (detail, "menubar") == 0)
+    fp_gtk_style_context_add_class (context, "menubar");
+  else if (strcmp (detail, "base") == 0)
+    fp_gtk_style_context_add_class (context, "background");
+  else if (strcmp (detail, "bar") == 0 ||
+           strcmp (detail, "progressbar") == 0)
+    fp_gtk_style_context_add_class (context, "progressbar");
+  else if (strcmp (detail, "toolbar") == 0)
+    fp_gtk_style_context_add_class (context, "toolbar");
+  else if (strcmp (detail, "handlebox_bin") == 0)
+    fp_gtk_style_context_add_class (context, "dock");
+  else if (strcmp (detail, "notebook") == 0)
+    fp_gtk_style_context_add_class (context, "notebook");
+  else if (strcmp (detail, "tab") == 0)
+  {
+      fp_gtk_style_context_add_class (context, "notebook");
+      fp_gtk_style_context_add_region (context, "tab", 0);
+  } else if (strcmp (detail, "paned") == 0) {
+      fp_gtk_style_context_add_class (context, "pane-separator");
+  }
+  else if (fp_g_str_has_prefix (detail, "cell"))
+    {
+      GtkRegionFlags row, col;
+      gboolean ruled = FALSE;
+      gchar** tokens;
+      guint i;
+
+      tokens = fp_g_strsplit (detail, "_", -1);
+      row = col = 0;
+      i = 0;
+
+      while (tokens[i])
+        {
+          if (strcmp (tokens[i], "even") == 0)
+            row |= GTK_REGION_EVEN;
+          else if (strcmp (tokens[i], "odd") == 0)
+            row |= GTK_REGION_ODD;
+          else if (strcmp (tokens[i], "start") == 0)
+            col |= GTK_REGION_FIRST;
+          else if (strcmp (tokens[i], "end") == 0)
+            col |= GTK_REGION_LAST;
+          else if (strcmp (tokens[i], "ruled") == 0)
+            ruled = TRUE;
+          else if (strcmp (tokens[i], "sorted") == 0)
+            col |= GTK_REGION_SORTED;
+
+          i++;
+        }
+
+      if (!ruled)
+        row &= ~(GTK_REGION_EVEN | GTK_REGION_ODD);
+
+      fp_gtk_style_context_add_class (context, "cell");
+      fp_gtk_style_context_add_region (context, "row", row);
+      fp_gtk_style_context_add_region (context, "column", col);
+
+      fp_g_strfreev (tokens);
+    }
+}
+
+static gboolean gtk3_get_drawable_data(JNIEnv *env, jintArray pixelArray,
+     int x, jint y, jint width, jint height, jint jwidth, int dx, int dy,
+                                                                   jint scale) {
+    GdkPixbuf *pixbuf;
+    jint *ary;
+
+    GdkWindow *root = (*fp_gdk_get_default_root_window)();
+    pixbuf = (*fp_gdk_pixbuf_get_from_drawable)(root, x, y, width, height);
+    if (pixbuf && scale != 1) {
+        GdkPixbuf *scaledPixbuf;
+        x /= scale;
+        y /= scale;
+        width /= scale;
+        height /= scale;
+        dx /= scale;
+        dy /= scale;
+        scaledPixbuf = (*fp_gdk_pixbuf_scale_simple)(pixbuf, width, height,
+                                                     GDK_INTERP_BILINEAR);
+        (*fp_g_object_unref)(pixbuf);
+        pixbuf = scaledPixbuf;
+    }
+
+    if (pixbuf) {
+        int nchan = (*fp_gdk_pixbuf_get_n_channels)(pixbuf);
+        int stride = (*fp_gdk_pixbuf_get_rowstride)(pixbuf);
+        if ((*fp_gdk_pixbuf_get_width)(pixbuf) == width
+                && (*fp_gdk_pixbuf_get_height)(pixbuf) == height
+                && (*fp_gdk_pixbuf_get_bits_per_sample)(pixbuf) == 8
+                && (*fp_gdk_pixbuf_get_colorspace)(pixbuf) == GDK_COLORSPACE_RGB
+                && nchan >= 3
+                ) {
+            guchar *p, *pix = (*fp_gdk_pixbuf_get_pixels)(pixbuf);
+            ary = (*env)->GetPrimitiveArrayCritical(env, pixelArray, NULL);
+            if (ary) {
+                jint _x, _y;
+                int index;
+                for (_y = 0; _y < height; _y++) {
+                    for (_x = 0; _x < width; _x++) {
+                        p = pix + _y * stride + _x * nchan;
+
+                        index = (_y + dy) * jwidth + (_x + dx);
+                        ary[index] = 0xff000000
+                                        | (p[0] << 16)
+                                        | (p[1] << 8)
+                                        | (p[2]);
+
+                    }
+                }
+                (*env)->ReleasePrimitiveArrayCritical(env, pixelArray, ary, 0);
+            }
+        }
+        (*fp_g_object_unref)(pixbuf);
+    }
+    return JNI_FALSE;
+}
+
+static GdkWindow* gtk3_get_window(void *widget) {
+    return fp_gtk_widget_get_window((GtkWidget*)widget);
+}
+
+static void gtk3_init(GtkApi* gtk) {
+    gtk->version = GTK_3;
+
+    gtk->show_uri_load = &gtk3_show_uri_load;
+    gtk->unload = &gtk3_unload;
+    gtk->flush_event_loop = &flush_gtk_event_loop;
+    gtk->gtk_check_version = fp_gtk_check_version;
+    gtk->get_setting = &gtk3_get_setting;
+
+    gtk->paint_arrow = &gtk3_paint_arrow;
+    gtk->paint_box = &gtk3_paint_box;
+    gtk->paint_box_gap = &gtk3_paint_box_gap;
+    gtk->paint_expander = &gtk3_paint_expander;
+    gtk->paint_extension = &gtk3_paint_extension;
+    gtk->paint_flat_box = &gtk3_paint_flat_box;
+    gtk->paint_focus = &gtk3_paint_focus;
+    gtk->paint_handle = &gtk3_paint_handle;
+    gtk->paint_hline = &gtk3_paint_hline;
+    gtk->paint_vline = &gtk3_paint_vline;
+    gtk->paint_option = &gtk3_paint_option;
+    gtk->paint_shadow = &gtk3_paint_shadow;
+    gtk->paint_slider = &gtk3_paint_slider;
+    gtk->paint_background = &gtk3_paint_background;
+    gtk->paint_check = &gtk3_paint_check;
+    gtk->set_range_value = &gtk3_set_range_value;
+
+    gtk->init_painting = &gtk3_init_painting;
+    gtk->copy_image = &gtk3_copy_image;
+
+    gtk->get_xthickness = &gtk3_get_xthickness;
+    gtk->get_ythickness = &gtk3_get_ythickness;
+    gtk->get_color_for_state = &gtk3_get_color_for_state;
+    gtk->get_class_value = &gtk3_get_class_value;
+
+    gtk->get_pango_font_name = &gtk3_get_pango_font_name;
+    gtk->get_icon_data = &gtk3_get_icon_data;
+    gtk->get_file_icon_data = &gtk3_get_file_icon_data;
+    gtk->gdk_threads_enter = fp_gdk_threads_enter;
+    gtk->gdk_threads_leave = fp_gdk_threads_leave;
+    gtk->gtk_show_uri = fp_gtk_show_uri;
+    gtk->get_drawable_data = &gtk3_get_drawable_data;
+    gtk->g_free = fp_g_free;
+
+    gtk->gtk_file_chooser_get_filename = fp_gtk_file_chooser_get_filename;
+    gtk->gtk_widget_hide = fp_gtk_widget_hide;
+    gtk->gtk_main_quit = fp_gtk_main_quit;
+    gtk->gtk_file_chooser_dialog_new = fp_gtk_file_chooser_dialog_new;
+    gtk->gtk_file_chooser_set_current_folder =
+                          fp_gtk_file_chooser_set_current_folder;
+    gtk->gtk_file_chooser_set_filename = fp_gtk_file_chooser_set_filename;
+    gtk->gtk_file_chooser_set_current_name =
+                          fp_gtk_file_chooser_set_current_name;
+    gtk->gtk_file_filter_add_custom = fp_gtk_file_filter_add_custom;
+    gtk->gtk_file_chooser_set_filter = fp_gtk_file_chooser_set_filter;
+    gtk->gtk_file_chooser_get_type = fp_gtk_file_chooser_get_type;
+    gtk->gtk_file_filter_new = fp_gtk_file_filter_new;
+    gtk->gtk_file_chooser_set_do_overwrite_confirmation =
+                          fp_gtk_file_chooser_set_do_overwrite_confirmation;
+    gtk->gtk_file_chooser_set_select_multiple =
+                          fp_gtk_file_chooser_set_select_multiple;
+    gtk->gtk_file_chooser_get_current_folder =
+                          fp_gtk_file_chooser_get_current_folder;
+    gtk->gtk_file_chooser_get_filenames = fp_gtk_file_chooser_get_filenames;
+    gtk->gtk_g_slist_length = fp_gtk_g_slist_length;
+    gtk->g_signal_connect_data = fp_g_signal_connect_data;
+    gtk->gtk_widget_show = fp_gtk_widget_show;
+    gtk->gtk_main = fp_gtk_main;
+    gtk->gtk_main_level = fp_gtk_main_level;
+    gtk->g_path_get_dirname = fp_g_path_get_dirname;
+    gtk->gdk_x11_drawable_get_xid = fp_gdk_x11_drawable_get_xid;
+    gtk->gtk_widget_destroy = fp_gtk_widget_destroy;
+    gtk->gtk_window_present = fp_gtk_window_present;
+    gtk->gtk_window_move = fp_gtk_window_move;
+    gtk->gtk_window_resize = fp_gtk_window_resize;
+    gtk->get_window = &gtk3_get_window;
+
+    gtk->g_object_unref = fp_g_object_unref;
+    gtk->g_list_append = fp_g_list_append;
+    gtk->g_list_free = fp_g_list_free;
+    gtk->g_list_free_full = fp_g_list_free_full;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.h	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,577 @@
+/*
+ * Copyright (c) 2005, 2016, 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.
+ */
+#ifndef _GTK3_INTERFACE_H
+#define _GTK3_INTERFACE_H
+
+#include <stdlib.h>
+#include <jni.h>
+#include <X11/X.h>
+#include "gtk_interface.h"
+
+#define LIGHTNESS_MULT  1.3
+#define DARKNESS_MULT   0.7
+
+#define G_PI    3.1415926535897932384626433832795028841971693993751
+
+typedef enum
+{
+  GTK_STATE_FLAG_NORMAL       = 0,
+  GTK_STATE_FLAG_ACTIVE       = 1 << 0,
+  GTK_STATE_FLAG_PRELIGHT     = 1 << 1,
+  GTK_STATE_FLAG_SELECTED     = 1 << 2,
+  GTK_STATE_FLAG_INSENSITIVE  = 1 << 3,
+  GTK_STATE_FLAG_INCONSISTENT = 1 << 4,
+  GTK_STATE_FLAG_FOCUSED      = 1 << 5,
+  GTK_STATE_FLAG_BACKDROP     = 1 << 6,
+  GTK_STATE_FLAG_DIR_LTR      = 1 << 7,
+  GTK_STATE_FLAG_DIR_RTL      = 1 << 8,
+  GTK_STATE_FLAG_LINK         = 1 << 9,
+  GTK_STATE_FLAG_VISITED      = 1 << 10,
+  GTK_STATE_FLAG_CHECKED      = 1 << 11
+} GtkStateFlags;
+
+typedef enum {
+  GTK_JUNCTION_NONE = 0,
+  GTK_JUNCTION_CORNER_TOPLEFT = 1 << 0,
+  GTK_JUNCTION_CORNER_TOPRIGHT = 1 << 1,
+  GTK_JUNCTION_CORNER_BOTTOMLEFT = 1 << 2,
+  GTK_JUNCTION_CORNER_BOTTOMRIGHT = 1 << 3,
+  GTK_JUNCTION_TOP =
+                   (GTK_JUNCTION_CORNER_TOPLEFT | GTK_JUNCTION_CORNER_TOPRIGHT),
+  GTK_JUNCTION_BOTTOM =
+             (GTK_JUNCTION_CORNER_BOTTOMLEFT | GTK_JUNCTION_CORNER_BOTTOMRIGHT),
+  GTK_JUNCTION_LEFT =
+                 (GTK_JUNCTION_CORNER_TOPLEFT | GTK_JUNCTION_CORNER_BOTTOMLEFT),
+  GTK_JUNCTION_RIGHT =
+               (GTK_JUNCTION_CORNER_TOPRIGHT | GTK_JUNCTION_CORNER_BOTTOMRIGHT)
+} GtkJunctionSides;
+
+typedef enum {
+  GTK_REGION_EVEN    = 1 << 0,
+  GTK_REGION_ODD     = 1 << 1,
+  GTK_REGION_FIRST   = 1 << 2,
+  GTK_REGION_LAST    = 1 << 3,
+  GTK_REGION_ONLY    = 1 << 4,
+  GTK_REGION_SORTED  = 1 << 5
+} GtkRegionFlags;
+
+typedef enum
+{
+  GTK_WINDOW_TOPLEVEL,
+  GTK_WINDOW_POPUP
+} GtkWindowType;
+
+typedef enum
+{
+  G_PARAM_READABLE            = 1 << 0,
+  G_PARAM_WRITABLE            = 1 << 1,
+  G_PARAM_CONSTRUCT           = 1 << 2,
+  G_PARAM_CONSTRUCT_ONLY      = 1 << 3,
+  G_PARAM_LAX_VALIDATION      = 1 << 4,
+  G_PARAM_STATIC_NAME         = 1 << 5
+} GParamFlags;
+
+typedef enum
+{
+  GTK_ICON_LOOKUP_NO_SVG           = 1 << 0,
+  GTK_ICON_LOOKUP_FORCE_SVG        = 1 << 1,
+  GTK_ICON_LOOKUP_USE_BUILTIN      = 1 << 2,
+  GTK_ICON_LOOKUP_GENERIC_FALLBACK = 1 << 3,
+  GTK_ICON_LOOKUP_FORCE_SIZE       = 1 << 4
+} GtkIconLookupFlags;
+
+typedef enum
+{
+  GTK_UPDATE_CONTINUOUS,
+  GTK_UPDATE_DISCONTINUOUS,
+  GTK_UPDATE_DELAYED
+} GtkUpdateType;
+
+typedef enum
+{
+  GTK_PROGRESS_CONTINUOUS,
+  GTK_PROGRESS_DISCRETE
+} GtkProgressBarStyle;
+
+typedef enum
+{
+  GTK_PROGRESS_LEFT_TO_RIGHT,
+  GTK_PROGRESS_RIGHT_TO_LEFT,
+  GTK_PROGRESS_BOTTOM_TO_TOP,
+  GTK_PROGRESS_TOP_TO_BOTTOM
+} GtkProgressBarOrientation;
+
+typedef enum {
+    CAIRO_FORMAT_INVALID   = -1,
+    CAIRO_FORMAT_ARGB32    = 0,
+    CAIRO_FORMAT_RGB24     = 1,
+    CAIRO_FORMAT_A8        = 2,
+    CAIRO_FORMAT_A1        = 3,
+    CAIRO_FORMAT_RGB16_565 = 4
+} cairo_format_t;
+
+/* We define all structure pointers to be void* */
+typedef void GdkPixbuf;
+typedef void GMainContext;
+typedef void GVfs;
+
+typedef void GdkColormap;
+typedef void GdkDrawable;
+typedef void GdkGC;
+typedef void GdkPixmap;
+typedef void GtkStyleContext;
+typedef void GtkFixed;
+typedef void GtkMenuItem;
+typedef void GtkMenuShell;
+typedef void GtkWidgetClass;
+typedef void PangoFontDescription;
+typedef void GtkSettings;
+typedef void GtkStyleProvider;
+typedef void cairo_pattern_t;
+typedef void cairo_t;
+typedef void cairo_surface_t;
+typedef void GtkScrolledWindow;
+typedef void GtkIconTheme;
+typedef void GtkWidget;
+typedef void GtkMisc;
+typedef void GtkContainer;
+typedef void GtkBin;
+typedef void GtkAdjustment;
+typedef void GtkRange;
+typedef void GtkProgressBar;
+typedef void GtkProgress;
+
+/* Some real structures */
+typedef struct
+{
+  guint32 pixel;
+  guint16 red;
+  guint16 green;
+  guint16 blue;
+} GdkColor;
+
+typedef struct
+{
+  gdouble red;
+  gdouble green;
+  gdouble blue;
+  gdouble alpha;
+} GdkRGBA;
+
+typedef struct {
+  gint      fd;
+  gushort   events;
+  gushort   revents;
+} GPollFD;
+
+typedef struct {
+  gint x;
+  gint y;
+  gint width;
+  gint height;
+} GdkRectangle;
+
+typedef struct {
+    int x, y;
+    int width, height;
+} GtkAllocation;
+
+typedef struct {
+  gint width;
+  gint height;
+} GtkRequisition;
+
+typedef struct {
+  GtkWidgetClass *g_class;
+} GTypeInstance;
+
+typedef struct {
+  gint16 left;
+  gint16 right;
+  gint16 top;
+  gint16 bottom;
+} GtkBorder;
+
+typedef struct
+{
+  GType         g_type;
+  union {
+    gint        v_int;
+    guint       v_uint;
+    glong       v_long;
+    gulong      v_ulong;
+    gint64      v_int64;
+    guint64     v_uint64;
+    gfloat      v_float;
+    gdouble     v_double;
+    gpointer    v_pointer;
+  } data[2];
+} GValue;
+
+typedef struct {
+  GTypeInstance  g_type_instance;
+  const gchar   *name;
+  GParamFlags    flags;
+  GType    value_type;
+  GType    owner_type;
+} GParamSpec;
+
+
+static gchar* (*fp_glib_check_version)(guint required_major,
+                           guint required_minor, guint required_micro);
+
+/**
+ * Returns :
+ * NULL if the GTK+ library is compatible with the given version, or a string
+ * describing the version mismatch.
+ */
+static gchar* (*fp_gtk_check_version)(guint required_major, guint
+                           required_minor, guint required_micro);
+
+static void (*fp_g_free)(gpointer mem);
+static void (*fp_g_object_unref)(gpointer object);
+static GdkWindow *(*fp_gdk_get_default_root_window) (void);
+
+static int (*fp_gdk_pixbuf_get_bits_per_sample)(const GdkPixbuf *pixbuf);
+static guchar *(*fp_gdk_pixbuf_get_pixels)(const GdkPixbuf *pixbuf);
+static gboolean (*fp_gdk_pixbuf_get_has_alpha)(const GdkPixbuf *pixbuf);
+static int (*fp_gdk_pixbuf_get_height)(const GdkPixbuf *pixbuf);
+static int (*fp_gdk_pixbuf_get_n_channels)(const GdkPixbuf *pixbuf);
+static int (*fp_gdk_pixbuf_get_rowstride)(const GdkPixbuf *pixbuf);
+static int (*fp_gdk_pixbuf_get_width)(const GdkPixbuf *pixbuf);
+static GdkPixbuf *(*fp_gdk_pixbuf_new_from_file)(const char *filename,
+                                                              GError **error);
+static GdkColorspace (*fp_gdk_pixbuf_get_colorspace)(const GdkPixbuf *pixbuf);
+
+static GdkPixbuf *(*fp_gdk_pixbuf_get_from_drawable)(GdkWindow *window,
+        int src_x, int src_y, int width, int height);
+static GdkPixbuf *(*fp_gdk_pixbuf_scale_simple)(GdkPixbuf *src,
+        int dest_width, int dest_heigh, GdkInterpType interp_type);
+
+
+static void (*fp_gtk_widget_destroy)(void *widget);
+static void (*fp_gtk_window_present)(GtkWindow *window);
+static void (*fp_gtk_window_move)(GtkWindow *window, gint x, gint y);
+static void (*fp_gtk_window_resize)(GtkWindow *window, gint width, gint height);
+
+/**
+ * Function Pointers for GtkFileChooser
+ */
+static gchar* (*fp_gtk_file_chooser_get_filename)(GtkFileChooser *chooser);
+static void (*fp_gtk_widget_hide)(void *widget);
+static void (*fp_gtk_main_quit)(void);
+static void* (*fp_gtk_file_chooser_dialog_new)(const gchar *title,
+    GtkWindow *parent, GtkFileChooserAction action,
+    const gchar *first_button_text, ...);
+static gboolean (*fp_gtk_file_chooser_set_current_folder)
+                              (GtkFileChooser *chooser, const gchar *filename);
+static gboolean (*fp_gtk_file_chooser_set_filename)(GtkFileChooser *chooser,
+    const char *filename);
+static void (*fp_gtk_file_chooser_set_current_name)(GtkFileChooser *chooser,
+    const gchar *name);
+static void (*fp_gtk_file_filter_add_custom)(GtkFileFilter *filter,
+    GtkFileFilterFlags needed, GtkFileFilterFunc func, gpointer data,
+    GDestroyNotify notify);
+static void (*fp_gtk_file_chooser_set_filter)(GtkFileChooser *chooser,
+    GtkFileFilter *filter);
+static GType (*fp_gtk_file_chooser_get_type)(void);
+static GtkFileFilter* (*fp_gtk_file_filter_new)(void);
+static void (*fp_gtk_file_chooser_set_do_overwrite_confirmation)(
+    GtkFileChooser *chooser, gboolean do_overwrite_confirmation);
+static void (*fp_gtk_file_chooser_set_select_multiple)(
+    GtkFileChooser *chooser, gboolean select_multiple);
+static gchar* (*fp_gtk_file_chooser_get_current_folder)
+                                                      (GtkFileChooser *chooser);
+static GSList* (*fp_gtk_file_chooser_get_filenames)(GtkFileChooser *chooser);
+static guint (*fp_gtk_g_slist_length)(GSList *list);
+static gulong (*fp_g_signal_connect_data)(gpointer instance,
+    const gchar *detailed_signal, GCallback c_handler, gpointer data,
+    GClosureNotify destroy_data, GConnectFlags connect_flags);
+static void (*fp_gtk_widget_show)(void *widget);
+static void (*fp_gtk_main)(void);
+static guint (*fp_gtk_main_level)(void);
+static gchar* (*fp_g_path_get_dirname) (const gchar *file_name);
+static XID (*fp_gdk_x11_drawable_get_xid) (GdkWindow *drawable);
+
+static GList* (*fp_g_list_append) (GList *list, gpointer data);
+static void (*fp_g_list_free) (GList *list);
+static void (*fp_g_list_free_full) (GList *list, GDestroyNotify free_func);
+
+static void (*fp_gdk_threads_enter)(void);
+static void (*fp_gdk_threads_leave)(void);
+
+static gboolean (*fp_gtk_show_uri)(GdkScreen *screen, const gchar *uri,
+    guint32 timestamp, GError **error);
+
+// Implementation functions prototypes
+static void gtk3_init(GtkApi* gtk);
+static GValue*      (*fp_g_value_init)(GValue *value, GType g_type);
+static gboolean     (*fp_g_type_is_a)(GType type, GType is_a_type);
+static gboolean     (*fp_g_value_get_boolean)(const GValue *value);
+static gchar        (*fp_g_value_get_char)(const GValue *value);
+static guchar       (*fp_g_value_get_uchar)(const GValue *value);
+static gint         (*fp_g_value_get_int)(const GValue *value);
+static guint        (*fp_g_value_get_uint)(const GValue *value);
+static glong        (*fp_g_value_get_long)(const GValue *value);
+static gulong       (*fp_g_value_get_ulong)(const GValue *value);
+static gint64       (*fp_g_value_get_int64)(const GValue *value);
+static guint64      (*fp_g_value_get_uint64)(const GValue *value);
+static gfloat       (*fp_g_value_get_float)(const GValue *value);
+static gdouble      (*fp_g_value_get_double)(const GValue *value);
+static const gchar* (*fp_g_value_get_string)(const GValue *value);
+static gint         (*fp_g_value_get_enum)(const GValue *value);
+static guint        (*fp_g_value_get_flags)(const GValue *value);
+static GParamSpec*  (*fp_g_value_get_param)(const GValue *value);
+static gpointer*    (*fp_g_value_get_boxed)(const GValue *value);
+static gpointer*    (*fp_g_value_get_pointer)(const GValue *value);
+static void         (*fp_g_object_get)(gpointer object,
+                                       const gchar* fpn, ...);
+static void         (*fp_g_object_set)(gpointer object,
+                                       const gchar *first_property_name,
+                                       ...);
+
+static gboolean (*fp_g_main_context_iteration)(GMainContext *context);
+static gboolean (*fp_g_str_has_prefix)(const gchar *str, const gchar *prefix);
+static gchar** (*fp_g_strsplit)(const gchar *string, const gchar *delimiter,
+           gint max_tokens);
+static void (*fp_g_strfreev)(gchar **str_array);
+
+
+static cairo_surface_t* (*fp_cairo_image_surface_create)(cairo_format_t format,
+                               int width, int height);
+static void (*fp_cairo_surface_destroy)(cairo_surface_t *surface);
+static cairo_t* (*fp_cairo_create)(cairo_surface_t *target);
+static void (*fp_cairo_destroy)(cairo_t *cr);
+static void (*fp_cairo_fill)(cairo_t *cr);
+static void (*fp_cairo_surface_flush)(cairo_surface_t *surface);
+static void (*fp_cairo_rectangle)(cairo_t *cr, double x, double y, double width,
+                double height);
+static void (*fp_cairo_set_source_rgb)(cairo_t *cr, double red, double green,
+                double blue);
+static void (*fp_cairo_set_source_rgba)(cairo_t *cr, double red, double green,
+                double blue, double alpha);
+static void (*fp_cairo_paint)(cairo_t *cr);
+static void (*fp_cairo_clip)(cairo_t *cr);
+static unsigned char* (*fp_cairo_image_surface_get_data)(
+                                                 cairo_surface_t *surface);
+static int (*fp_cairo_image_surface_get_stride) (cairo_surface_t *surface);
+static GdkPixbuf* (*fp_gdk_pixbuf_get_from_surface)(cairo_surface_t *surface,
+                            gint src_x, gint src_y, gint width, gint height);
+static GtkStateType (*fp_gtk_widget_get_state)(GtkWidget *widget);
+static void (*fp_gtk_widget_set_state)(GtkWidget *widget, GtkStateType state);
+static gboolean (*fp_gtk_widget_is_focus)(GtkWidget *widget);
+static void (*fp_gtk_widget_set_allocation)(GtkWidget *widget,
+                                            const GtkAllocation *allocation);
+static GtkWidget* (*fp_gtk_widget_get_parent)(GtkWidget *widget);
+static GtkStyleContext* (*fp_gtk_widget_get_style_context)(GtkWidget *widget);
+static void (*fp_gtk_style_context_get_color)(GtkStyleContext *context,
+                                           GtkStateFlags state, GdkRGBA *color);
+static void (*fp_gtk_style_context_get_background_color)
+                (GtkStyleContext *context, GtkStateFlags state, GdkRGBA *color);
+static void (*fp_gtk_style_context_get)(GtkStyleContext *context,
+                                                      GtkStateFlags state, ...);
+static GtkStateFlags (*fp_gtk_widget_get_state_flags)(GtkWidget* widget);
+static void (*fp_gtk_style_context_set_state)(GtkStyleContext* style,
+                                              GtkStateFlags flags);
+static void (*fp_gtk_style_context_add_class)(GtkStyleContext *context,
+                                                 const gchar *class_name);
+static void (*fp_gtk_style_context_save)(GtkStyleContext *context);
+static void (*fp_gtk_style_context_restore)(GtkStyleContext *context);
+static void (*fp_gtk_render_check)(GtkStyleContext *context, cairo_t *cr,
+                     gdouble x, gdouble y, gdouble width, gdouble height);
+static void (*fp_gtk_render_option)(GtkStyleContext *context, cairo_t *cr,
+                     gdouble x, gdouble y, gdouble width, gdouble height);
+static void (*fp_gtk_render_extension)(GtkStyleContext *context, cairo_t *cr,
+                     gdouble x, gdouble y, gdouble width, gdouble height,
+                     GtkPositionType gap_side);
+static void (*fp_gtk_render_expander)(GtkStyleContext *context, cairo_t *cr,
+                     gdouble x, gdouble y, gdouble width, gdouble height);
+static void (*fp_gtk_render_frame_gap)(GtkStyleContext *context, cairo_t *cr,
+                     gdouble x, gdouble y, gdouble width, gdouble height,
+                     GtkPositionType gap_side, gdouble xy0_gap,
+                     gdouble xy1_gap);
+static void (*fp_gtk_render_line)(GtkStyleContext *context, cairo_t *cr,
+                     gdouble x0, gdouble y0, gdouble x1, gdouble y1);
+static GdkPixbuf* (*fp_gtk_widget_render_icon_pixbuf)(GtkWidget *widget,
+                     const gchar *stock_id, GtkIconSize size);
+static cairo_surface_t* (*fp_gdk_window_create_similar_image_surface)(
+                     GdkWindow *window, cairo_format_t format, int width,
+                     int height, int scale);
+static cairo_surface_t* (*fp_gdk_window_create_similar_surface)(
+                     GdkWindow *window, cairo_format_t format,
+                     int width, int height);
+static GdkWindow* (*fp_gtk_widget_get_window)(GtkWidget *widget);
+static GtkSettings *(*fp_gtk_settings_get_for_screen)(GdkScreen *screen);
+static GdkScreen *(*fp_gtk_widget_get_screen)(GtkWidget *widget);
+static GtkStyleProvider* (*fp_gtk_css_provider_get_named)(const gchar *name,
+                     const gchar *variant);
+static void (*fp_gtk_style_context_add_provider)(GtkStyleContext *context,
+                     GtkStyleProvider *provider, guint priority);
+static void (*fp_gtk_render_frame)(GtkStyleContext *context,cairo_t *cr,
+                     gdouble x, gdouble y, gdouble width, gdouble height);
+static void (*fp_gtk_render_focus)(GtkStyleContext *context,cairo_t *cr,
+                     gdouble x, gdouble y, gdouble width, gdouble height);
+static void (*fp_gtk_render_handle)(GtkStyleContext *context,cairo_t *cr,
+                     gdouble x, gdouble y, gdouble width, gdouble height);
+static void (*fp_gtk_style_context_get_property)(GtkStyleContext *context,
+                     const gchar *property, GtkStateFlags state, GValue *value);
+static void (*fp_gtk_render_activity)(GtkStyleContext *context, cairo_t *cr,
+                     gdouble x, gdouble y, gdouble width, gdouble height);
+static void (*fp_gtk_render_background)(GtkStyleContext *context, cairo_t *cr,
+                     gdouble x, gdouble y, gdouble width, gdouble height);
+static gboolean (*fp_gtk_style_context_has_class)(GtkStyleContext *context,
+                     const gchar *class_name);
+static void transform_detail_string (const gchar *detail,
+                     GtkStyleContext *context);
+void (*fp_gtk_style_context_set_junction_sides)(GtkStyleContext  *context,
+                     GtkJunctionSides  sides);
+void (*fp_gtk_style_context_add_region)(GtkStyleContext *context,
+                     const gchar *region_name, GtkRegionFlags flags);
+void (*fp_gtk_render_arrow)(GtkStyleContext *context, cairo_t *cr,
+                     gdouble angle, gdouble x, gdouble y, gdouble size);
+void (*fp_gtk_bin_set_child)(GtkBin *bin, GtkWidget *widget);
+void (*fp_gtk_scrolled_window_set_shadow_type)(
+                     GtkScrolledWindow *scrolled_window, GtkShadowType type);
+static void (*fp_gtk_render_slider)(GtkStyleContext *context, cairo_t *cr,
+                     gdouble x, gdouble y, gdouble width, gdouble height,
+                     GtkOrientation orientation);
+static void (*fp_gtk_style_context_get_padding)(GtkStyleContext *self,
+                     GtkStateFlags state, GtkBorder* padding);
+static void (*fp_gtk_range_set_inverted)(GtkRange *range, gboolean  setting);
+static PangoFontDescription* (*fp_gtk_style_context_get_font)(
+                     GtkStyleContext *context, GtkStateFlags state);
+static int (*fp_gtk_widget_get_allocated_width)(GtkWidget *widget);
+static int (*fp_gtk_widget_get_allocated_height)(GtkWidget *widget);
+static GtkIconTheme* (*fp_gtk_icon_theme_get_default)(void);
+static GdkPixbuf* (*fp_gtk_icon_theme_load_icon)(GtkIconTheme *icon_theme,
+                     const gchar *icon_name, gint size,
+                     GtkIconLookupFlags flags, GError **error);
+static void (*fp_gtk_adjustment_set_lower)(GtkAdjustment *adjustment,
+                     gdouble lower);
+static void (*fp_gtk_adjustment_set_page_increment)(GtkAdjustment *adjustment,
+                     gdouble page_increment);
+static void (*fp_gtk_adjustment_set_page_size)(GtkAdjustment *adjustment,
+                     gdouble page_size);
+static void (*fp_gtk_adjustment_set_step_increment)(GtkAdjustment *adjustment,
+                     gdouble step_increment);
+static void (*fp_gtk_adjustment_set_upper)(GtkAdjustment *adjustment,
+                     gdouble upper);
+static void (*fp_gtk_adjustment_set_value)(GtkAdjustment *adjustment,
+                     gdouble value);
+static GdkGC *(*fp_gdk_gc_new)(GdkDrawable*);
+static void (*fp_gdk_rgb_gc_set_foreground)(GdkGC*, guint32);
+static void (*fp_gdk_draw_rectangle)(GdkDrawable*, GdkGC*, gboolean,
+        gint, gint, gint, gint);
+static GdkPixbuf *(*fp_gdk_pixbuf_new)(GdkColorspace colorspace,
+        gboolean has_alpha, int bits_per_sample, int width, int height);
+static void (*fp_gdk_drawable_get_size)(GdkDrawable *drawable,
+        gint* width, gint* height);
+static gboolean (*fp_gtk_init_check)(int* argc, char** argv);
+
+/* Widget creation */
+static GtkWidget* (*fp_gtk_arrow_new)(GtkArrowType arrow_type,
+                                      GtkShadowType shadow_type);
+static GtkWidget* (*fp_gtk_button_new)();
+static GtkWidget* (*fp_gtk_check_button_new)();
+static GtkWidget* (*fp_gtk_check_menu_item_new)();
+static GtkWidget* (*fp_gtk_color_selection_dialog_new)(const gchar* title);
+static GtkWidget* (*fp_gtk_combo_box_new)();
+static GtkWidget* (*fp_gtk_combo_box_entry_new)();
+static GtkWidget* (*fp_gtk_entry_new)();
+static GtkWidget* (*fp_gtk_fixed_new)();
+static GtkWidget* (*fp_gtk_handle_box_new)();
+static GtkWidget* (*fp_gtk_hpaned_new)();
+static GtkWidget* (*fp_gtk_vpaned_new)();
+static GtkWidget* (*fp_gtk_scale_new)(GtkOrientation  orientation,
+                                       GtkAdjustment* adjustment);
+static GtkWidget* (*fp_gtk_hscrollbar_new)(GtkAdjustment* adjustment);
+static GtkWidget* (*fp_gtk_vscrollbar_new)(GtkAdjustment* adjustment);
+static GtkWidget* (*fp_gtk_hseparator_new)();
+static GtkWidget* (*fp_gtk_vseparator_new)();
+static GtkWidget* (*fp_gtk_image_new)();
+static GtkWidget* (*fp_gtk_label_new)(const gchar* str);
+static GtkWidget* (*fp_gtk_menu_new)();
+static GtkWidget* (*fp_gtk_menu_bar_new)();
+static GtkWidget* (*fp_gtk_menu_item_new)();
+static GtkWidget* (*fp_gtk_notebook_new)();
+static GtkWidget* (*fp_gtk_progress_bar_new)();
+static GtkWidget* (*fp_gtk_progress_bar_set_orientation)(
+        GtkProgressBar *pbar,
+        GtkProgressBarOrientation orientation);
+static GtkWidget* (*fp_gtk_radio_button_new)(GSList *group);
+static GtkWidget* (*fp_gtk_radio_menu_item_new)(GSList *group);
+static GtkWidget* (*fp_gtk_scrolled_window_new)(GtkAdjustment *hadjustment,
+        GtkAdjustment *vadjustment);
+static GtkWidget* (*fp_gtk_separator_menu_item_new)();
+static GtkWidget* (*fp_gtk_separator_tool_item_new)();
+static GtkWidget* (*fp_gtk_text_view_new)();
+static GtkWidget* (*fp_gtk_toggle_button_new)();
+static GtkWidget* (*fp_gtk_toolbar_new)();
+static GtkWidget* (*fp_gtk_tree_view_new)();
+static GtkWidget* (*fp_gtk_viewport_new)(GtkAdjustment *hadjustment,
+        GtkAdjustment *vadjustment);
+static GtkWidget* (*fp_gtk_window_new)(GtkWindowType type);
+static GtkWidget* (*fp_gtk_dialog_new)();
+static GtkWidget* (*fp_gtk_spin_button_new)(GtkAdjustment *adjustment,
+        gdouble climb_rate, guint digits);
+static GtkWidget* (*fp_gtk_frame_new)(const gchar *label);
+
+/* Other widget operations */
+static GtkAdjustment* (*fp_gtk_adjustment_new)(gdouble value,
+        gdouble lower, gdouble upper, gdouble step_increment,
+        gdouble page_increment, gdouble page_size);
+static void (*fp_gtk_container_add)(GtkContainer *window, GtkWidget *widget);
+static void (*fp_gtk_menu_shell_append)(GtkMenuShell *menu_shell,
+        GtkWidget *child);
+static void (*fp_gtk_menu_item_set_submenu)(GtkMenuItem *menu_item,
+        GtkWidget *submenu);
+static void (*fp_gtk_widget_realize)(GtkWidget *widget);
+static GdkPixbuf* (*fp_gtk_widget_render_icon)(GtkWidget *widget,
+        const gchar *stock_id, GtkIconSize size, const gchar *detail);
+static void (*fp_gtk_widget_set_name)(GtkWidget *widget, const gchar *name);
+static void (*fp_gtk_widget_set_parent)(GtkWidget *widget, GtkWidget *parent);
+static void (*fp_gtk_widget_set_direction)(GtkWidget *widget,
+        GtkTextDirection direction);
+static void (*fp_gtk_widget_style_get)(GtkWidget *widget,
+        const gchar *first_property_name, ...);
+static void (*fp_gtk_widget_class_install_style_property)(
+        GtkWidgetClass* class, GParamSpec *pspec);
+static GParamSpec* (*fp_gtk_widget_class_find_style_property)(
+        GtkWidgetClass* class, const gchar* property_name);
+static void (*fp_gtk_widget_style_get_property)(GtkWidget* widget,
+        const gchar* property_name, GValue* value);
+static char* (*fp_pango_font_description_to_string)(
+        const PangoFontDescription* fd);
+static GtkSettings* (*fp_gtk_settings_get_default)();
+static GtkSettings* (*fp_gtk_widget_get_settings)(GtkWidget *widget);
+static GType        (*fp_gtk_border_get_type)();
+static void (*fp_gtk_arrow_set)(GtkWidget* arrow,
+                                GtkArrowType arrow_type,
+                                GtkShadowType shadow_type);
+static void (*fp_gtk_widget_size_request)(GtkWidget *widget,
+                                          GtkRequisition *requisition);
+static GtkAdjustment* (*fp_gtk_range_get_adjustment)(GtkRange* range);
+
+#endif /* !_GTK3_INTERFACE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk_interface.c	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+#include <dlfcn.h>
+#include <stdlib.h>
+#include "jvm_md.h"
+#include "gtk_interface.h"
+
+GtkApi* gtk2_load(JNIEnv *env, const char* lib_name);
+GtkApi* gtk3_load(JNIEnv *env, const char* lib_name);
+
+gboolean gtk2_check(const char* lib_name, int flags);
+gboolean gtk3_check(const char* lib_name, int flags);
+
+GtkApi *gtk;
+
+typedef struct {
+    GtkVersion version;
+    const char* name;
+    const char* vname;
+    GtkApi* (*load)(JNIEnv *env, const char* lib_name);
+    gboolean (*check)(const char* lib_name, int flags);
+} GtkLib;
+
+static GtkLib libs[] = {
+    {
+        GTK_2,
+        JNI_LIB_NAME("gtk-x11-2.0"),
+        VERSIONED_JNI_LIB_NAME("gtk-x11-2.0", "0"),
+        &gtk2_load,
+        &gtk2_check
+    },
+    {
+        GTK_3,
+        JNI_LIB_NAME("gtk-3"),
+        VERSIONED_JNI_LIB_NAME("gtk-3", "0"),
+        &gtk3_load,
+        &gtk3_check
+    },
+    {
+        0,
+        NULL,
+        NULL,
+        NULL,
+        NULL
+    }
+};
+
+static GtkLib* get_loaded() {
+    GtkLib* lib = libs;
+    while(!gtk && lib->version) {
+        if (lib->check(lib->vname, RTLD_NOLOAD)) {
+            return lib;
+        }
+        if (lib->check(lib->name, RTLD_NOLOAD)) {
+            return lib;
+        }
+        lib++;
+    }
+    return NULL;
+}
+
+gboolean gtk_load(JNIEnv *env, GtkVersion version, gboolean verbose) {
+    if (gtk == NULL) {
+        GtkLib* lib = get_loaded();
+        if (lib) {
+            if (version != GTK_ANY && lib->version != version) {
+                if (verbose) {
+                    fprintf(stderr, "WARNING: Cannot load GTK%d library: \
+                         GTK%d has already been loaded\n", version, lib->version);
+                }
+                return FALSE;
+            }
+            if (verbose) {
+                fprintf(stderr, "Looking for GTK%d library...\n", version);
+            }
+            gtk = lib->load(env, lib->vname);
+            if (!gtk) {
+                gtk = lib->load(env, lib->name);
+            }
+        } else {
+            lib = libs;
+            while (!gtk && lib->version) {
+                if (version == GTK_ANY || lib->version == version) {
+                    if (verbose) {
+                        fprintf(stderr, "Looking for GTK%d library...\n",
+                                                                  lib->version);
+                    }
+                    gtk = lib->load(env, lib->vname);
+                    if (!gtk) {
+                        gtk = lib->load(env, lib->name);
+                    }
+                    if (verbose && !gtk) {
+                        fprintf(stderr, "Not found.\n");
+                    }
+                }
+                lib++;
+            }
+            lib--;
+        }
+        if (verbose) {
+            if (gtk) {
+                fprintf(stderr, "GTK%d library loaded.\n", lib->version);
+            } else {
+                fprintf(stderr, "Failed to load GTK library.\n");
+            }
+        }
+    }
+    return gtk != NULL;
+}
+
+static gboolean check_version(GtkVersion version, int flags) {
+    GtkLib* lib = libs;
+    while (lib->version) {
+        if (version == GTK_ANY || lib->version == version) {
+            if (lib->check(lib->vname, flags)) {
+                return TRUE;
+            }
+            if (lib->check(lib->name, flags)) {
+                return TRUE;
+            }
+        }
+        lib++;
+    }
+    return FALSE;
+}
+
+gboolean gtk_check_version(GtkVersion version) {
+    if (gtk) {
+        return TRUE;
+    }
+    if (check_version(version, RTLD_NOLOAD)) {
+        return TRUE;
+    }
+    return check_version(version, RTLD_LAZY | RTLD_LOCAL);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk_interface.h	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,560 @@
+/*
+ * Copyright (c) 2005, 2016, 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.
+ */
+#ifndef _GTK_INTERFACE_H
+#define _GTK_INTERFACE_H
+
+#include <X11/X.h>
+#include <jni.h>
+
+#ifndef FALSE
+#define FALSE           (0)
+#define TRUE            (!FALSE)
+#endif
+
+#define _G_TYPE_CIC(ip, gt, ct)       ((ct*) ip)
+#define G_TYPE_CHECK_INSTANCE_CAST(instance, g_type, c_type)  \
+                                    (_G_TYPE_CIC ((instance), (g_type), c_type))
+#define GTK_TYPE_FILE_CHOOSER             (fp_gtk_file_chooser_get_type ())
+#define GTK_FILE_CHOOSER(obj) \
+     (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FILE_CHOOSER, GtkFileChooser))
+#define G_CALLBACK(f) ((GCallback) (f))
+#define G_TYPE_FUNDAMENTAL_SHIFT (2)
+#define G_TYPE_MAKE_FUNDAMENTAL(x) ((GType) ((x) << G_TYPE_FUNDAMENTAL_SHIFT))
+#define G_TYPE_OBJECT G_TYPE_MAKE_FUNDAMENTAL (20)
+#define GTK_STOCK_CANCEL           "gtk-cancel"
+#define GTK_STOCK_SAVE             "gtk-save"
+#define GTK_STOCK_OPEN             "gtk-open"
+#define GDK_CURRENT_TIME           0L
+
+#define G_TYPE_INVALID                  G_TYPE_MAKE_FUNDAMENTAL (0)
+#define G_TYPE_NONE                     G_TYPE_MAKE_FUNDAMENTAL (1)
+#define G_TYPE_INTERFACE                G_TYPE_MAKE_FUNDAMENTAL (2)
+#define G_TYPE_CHAR                     G_TYPE_MAKE_FUNDAMENTAL (3)
+#define G_TYPE_UCHAR                    G_TYPE_MAKE_FUNDAMENTAL (4)
+#define G_TYPE_BOOLEAN                  G_TYPE_MAKE_FUNDAMENTAL (5)
+#define G_TYPE_INT                      G_TYPE_MAKE_FUNDAMENTAL (6)
+#define G_TYPE_UINT                     G_TYPE_MAKE_FUNDAMENTAL (7)
+#define G_TYPE_LONG                     G_TYPE_MAKE_FUNDAMENTAL (8)
+#define G_TYPE_ULONG                    G_TYPE_MAKE_FUNDAMENTAL (9)
+#define G_TYPE_INT64                    G_TYPE_MAKE_FUNDAMENTAL (10)
+#define G_TYPE_UINT64                   G_TYPE_MAKE_FUNDAMENTAL (11)
+#define G_TYPE_ENUM                     G_TYPE_MAKE_FUNDAMENTAL (12)
+#define G_TYPE_FLAGS                    G_TYPE_MAKE_FUNDAMENTAL (13)
+#define G_TYPE_FLOAT                    G_TYPE_MAKE_FUNDAMENTAL (14)
+#define G_TYPE_DOUBLE                   G_TYPE_MAKE_FUNDAMENTAL (15)
+#define G_TYPE_STRING                   G_TYPE_MAKE_FUNDAMENTAL (16)
+#define G_TYPE_POINTER                  G_TYPE_MAKE_FUNDAMENTAL (17)
+#define G_TYPE_BOXED                    G_TYPE_MAKE_FUNDAMENTAL (18)
+#define G_TYPE_PARAM                    G_TYPE_MAKE_FUNDAMENTAL (19)
+#define G_TYPE_OBJECT                   G_TYPE_MAKE_FUNDAMENTAL (20)
+
+#define GTK_TYPE_BORDER                 ((*fp_gtk_border_get_type)())
+
+#define G_TYPE_FUNDAMENTAL_SHIFT        (2)
+#define G_TYPE_MAKE_FUNDAMENTAL(x)      ((GType) ((x) << G_TYPE_FUNDAMENTAL_SHIFT))
+
+#ifndef MIN
+#define MIN(a, b)  (((a) < (b)) ? (a) : (b))
+#endif
+
+#define CONV_BUFFER_SIZE 128
+#define NO_SYMBOL_EXCEPTION 1
+
+/* basic types */
+typedef char    gchar;
+typedef short   gshort;
+typedef int     gint;
+typedef long    glong;
+typedef float   gfloat;
+typedef double  gdouble;
+typedef void*   gpointer;
+typedef gint    gboolean;
+typedef signed char  gint8;
+typedef signed short gint16;
+typedef signed int   gint32;
+typedef unsigned char  guchar;
+typedef unsigned char  guint8;
+typedef unsigned short gushort;
+typedef unsigned short guint16;
+typedef unsigned int   guint;
+typedef unsigned int   guint32;
+typedef unsigned int   gsize;
+typedef unsigned long  gulong;
+typedef signed long long   gint64;
+typedef unsigned long long guint64;
+typedef gulong GType;
+
+typedef struct _GList GList;
+struct _GList
+{
+  gpointer data;
+  GList *next;
+  GList *prev;
+};
+
+typedef struct _GSList GSList;
+struct _GSList {
+  gpointer data;
+  GSList *next;
+};
+
+typedef enum {
+    BUTTON,                     /* GtkButton */
+    CHECK_BOX,                  /* GtkCheckButton */
+    CHECK_BOX_MENU_ITEM,        /* GtkCheckMenuItem */
+    COLOR_CHOOSER,              /* GtkColorSelectionDialog */
+    COMBO_BOX,                  /* GtkComboBox */
+    COMBO_BOX_ARROW_BUTTON,     /* GtkComboBoxEntry */
+    COMBO_BOX_TEXT_FIELD,       /* GtkComboBoxEntry */
+    DESKTOP_ICON,               /* GtkLabel */
+    DESKTOP_PANE,               /* GtkContainer */
+    EDITOR_PANE,                /* GtkTextView */
+    FORMATTED_TEXT_FIELD,       /* GtkEntry */
+    HANDLE_BOX,                 /* GtkHandleBox */
+    HPROGRESS_BAR,              /* GtkProgressBar */
+    HSCROLL_BAR,                /* GtkHScrollbar */
+    HSCROLL_BAR_BUTTON_LEFT,    /* GtkHScrollbar */
+    HSCROLL_BAR_BUTTON_RIGHT,   /* GtkHScrollbar */
+    HSCROLL_BAR_TRACK,          /* GtkHScrollbar */
+    HSCROLL_BAR_THUMB,          /* GtkHScrollbar */
+    HSEPARATOR,                 /* GtkHSeparator */
+    HSLIDER,                    /* GtkHScale */
+    HSLIDER_TRACK,              /* GtkHScale */
+    HSLIDER_THUMB,              /* GtkHScale */
+    HSPLIT_PANE_DIVIDER,        /* GtkHPaned */
+    INTERNAL_FRAME,             /* GtkWindow */
+    INTERNAL_FRAME_TITLE_PANE,  /* GtkLabel */
+    IMAGE,                      /* GtkImage */
+    LABEL,                      /* GtkLabel */
+    LIST,                       /* GtkTreeView */
+    MENU,                       /* GtkMenu */
+    MENU_BAR,                   /* GtkMenuBar */
+    MENU_ITEM,                  /* GtkMenuItem */
+    MENU_ITEM_ACCELERATOR,      /* GtkLabel */
+    OPTION_PANE,                /* GtkMessageDialog */
+    PANEL,                      /* GtkContainer */
+    PASSWORD_FIELD,             /* GtkEntry */
+    POPUP_MENU,                 /* GtkMenu */
+    POPUP_MENU_SEPARATOR,       /* GtkSeparatorMenuItem */
+    RADIO_BUTTON,               /* GtkRadioButton */
+    RADIO_BUTTON_MENU_ITEM,     /* GtkRadioMenuItem */
+    ROOT_PANE,                  /* GtkContainer */
+    SCROLL_PANE,                /* GtkScrolledWindow */
+    SPINNER,                    /* GtkSpinButton */
+    SPINNER_ARROW_BUTTON,       /* GtkSpinButton */
+    SPINNER_TEXT_FIELD,         /* GtkSpinButton */
+    SPLIT_PANE,                 /* GtkPaned */
+    TABBED_PANE,                /* GtkNotebook */
+    TABBED_PANE_TAB_AREA,       /* GtkNotebook */
+    TABBED_PANE_CONTENT,        /* GtkNotebook */
+    TABBED_PANE_TAB,            /* GtkNotebook */
+    TABLE,                      /* GtkTreeView */
+    TABLE_HEADER,               /* GtkButton */
+    TEXT_AREA,                  /* GtkTextView */
+    TEXT_FIELD,                 /* GtkEntry */
+    TEXT_PANE,                  /* GtkTextView */
+    TITLED_BORDER,              /* GtkFrame */
+    TOGGLE_BUTTON,              /* GtkToggleButton */
+    TOOL_BAR,                   /* GtkToolbar */
+    TOOL_BAR_DRAG_WINDOW,       /* GtkToolbar */
+    TOOL_BAR_SEPARATOR,         /* GtkSeparatorToolItem */
+    TOOL_TIP,                   /* GtkWindow */
+    TREE,                       /* GtkTreeView */
+    TREE_CELL,                  /* GtkTreeView */
+    VIEWPORT,                   /* GtkViewport */
+    VPROGRESS_BAR,              /* GtkProgressBar */
+    VSCROLL_BAR,                /* GtkVScrollbar */
+    VSCROLL_BAR_BUTTON_UP,      /* GtkVScrollbar */
+    VSCROLL_BAR_BUTTON_DOWN,    /* GtkVScrollbar */
+    VSCROLL_BAR_TRACK,          /* GtkVScrollbar */
+    VSCROLL_BAR_THUMB,          /* GtkVScrollbar */
+    VSEPARATOR,                 /* GtkVSeparator */
+    VSLIDER,                    /* GtkVScale */
+    VSLIDER_TRACK,              /* GtkVScale */
+    VSLIDER_THUMB,              /* GtkVScale */
+    VSPLIT_PANE_DIVIDER,        /* GtkVPaned */
+    WIDGET_TYPE_SIZE
+} WidgetType;
+
+typedef enum
+{
+    _GTK_ARROW_TYPE,
+    _GTK_BUTTON_TYPE,
+    _GTK_CHECK_BUTTON_TYPE,
+    _GTK_CHECK_MENU_ITEM_TYPE,
+    _GTK_COLOR_SELECTION_DIALOG_TYPE,
+    _GTK_COMBO_BOX_TYPE,
+    _GTK_COMBO_BOX_ARROW_BUTTON_TYPE,
+    _GTK_COMBO_BOX_TEXT_FIELD_TYPE,
+    _GTK_CONTAINER_TYPE,
+    _GTK_ENTRY_TYPE,
+    _GTK_FRAME_TYPE,
+    _GTK_HANDLE_BOX_TYPE,
+    _GTK_HPANED_TYPE,
+    _GTK_HPROGRESS_BAR_TYPE,
+    _GTK_HSCALE_TYPE,
+    _GTK_HSCROLLBAR_TYPE,
+    _GTK_HSEPARATOR_TYPE,
+    _GTK_IMAGE_TYPE,
+    _GTK_MENU_TYPE,
+    _GTK_MENU_BAR_TYPE,
+    _GTK_MENU_ITEM_TYPE,
+    _GTK_NOTEBOOK_TYPE,
+    _GTK_LABEL_TYPE,
+    _GTK_RADIO_BUTTON_TYPE,
+    _GTK_RADIO_MENU_ITEM_TYPE,
+    _GTK_SCROLLED_WINDOW_TYPE,
+    _GTK_SEPARATOR_MENU_ITEM_TYPE,
+    _GTK_SEPARATOR_TOOL_ITEM_TYPE,
+    _GTK_SPIN_BUTTON_TYPE,
+    _GTK_TEXT_VIEW_TYPE,
+    _GTK_TOGGLE_BUTTON_TYPE,
+    _GTK_TOOLBAR_TYPE,
+    _GTK_TOOLTIP_TYPE,
+    _GTK_TREE_VIEW_TYPE,
+    _GTK_VIEWPORT_TYPE,
+    _GTK_VPANED_TYPE,
+    _GTK_VPROGRESS_BAR_TYPE,
+    _GTK_VSCALE_TYPE,
+    _GTK_VSCROLLBAR_TYPE,
+    _GTK_VSEPARATOR_TYPE,
+    _GTK_WINDOW_TYPE,
+    _GTK_DIALOG_TYPE,
+    _GTK_WIDGET_TYPE_SIZE
+} GtkWidgetType;
+
+typedef enum
+{
+  GTK_STATE_NORMAL,
+  GTK_STATE_ACTIVE,
+  GTK_STATE_PRELIGHT,
+  GTK_STATE_SELECTED,
+  GTK_STATE_INSENSITIVE,
+  GTK_STATE_INCONSISTENT,
+  GTK_STATE_FOCUSED
+} GtkStateType;
+
+typedef enum
+{
+  GTK_SHADOW_NONE,
+  GTK_SHADOW_IN,
+  GTK_SHADOW_OUT,
+  GTK_SHADOW_ETCHED_IN,
+  GTK_SHADOW_ETCHED_OUT
+} GtkShadowType;
+
+typedef enum
+{
+  GTK_EXPANDER_COLLAPSED,
+  GTK_EXPANDER_SEMI_COLLAPSED,
+  GTK_EXPANDER_SEMI_EXPANDED,
+  GTK_EXPANDER_EXPANDED
+} GtkExpanderStyle;
+
+typedef enum
+{
+  GTK_ICON_SIZE_INVALID,
+  GTK_ICON_SIZE_MENU,
+  GTK_ICON_SIZE_SMALL_TOOLBAR,
+  GTK_ICON_SIZE_LARGE_TOOLBAR,
+  GTK_ICON_SIZE_BUTTON,
+  GTK_ICON_SIZE_DND,
+  GTK_ICON_SIZE_DIALOG
+} GtkIconSize;
+
+typedef enum
+{
+  GTK_ORIENTATION_HORIZONTAL,
+  GTK_ORIENTATION_VERTICAL
+} GtkOrientation;
+
+typedef enum
+{
+    FOREGROUND,
+    BACKGROUND,
+    TEXT_FOREGROUND,
+    TEXT_BACKGROUND,
+    FOCUS,
+    LIGHT,
+    DARK,
+    MID,
+    BLACK,
+    WHITE
+} ColorType;
+
+typedef enum
+{
+    GTK_FONT_NAME,
+    GTK_ICON_SIZES,
+    GTK_CURSOR_BLINK,
+    GTK_CURSOR_BLINK_TIME
+} Setting;
+
+typedef enum
+{
+  GTK_ARROW_UP,
+  GTK_ARROW_DOWN,
+  GTK_ARROW_LEFT,
+  GTK_ARROW_RIGHT,
+  GTK_ARROW_NONE
+} GtkArrowType;
+
+typedef enum
+{
+  GTK_TEXT_DIR_NONE,
+  GTK_TEXT_DIR_LTR,
+  GTK_TEXT_DIR_RTL
+} GtkTextDirection;
+
+typedef enum
+{
+  GTK_POS_LEFT,
+  GTK_POS_RIGHT,
+  GTK_POS_TOP,
+  GTK_POS_BOTTOM
+} GtkPositionType;
+
+/* SynthConstants */
+static const gint ENABLED    = 1 << 0;
+static const gint MOUSE_OVER = 1 << 1;
+static const gint PRESSED    = 1 << 2;
+static const gint DISABLED   = 1 << 3;
+static const gint FOCUSED    = 1 << 8;
+static const gint SELECTED   = 1 << 9;
+static const gint DEFAULT    = 1 << 10;
+
+typedef enum
+{
+  GTK_ANY,
+  GTK_1,
+  GTK_2,
+  GTK_3
+} GtkVersion;
+
+//------------------------------
+
+
+
+typedef enum {
+  GTK_RESPONSE_NONE = -1,
+  GTK_RESPONSE_REJECT = -2,
+  GTK_RESPONSE_ACCEPT = -3,
+  GTK_RESPONSE_DELETE_EVENT = -4,
+  GTK_RESPONSE_OK = -5,
+  GTK_RESPONSE_CANCEL = -6,
+  GTK_RESPONSE_CLOSE = -7,
+  GTK_RESPONSE_YES = -8,
+  GTK_RESPONSE_NO = -9,
+  GTK_RESPONSE_APPLY = -10,
+  GTK_RESPONSE_HELP = -11
+} GtkResponseType;
+
+typedef enum {
+  GTK_FILE_CHOOSER_ACTION_OPEN,
+  GTK_FILE_CHOOSER_ACTION_SAVE,
+  GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+  GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
+} GtkFileChooserAction;
+
+typedef enum {
+  GTK_FILE_FILTER_FILENAME = 1 << 0,
+  GTK_FILE_FILTER_URI = 1 << 1,
+  GTK_FILE_FILTER_DISPLAY_NAME = 1 << 2,
+  GTK_FILE_FILTER_MIME_TYPE = 1 << 3
+} GtkFileFilterFlags;
+
+typedef enum {
+  GDK_COLORSPACE_RGB
+} GdkColorspace;
+
+typedef enum {
+    GDK_INTERP_NEAREST,
+    GDK_INTERP_TILES,
+    GDK_INTERP_BILINEAR,
+    GDK_INTERP_HYPER
+} GdkInterpType;
+
+typedef enum {
+  G_CONNECT_AFTER = 1 << 0, G_CONNECT_SWAPPED = 1 << 1
+} GConnectFlags;
+//------------------------------
+
+
+typedef void GError;
+typedef void GdkScreen;
+typedef void GtkWindow;
+typedef void GdkWindow;
+typedef void GClosure;
+typedef void GtkFileChooser;
+typedef void GtkFileFilter;
+typedef struct {
+    GtkFileFilterFlags contains;
+    const gchar *filename;
+    const gchar *uri;
+    const gchar *display_name;
+    const gchar *mime_type;
+} GtkFileFilterInfo;
+typedef gboolean (*GtkFileFilterFunc)(const GtkFileFilterInfo *filter_info,
+                                                                 gpointer data);
+typedef void (*GClosureNotify)(gpointer data, GClosure *closure);
+typedef void (*GDestroyNotify)(gpointer data);
+typedef void (*GCallback)(void);
+
+
+typedef struct GtkApi {
+    int version;
+    gboolean (*show_uri_load)(JNIEnv *env);
+    gboolean (*unload)();
+    void (*flush_event_loop)();
+    gchar* (*gtk_check_version)(guint required_major, guint required_minor,
+                                guint required_micro);
+    jobject (*get_setting)(JNIEnv *env, Setting property);
+
+    void (*paint_arrow)(WidgetType widget_type, GtkStateType state_type,
+        GtkShadowType shadow_type, const gchar *detail,
+        gint x, gint y, gint width, gint height,
+        GtkArrowType arrow_type, gboolean fill);
+    void (*paint_box)(WidgetType widget_type, GtkStateType state_type,
+                        GtkShadowType shadow_type, const gchar *detail,
+                        gint x, gint y, gint width, gint height,
+                        gint synth_state, GtkTextDirection dir);
+    void (*paint_box_gap)(WidgetType widget_type, GtkStateType state_type,
+            GtkShadowType shadow_type, const gchar *detail,
+            gint x, gint y, gint width, gint height,
+            GtkPositionType gap_side, gint gap_x, gint gap_width);
+    void (*paint_expander)(WidgetType widget_type, GtkStateType state_type,
+            const gchar *detail, gint x, gint y, gint width, gint height,
+            GtkExpanderStyle expander_style);
+    void (*paint_extension)(WidgetType widget_type, GtkStateType state_type,
+            GtkShadowType shadow_type, const gchar *detail,
+            gint x, gint y, gint width, gint height, GtkPositionType gap_side);
+    void (*paint_flat_box)(WidgetType widget_type, GtkStateType state_type,
+            GtkShadowType shadow_type, const gchar *detail,
+            gint x, gint y, gint width, gint height, gboolean has_focus);
+    void (*paint_focus)(WidgetType widget_type, GtkStateType state_type,
+            const char *detail, gint x, gint y, gint width, gint height);
+    void (*paint_handle)(WidgetType widget_type, GtkStateType state_type,
+           GtkShadowType shadow_type, const gchar *detail,
+           gint x, gint y, gint width, gint height, GtkOrientation orientation);
+    void (*paint_hline)(WidgetType widget_type, GtkStateType state_type,
+            const gchar *detail, gint x, gint y, gint width, gint height);
+    void (*paint_vline)(WidgetType widget_type, GtkStateType state_type,
+            const gchar *detail, gint x, gint y, gint width, gint height);
+    void (*paint_option)(WidgetType widget_type, gint synth_state,
+             const gchar *detail, gint x, gint y, gint width, gint height);
+    void (*paint_shadow)(WidgetType widget_type, GtkStateType state_type,
+                           GtkShadowType shadow_type, const gchar *detail,
+                           gint x, gint y, gint width, gint height,
+                           gint synth_state, GtkTextDirection dir);
+    void (*paint_slider)(WidgetType widget_type, GtkStateType state_type,
+            GtkShadowType shadow_type, const gchar *detail,
+            gint x, gint y, gint width, gint height, GtkOrientation orientation,
+            gboolean has_focus);
+    void (*paint_background)(WidgetType widget_type, GtkStateType state_type,
+            gint x, gint y, gint width, gint height);
+    void (*paint_check)(WidgetType widget_type, gint synth_state,
+        const gchar *detail, gint x, gint y, gint width, gint height);
+    void (*set_range_value)(WidgetType widget_type, jdouble value,
+                              jdouble min, jdouble max, jdouble visible);
+
+    void (*init_painting)(JNIEnv *env, gint w, gint h);
+    gint (*copy_image)(gint *dest, gint width, gint height);
+
+    gint (*get_xthickness)(JNIEnv *env, WidgetType widget_type);
+    gint (*get_ythickness)(JNIEnv *env, WidgetType widget_type);
+    gint (*get_color_for_state)(JNIEnv *env, WidgetType widget_type,
+                                  GtkStateType state_type, ColorType color_type);
+    jobject (*get_class_value)(JNIEnv *env, WidgetType widget_type,
+                               const char* key);
+
+    jstring (*get_pango_font_name)(JNIEnv *env, WidgetType widget_type);
+    jboolean (*get_icon_data)(JNIEnv *env, gint widget_type,
+                    const gchar *stock_id, GtkIconSize size,
+                    GtkTextDirection direction, const char *detail,
+                    jmethodID icon_upcall_method, jobject this);
+    jboolean (*get_file_icon_data)(JNIEnv *env, const char *filename,
+                    GError **error, jmethodID icon_upcall_method, jobject this);
+    void (*gdk_threads_enter)(void);
+    void (*gdk_threads_leave)(void);
+    gboolean (*gtk_show_uri)(GdkScreen *screen, const gchar *uri,
+                                             guint32 timestamp, GError **error);
+    gboolean (*get_drawable_data)(JNIEnv *env, jintArray pixelArray,
+                                       jint x, jint y, jint width, jint height,
+                                       jint jwidth, int dx, int dy, jint scale);
+    void (*g_free)(gpointer mem);
+
+
+    gchar* (*gtk_file_chooser_get_filename)(GtkFileChooser *chooser);
+    void (*gtk_widget_hide)(void* widget);
+    void (*gtk_main_quit)(void);
+    void* (*gtk_file_chooser_dialog_new)(const gchar *title,
+        GtkWindow *parent, GtkFileChooserAction action,
+        const gchar *first_button_text, ...);
+    gboolean (*gtk_file_chooser_set_current_folder)(GtkFileChooser *chooser,
+        const gchar *filename);
+    gboolean (*gtk_file_chooser_set_filename)(GtkFileChooser *chooser,
+        const char *filename);
+    void (*gtk_file_chooser_set_current_name)(GtkFileChooser *chooser,
+        const gchar *name);
+    void (*gtk_file_filter_add_custom)(GtkFileFilter *filter,
+        GtkFileFilterFlags needed, GtkFileFilterFunc func, gpointer data,
+        GDestroyNotify notify);
+    void (*gtk_file_chooser_set_filter)(GtkFileChooser *chooser,
+        GtkFileFilter *filter);
+    GType (*gtk_file_chooser_get_type)(void);
+    GtkFileFilter* (*gtk_file_filter_new)(void);
+    void (*gtk_file_chooser_set_do_overwrite_confirmation)(
+        GtkFileChooser *chooser, gboolean do_overwrite_confirmation);
+    void (*gtk_file_chooser_set_select_multiple)(
+        GtkFileChooser *chooser, gboolean select_multiple);
+    gchar* (*gtk_file_chooser_get_current_folder)(GtkFileChooser *chooser);
+    GSList* (*gtk_file_chooser_get_filenames)(GtkFileChooser *chooser);
+    guint (*gtk_g_slist_length)(GSList *list);
+    gulong (*g_signal_connect_data)(gpointer instance,
+        const gchar *detailed_signal, GCallback c_handler, gpointer data,
+        GClosureNotify destroy_data, GConnectFlags connect_flags);
+    void (*gtk_widget_show)(void *widget);
+    void (*gtk_main)(void);
+    guint (*gtk_main_level)(void);
+    gchar* (*g_path_get_dirname) (const gchar *file_name);
+    XID (*gdk_x11_drawable_get_xid) (void *drawable);
+    void (*gtk_widget_destroy)(void *widget);
+    void (*gtk_window_present)(void *window);
+    void (*gtk_window_move)(void *window, gint x, gint y);
+    void (*gtk_window_resize)(void *window, gint width, gint height);
+    GdkWindow *(*get_window)(void *widget);
+
+    void (*g_object_unref)(gpointer object);
+    GList* (*g_list_append) (GList *list, gpointer data);
+    void (*g_list_free) (GList *list);
+    void (*g_list_free_full) (GList *list, GDestroyNotify free_func);
+} GtkApi;
+
+gboolean gtk_load(JNIEnv *env, GtkVersion version, gboolean verbose);
+gboolean gtk_check_version(GtkVersion version);
+
+extern GtkApi* gtk;
+
+#endif /* !_GTK_INTERFACE_H */
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/sun_awt_X11_GtkFileDialogPeer.c	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/sun_awt_X11_GtkFileDialogPeer.c	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,11 +28,12 @@
 #include <jni_util.h>
 #include <string.h>
 #include <X11/X.h>
-#include "gtk2_interface.h"
+#include "gtk_interface.h"
 #include "sun_awt_X11_GtkFileDialogPeer.h"
 #include "java_awt_FileDialog.h"
 #include "debug_assert.h"
 
+typedef void GtkWidget;
 static JavaVM *jvm;
 
 /* To cache some method IDs */
@@ -90,20 +91,20 @@
     {
         // Callbacks from GTK signals are made within the GTK lock
         // So, within a signal handler there is no need to call
-        // gdk_threads_enter() / fp_gdk_threads_leave()
+        // gdk_threads_enter() / gtk->gdk_threads_leave()
         if (!isSignalHandler) {
-            fp_gdk_threads_enter();
+            gtk->gdk_threads_enter();
         }
 
-        fp_gtk_widget_hide (dialog);
-        fp_gtk_widget_destroy (dialog);
+        gtk->gtk_widget_hide (dialog);
+        gtk->gtk_widget_destroy (dialog);
 
-        fp_gtk_main_quit ();
+        gtk->gtk_main_quit ();
 
         (*env)->SetLongField(env, jpeer, widgetFieldID, 0);
 
         if (!isSignalHandler) {
-            fp_gdk_threads_leave();
+            gtk->gdk_threads_leave();
         }
     }
 
@@ -133,16 +134,16 @@
 {
     GtkWidget * dialog;
 
-    fp_gdk_threads_enter();
+    gtk->gdk_threads_enter();
 
     dialog = (GtkWidget*)jlong_to_ptr(
             (*env)->GetLongField(env, jpeer, widgetFieldID));
 
     if (dialog != NULL) {
-        fp_gtk_window_present((GtkWindow*)dialog);
+        gtk->gtk_window_present((GtkWindow*)dialog);
     }
 
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_leave();
 }
 
 /*
@@ -155,21 +156,21 @@
 {
     GtkWindow* dialog;
 
-    fp_gdk_threads_enter();
+    gtk->gdk_threads_enter();
 
     dialog = (GtkWindow*)jlong_to_ptr(
         (*env)->GetLongField(env, jpeer, widgetFieldID));
 
     if (dialog != NULL) {
         if (x >= 0 && y >= 0) {
-            fp_gtk_window_move(dialog, (gint)x, (gint)y);
+            gtk->gtk_window_move(dialog, (gint)x, (gint)y);
         }
         if (width > 0 && height > 0) {
-            fp_gtk_window_resize(dialog, (gint)width, (gint)height);
+            gtk->gtk_window_resize(dialog, (gint)width, (gint)height);
         }
     }
 
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_leave();
 }
 
 /*
@@ -182,18 +183,18 @@
     gboolean isAllDirsSame = TRUE;
 
     while (it) {
-        gchar* dir = fp_g_path_get_dirname((gchar*) it->data);
+        gchar* dir = gtk->g_path_get_dirname((gchar*) it->data);
 
         if (prevDir && strcmp(prevDir, dir) != 0) {
             isAllDirsSame = FALSE;
-            fp_g_free(dir);
+            gtk->g_free(dir);
             break;
         }
 
         if (!prevDir) {
             prevDir = strdup(dir);
         }
-        fp_g_free(dir);
+        gtk->g_free(dir);
 
         it = it->next;
     }
@@ -233,7 +234,7 @@
         return NULL;
     }
 
-    array = (*env)->NewObjectArray(env, fp_gtk_g_slist_length(list), stringCls, NULL);
+    array = (*env)->NewObjectArray(env, gtk->gtk_g_slist_length(list), stringCls, NULL);
     if (array == NULL) {
         (*env)->ExceptionClear(env);
         JNU_ThrowInternalError(env, "Could not instantiate array files array");
@@ -287,7 +288,7 @@
     filenames = NULL;
 
     if (responseId == GTK_RESPONSE_ACCEPT) {
-        filenames = fp_gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(aDialog));
+        filenames = gtk->gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(aDialog));
     }
 
     jfilenames = toFilenamesArray(env, filenames, &jcurrent_folder);
@@ -318,7 +319,7 @@
         JNU_CHECK_EXCEPTION(env);
     }
 
-    fp_gdk_threads_enter();
+    gtk->gdk_threads_enter();
 
     const char *title = jtitle == NULL? "": (*env)->GetStringUTFChars(env, jtitle, 0);
     if (title == NULL) {
@@ -329,19 +330,19 @@
 
     if (mode == java_awt_FileDialog_SAVE) {
         /* Save action */
-        dialog = fp_gtk_file_chooser_dialog_new(title, NULL,
+        dialog = gtk->gtk_file_chooser_dialog_new(title, NULL,
                 GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL,
                 GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
     }
     else {
         /* Default action OPEN */
-        dialog = fp_gtk_file_chooser_dialog_new(title, NULL,
+        dialog = gtk->gtk_file_chooser_dialog_new(title, NULL,
                 GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL,
                 GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
 
         /* Set multiple selection mode, that is allowed only in OPEN action */
         if (multiple) {
-            fp_gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog),
+            gtk->gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog),
                     multiple);
         }
     }
@@ -358,7 +359,7 @@
             JNU_ThrowOutOfMemoryError(env, "Could not get dir");
             return;
         }
-        fp_gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), dir);
+        gtk->gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), dir);
         (*env)->ReleaseStringUTFChars(env, jdir, dir);
     }
 
@@ -371,47 +372,48 @@
             return;
         }
         if (mode == java_awt_FileDialog_SAVE) {
-            fp_gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), filename);
+            gtk->gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), filename);
         } else {
-            fp_gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), filename);
+            gtk->gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), filename);
         }
         (*env)->ReleaseStringUTFChars(env, jfile, filename);
     }
 
     /* Set the file filter */
     if (jfilter != NULL) {
-        filter = fp_gtk_file_filter_new();
-        fp_gtk_file_filter_add_custom(filter, GTK_FILE_FILTER_FILENAME,
+        filter = gtk->gtk_file_filter_new();
+        gtk->gtk_file_filter_add_custom(filter, GTK_FILE_FILTER_FILENAME,
                 filenameFilterCallback, jpeer, NULL);
-        fp_gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter);
+        gtk->gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter);
     }
 
     /* Other Properties */
-    if (fp_gtk_check_version(2, 8, 0) == NULL) {
-        fp_gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(
+    if (gtk->gtk_check_version(2, 8, 0) == NULL ||
+                                     gtk->gtk_check_version(3, 0, 0) == NULL) {
+        gtk->gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(
                 dialog), TRUE);
     }
 
     /* Set the initial location */
     if (x >= 0 && y >= 0) {
-        fp_gtk_window_move((GtkWindow*)dialog, (gint)x, (gint)y);
+        gtk->gtk_window_move((GtkWindow*)dialog, (gint)x, (gint)y);
 
         // NOTE: it doesn't set the initial size for the file chooser
         // as it seems like the file chooser overrides the size internally
     }
 
-    fp_g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(
-            handle_response), jpeer);
+    gtk->g_signal_connect_data(dialog, "response", G_CALLBACK(
+            handle_response), jpeer, 0, 0);
 
     (*env)->SetLongField(env, jpeer, widgetFieldID, ptr_to_jlong(dialog));
 
-    fp_gtk_widget_show(dialog);
+    gtk->gtk_widget_show(dialog);
 
-    XID xid = fp_gdk_x11_drawable_get_xid(dialog->window);
+    XID xid = gtk->gdk_x11_drawable_get_xid(gtk->get_window(dialog));
     if( (*env)->CallBooleanMethod(env, jpeer, setWindowMethodID, xid) ) {
-        fp_gtk_main();
+        gtk->gtk_main();
     }
 
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_leave();
 }
 
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/swing_GTKEngine.c	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/swing_GTKEngine.c	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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,9 +24,24 @@
  */
 
 #include <stdlib.h>
-#include "gtk2_interface.h"
+#include "gtk_interface.h"
 #include "com_sun_java_swing_plaf_gtk_GTKEngine.h"
 
+/* Static buffer for conversion from java.lang.String to UTF-8 */
+static char conversionBuffer[CONV_BUFFER_SIZE];
+
+const char *getStrFor(JNIEnv *env, jstring val)
+{
+    int length = (*env)->GetStringLength(env, val);
+    if (length > CONV_BUFFER_SIZE-1)
+    {
+        length = CONV_BUFFER_SIZE-1;
+    }
+
+    (*env)->GetStringUTFRegion(env, val, 0, length, conversionBuffer);
+    return conversionBuffer;
+}
+
 /*
  * Class:     com_sun_java_swing_plaf_gtk_GTKEngine
  * Method:    native_paint_arrow
@@ -38,10 +53,10 @@
         jint widget_type, jint state, jint shadow_type, jstring detail,
         jint x, jint y, jint w, jint h, jint arrow_type)
 {
-    fp_gdk_threads_enter();
-    gtk2_paint_arrow(widget_type, state, shadow_type, getStrFor(env, detail),
+    gtk->gdk_threads_enter();
+    gtk->paint_arrow(widget_type, state, shadow_type, getStrFor(env, detail),
             x, y, w, h, arrow_type, TRUE);
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_leave();
 }
 
 /*
@@ -56,10 +71,10 @@
         jint x, jint y, jint w, jint h,
         jint synth_state, jint dir)
 {
-    fp_gdk_threads_enter();
-    gtk2_paint_box(widget_type, state, shadow_type, getStrFor(env, detail),
+    gtk->gdk_threads_enter();
+    gtk->paint_box(widget_type, state, shadow_type, getStrFor(env, detail),
                    x, y, w, h, synth_state, dir);
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_leave();
 }
 
 /*
@@ -74,10 +89,10 @@
         jint x, jint y, jint w, jint h,
         jint gap_side, jint gap_x, jint gap_w)
 {
-    fp_gdk_threads_enter();
-    gtk2_paint_box_gap(widget_type, state, shadow_type, getStrFor(env, detail),
+    gtk->gdk_threads_enter();
+    gtk->paint_box_gap(widget_type, state, shadow_type, getStrFor(env, detail),
             x, y, w, h, gap_side, gap_x, gap_w);
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_leave();
 }
 
 /*
@@ -91,10 +106,10 @@
         jint widget_type, jint synth_state, jstring detail,
         jint x, jint y, jint w, jint h)
 {
-    fp_gdk_threads_enter();
-    gtk2_paint_check(widget_type, synth_state, getStrFor(env, detail),
+    gtk->gdk_threads_enter();
+    gtk->paint_check(widget_type, synth_state, getStrFor(env, detail),
                      x, y, w, h);
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_leave();
 }
 
 /*
@@ -108,10 +123,10 @@
         jint widget_type, jint state, jstring detail,
         jint x, jint y, jint w, jint h, jint expander_style)
 {
-    fp_gdk_threads_enter();
-    gtk2_paint_expander(widget_type, state, getStrFor(env, detail),
+    gtk->gdk_threads_enter();
+    gtk->paint_expander(widget_type, state, getStrFor(env, detail),
             x, y, w, h, expander_style);
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_leave();
 }
 
 /*
@@ -125,10 +140,10 @@
         jint widget_type, jint state, jint shadow_type, jstring detail,
         jint x, jint y, jint w, jint h, jint placement)
 {
-    fp_gdk_threads_enter();
-    gtk2_paint_extension(widget_type, state, shadow_type,
+    gtk->gdk_threads_enter();
+    gtk->paint_extension(widget_type, state, shadow_type,
             getStrFor(env, detail), x, y, w, h, placement);
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_leave();
 }
 
 /*
@@ -142,10 +157,10 @@
         jint widget_type, jint state, jint shadow_type, jstring detail,
         jint x, jint y, jint w, jint h, jboolean has_focus)
 {
-    fp_gdk_threads_enter();
-    gtk2_paint_flat_box(widget_type, state, shadow_type,
+    gtk->gdk_threads_enter();
+    gtk->paint_flat_box(widget_type, state, shadow_type,
             getStrFor(env, detail), x, y, w, h, has_focus);
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_leave();
 }
 
 /*
@@ -159,10 +174,10 @@
         jint widget_type, jint state, jstring detail,
         jint x, jint y, jint w, jint h)
 {
-    fp_gdk_threads_enter();
-    gtk2_paint_focus(widget_type, state, getStrFor(env, detail),
+    gtk->gdk_threads_enter();
+    gtk->paint_focus(widget_type, state, getStrFor(env, detail),
             x, y, w, h);
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_leave();
 }
 
 /*
@@ -176,10 +191,10 @@
         jint widget_type, jint state, jint shadow_type, jstring detail,
         jint x, jint y, jint w, jint h, jint orientation)
 {
-    fp_gdk_threads_enter();
-    gtk2_paint_handle(widget_type, state, shadow_type, getStrFor(env, detail),
+    gtk->gdk_threads_enter();
+    gtk->paint_handle(widget_type, state, shadow_type, getStrFor(env, detail),
             x, y, w, h, orientation);
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_leave();
 }
 
 /*
@@ -193,10 +208,10 @@
         jint widget_type, jint state, jstring detail,
         jint x, jint y, jint w, jint h)
 {
-    fp_gdk_threads_enter();
-    gtk2_paint_hline(widget_type, state, getStrFor(env, detail),
+    gtk->gdk_threads_enter();
+    gtk->paint_hline(widget_type, state, getStrFor(env, detail),
             x, y, w, h);
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_leave();
 }
 
 /*
@@ -210,10 +225,10 @@
         jint widget_type, jint synth_state, jstring detail,
         jint x, jint y, jint w, jint h)
 {
-    fp_gdk_threads_enter();
-    gtk2_paint_option(widget_type, synth_state, getStrFor(env, detail),
+    gtk->gdk_threads_enter();
+    gtk->paint_option(widget_type, synth_state, getStrFor(env, detail),
                       x, y, w, h);
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_leave();
 }
 
 /*
@@ -228,10 +243,10 @@
         jint x, jint y, jint w, jint h,
         jint synth_state, jint dir)
 {
-    fp_gdk_threads_enter();
-    gtk2_paint_shadow(widget_type, state, shadow_type, getStrFor(env, detail),
+    gtk->gdk_threads_enter();
+    gtk->paint_shadow(widget_type, state, shadow_type, getStrFor(env, detail),
                       x, y, w, h, synth_state, dir);
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_leave();
 }
 
 /*
@@ -243,12 +258,12 @@
 Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1slider(
         JNIEnv *env, jobject this,
         jint widget_type, jint state, jint shadow_type, jstring detail,
-        jint x, jint y, jint w, jint h, jint orientation)
+        jint x, jint y, jint w, jint h, jint orientation, jboolean has_focus)
 {
-    fp_gdk_threads_enter();
-    gtk2_paint_slider(widget_type, state, shadow_type, getStrFor(env, detail),
-            x, y, w, h, orientation);
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_enter();
+    gtk->paint_slider(widget_type, state, shadow_type, getStrFor(env, detail),
+            x, y, w, h, orientation, has_focus);
+    gtk->gdk_threads_leave();
 }
 
 /*
@@ -262,10 +277,10 @@
         jint widget_type, jint state, jstring detail,
         jint x, jint y, jint w, jint h)
 {
-    fp_gdk_threads_enter();
-    gtk2_paint_vline(widget_type, state, getStrFor(env, detail),
+    gtk->gdk_threads_enter();
+    gtk->paint_vline(widget_type, state, getStrFor(env, detail),
             x, y, w, h);
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_leave();
 }
 
 /*
@@ -278,9 +293,9 @@
         JNIEnv *env, jobject this, jint widget_type, jint state,
         jint x, jint y, jint w, jint h)
 {
-    fp_gdk_threads_enter();
-    gtk_paint_background(widget_type, state, x, y, w, h);
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_enter();
+    gtk->paint_background(widget_type, state, x, y, w, h);
+    gtk->gdk_threads_leave();
 }
 
 /*
@@ -292,9 +307,9 @@
 Java_com_sun_java_swing_plaf_gtk_GTKEngine_nativeStartPainting(
         JNIEnv *env, jobject this, jint w, jint h)
 {
-    fp_gdk_threads_enter();
-    gtk2_init_painting(env, w, h);
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_enter();
+    gtk->init_painting(env, w, h);
+    gtk->gdk_threads_leave();
 }
 
 /*
@@ -308,9 +323,9 @@
 {
     jint transparency;
     gint *buffer = (gint*) (*env)->GetPrimitiveArrayCritical(env, dest, 0);
-    fp_gdk_threads_enter();
-    transparency = gtk2_copy_image(buffer, width, height);
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_enter();
+    transparency = gtk->copy_image(buffer, width, height);
+    gtk->gdk_threads_leave();
     (*env)->ReleasePrimitiveArrayCritical(env, dest, buffer, 0);
     return transparency;
 }
@@ -324,7 +339,9 @@
         JNIEnv *env, jobject this)
 {
     // Note that flush_gtk_event_loop takes care of locks (7053002)
-    flush_gtk_event_loop();
+    gtk->gdk_threads_enter();
+    gtk->flush_event_loop();
+    gtk->gdk_threads_leave();
 }
 
 /*
@@ -336,9 +353,9 @@
         JNIEnv *env, jobject this, jint property)
 {
     jobject obj;
-    fp_gdk_threads_enter();
-    obj = gtk2_get_setting(env, property);
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_enter();
+    obj = gtk->get_setting(env, property);
+    gtk->gdk_threads_leave();
     return obj;
 }
 
@@ -352,7 +369,7 @@
         JNIEnv *env, jobject this, jint widget_type,
         jdouble value, jdouble min, jdouble max, jdouble visible)
 {
-    fp_gdk_threads_enter();
-    gtk2_set_range_value(widget_type, value, min, max, visible);
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_enter();
+    gtk->set_range_value(widget_type, value, min, max, visible);
+    gtk->gdk_threads_leave();
 }
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/swing_GTKStyle.c	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/swing_GTKStyle.c	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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,9 +24,12 @@
  */
 
 #include <stdlib.h>
-#include "gtk2_interface.h"
+#include <stdio.h>
+#include "gtk_interface.h"
 #include "com_sun_java_swing_plaf_gtk_GTKStyle.h"
 
+const char *getStrFor(JNIEnv *env, jstring val);
+
 /*
  * Class:     com_sun_java_swing_plaf_gtk_GTKStyle
  * Method:    nativeGetXThickness
@@ -37,9 +40,9 @@
     JNIEnv *env, jclass klass, jint widget_type)
 {
     jint ret;
-    fp_gdk_threads_enter();
-    ret = gtk2_get_xthickness(env, widget_type);
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_enter();
+    ret = gtk->get_xthickness(env, widget_type);
+    gtk->gdk_threads_leave();
     return ret;
 }
 
@@ -53,9 +56,9 @@
     JNIEnv *env, jclass klass, jint widget_type)
 {
     jint ret;
-    fp_gdk_threads_enter();
-    ret = gtk2_get_ythickness(env, widget_type);
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_enter();
+    ret = gtk->get_ythickness(env, widget_type);
+    gtk->gdk_threads_leave();
     return ret;
 }
 
@@ -70,9 +73,9 @@
     jint state_type, jint type_id)
 {
     jint ret;
-    fp_gdk_threads_enter();
-    ret = gtk2_get_color_for_state(env, widget_type, state_type, type_id);
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_enter();
+    ret = gtk->get_color_for_state(env, widget_type, state_type, type_id);
+    gtk->gdk_threads_leave();
     return ret;
 }
 
@@ -86,9 +89,9 @@
     JNIEnv *env, jclass klass, jint widget_type, jstring key)
 {
     jobject ret;
-    fp_gdk_threads_enter();
-    ret = gtk2_get_class_value(env, widget_type, key);
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_enter();
+    ret = gtk->get_class_value(env, widget_type, getStrFor(env, key));
+    gtk->gdk_threads_leave();
     return ret;
 }
 
@@ -102,8 +105,8 @@
     JNIEnv *env, jclass klass, jint widget_type)
 {
     jstring ret;
-    fp_gdk_threads_enter();
-    ret = gtk2_get_pango_font_name(env, widget_type);
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_enter();
+    ret = gtk->get_pango_font_name(env, widget_type);
+    gtk->gdk_threads_leave();
     return ret;
 }
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/java2d/x11/XRBackendNative.c	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/java2d/x11/XRBackendNative.c	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, 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
@@ -72,8 +72,8 @@
 
 #include <dlfcn.h>
 
-#if defined(__solaris__) || defined(_AIX)
-/* Solaris 10 and AIX will not have these symbols at runtime */
+#if defined(__solaris__)
+/* Solaris 10 will not have these symbols at compile time */
 
 typedef Picture (*XRenderCreateLinearGradientFuncType)
                                      (Display *dpy,
@@ -147,7 +147,22 @@
         return JNI_FALSE;
     }
 
-#if defined(__solaris__) || defined(_AIX)
+#if defined(_AIX)
+    // On AIX we have to use a special syntax because the shared libraries are packed in
+    // multi-architecture archives. We first try to load the system default libXrender
+    // which is contained in the 'X11.base.lib' fileset starting with AIX 6.1
+    xrenderlib = dlopen("libXrender.a(shr_64.o)", RTLD_GLOBAL | RTLD_LAZY | RTLD_MEMBER);
+    if (xrenderlib == NULL) {
+      // If the latter wasn't successful, we also try to load the version under /opt/freeware
+      // This may be downloaded from the "AIX Toolbox for Linux Applications" even for AIX 5.3
+      xrenderlib = dlopen("libXrender.a(libXrender.so.0)", RTLD_GLOBAL | RTLD_LAZY | RTLD_MEMBER);
+    }
+    if (xrenderlib != NULL) {
+      dlclose(xrenderlib);
+    } else {
+      available = JNI_FALSE;
+    }
+#elif defined(__solaris__)
     xrenderlib = dlopen("libXrender.so",RTLD_GLOBAL|RTLD_LAZY);
     if (xrenderlib != NULL) {
 
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/XToolkit.c	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/XToolkit.c	Thu Apr 28 23:08:16 2016 -0700
@@ -354,7 +354,6 @@
 
 static void     waitForEvents(JNIEnv *, jlong);
 static void     awt_pipe_init();
-static void     processOneEvent(XtInputMask iMask);
 static Boolean  performPoll(JNIEnv *, jlong);
 static void     wakeUp();
 static void     update_poll_timeout(int timeout_control);
@@ -614,7 +613,7 @@
 } /* get_poll_timeout() */
 
 /*
- * Waits for X/Xt events to appear on the pipe. Returns only when
+ * Waits for X events to appear on the pipe. Returns only when
  * it is likely (but not definite) that there are events waiting to
  * be processed.
  *
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/awt_Desktop.c	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/awt_Desktop.c	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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,7 +24,7 @@
  */
 
 #include "jni_util.h"
-#include "gtk2_interface.h"
+#include "gtk_interface.h"
 #include "gnome_interface.h"
 
 static gboolean gtk_has_been_loaded = FALSE;
@@ -36,14 +36,14 @@
  * Signature: ()Z
  */
 JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XDesktopPeer_init
-  (JNIEnv *env, jclass cls)
+  (JNIEnv *env, jclass cls, jint version, jboolean verbose)
 {
 
     if (gtk_has_been_loaded || gnome_has_been_loaded) {
         return JNI_TRUE;
     }
 
-    if (gtk2_load(env) && gtk2_show_uri_load(env)) {
+    if (gtk_load(env, version, verbose) && gtk->show_uri_load(env)) {
         gtk_has_been_loaded = TRUE;
         return JNI_TRUE;
     } else if (gnome_load()) {
@@ -74,9 +74,9 @@
     }
 
     if (gtk_has_been_loaded) {
-        fp_gdk_threads_enter();
-        success = fp_gtk_show_uri(NULL, url_c, GDK_CURRENT_TIME, NULL);
-        fp_gdk_threads_leave();
+        gtk->gdk_threads_enter();
+        success = gtk->gtk_show_uri(NULL, url_c, GDK_CURRENT_TIME, NULL);
+        gtk->gdk_threads_leave();
     } else if (gnome_has_been_loaded) {
         success = (*gnome_url_show)(url_c, NULL);
     }
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/awt_Taskbar.c	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/awt_Taskbar.c	Thu Apr 28 23:08:16 2016 -0700
@@ -109,7 +109,7 @@
  * Signature: (Ljava/lang/String;)Z
  */
 JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XTaskbarPeer_init
-(JNIEnv *env, jclass cls, jstring jname) {
+(JNIEnv *env, jclass cls, jstring jname, jint version, jboolean verbose) {
     jclass clazz;
 
     jTaskbarCls = (*env)->NewGlobalRef(env, cls);
@@ -121,7 +121,7 @@
     CHECK_NULL_RETURN(
             jMenuItemGetLabel = (*env)->GetMethodID(env, clazz, "getLabel", "()Ljava/lang/String;"), JNI_FALSE);
 
-    if (gtk2_load(env) && unity_load()) {
+    if (gtk_load(env, version, verbose) && unity_load()) {
         const gchar* name = (*env)->GetStringUTFChars(env, jname, NULL);
         if (name) {
             entry = fp_unity_launcher_entry_get_for_desktop_file(name);
@@ -139,9 +139,9 @@
  */
 JNIEXPORT void JNICALL Java_sun_awt_X11_XTaskbarPeer_runloop
 (JNIEnv *env, jclass cls) {
-    fp_gdk_threads_enter();
-    fp_gtk_main();
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_enter();
+    gtk->gtk_main();
+    gtk->gdk_threads_leave();
 }
 
 /*
@@ -151,14 +151,14 @@
  */
 JNIEXPORT void JNICALL Java_sun_awt_X11_XTaskbarPeer_setBadge
 (JNIEnv *env, jobject obj, jlong value, jboolean visible) {
-    fp_gdk_threads_enter();
+    gtk->gdk_threads_enter();
     fp_unity_launcher_entry_set_count(entry, value);
     fp_unity_launcher_entry_set_count_visible(entry, visible);
     DbusmenuMenuitem* m;
     if (m = fp_unity_launcher_entry_get_quicklist(entry)) {
         fp_unity_launcher_entry_set_quicklist(entry, m);
     }
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_leave();
 }
 
 /*
@@ -168,13 +168,13 @@
  */
 JNIEXPORT void JNICALL Java_sun_awt_X11_XTaskbarPeer_setUrgent
 (JNIEnv *env, jobject obj, jboolean urgent) {
-    fp_gdk_threads_enter();
+    gtk->gdk_threads_enter();
     fp_unity_launcher_entry_set_urgent(entry, urgent);
     DbusmenuMenuitem* m;
     if (m = fp_unity_launcher_entry_get_quicklist(entry)) {
         fp_unity_launcher_entry_set_quicklist(entry, m);
     }
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_leave();
 }
 
 /*
@@ -184,14 +184,14 @@
  */
 JNIEXPORT void JNICALL Java_sun_awt_X11_XTaskbarPeer_updateProgress
 (JNIEnv *env, jobject obj, jdouble value, jboolean visible) {
-    fp_gdk_threads_enter();
+    gtk->gdk_threads_enter();
     fp_unity_launcher_entry_set_progress(entry, value);
     fp_unity_launcher_entry_set_progress_visible(entry, visible);
     DbusmenuMenuitem* m;
     if (m = fp_unity_launcher_entry_get_quicklist(entry)) {
         fp_unity_launcher_entry_set_quicklist(entry, m);
     }
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_leave();
 }
 
 void deleteGlobalRef(gpointer data) {
@@ -209,7 +209,7 @@
         }
         elem = (*env)->NewGlobalRef(env, elem);
 
-        globalRefs = fp_g_list_append(globalRefs, elem);
+        globalRefs = gtk->g_list_append(globalRefs, elem);
 
         jstring jlabel = (jstring) (*env)->CallObjectMethod(env, elem, jMenuItemGetLabel);
         if (!(*env)->ExceptionCheck(env) && jlabel) {
@@ -224,7 +224,8 @@
 
                 (*env)->ReleaseStringUTFChars(env, jlabel, label);
                 fp_dbusmenu_menuitem_child_append(menu, mi);
-                fp_g_signal_connect(mi, "item_activated", G_CALLBACK(callback), elem);
+                gtk->g_signal_connect_data(mi, "item_activated",
+                                           G_CALLBACK(callback), elem, NULL, 0);
             }
         }
     }
@@ -238,7 +239,7 @@
 JNIEXPORT void JNICALL Java_sun_awt_X11_XTaskbarPeer_setNativeMenu
 (JNIEnv *env, jobject obj, jobjectArray items) {
 
-    fp_gdk_threads_enter();
+    gtk->gdk_threads_enter();
 
     if (!menu) {
         menu = fp_dbusmenu_menuitem_new();
@@ -247,14 +248,14 @@
     fp_unity_launcher_entry_set_quicklist(entry, menu);
 
     GList* list = fp_dbusmenu_menuitem_take_children(menu);
-    fp_g_list_free_full(list, fp_g_object_unref);
+    gtk->g_list_free_full(list, gtk->g_object_unref);
 
-    fp_g_list_free_full(globalRefs, deleteGlobalRef);
+    gtk->g_list_free_full(globalRefs, deleteGlobalRef);
     globalRefs = NULL;
 
     if (items) {
         fill_menu(env, items);
     }
 
-    fp_gdk_threads_leave();
+    gtk->gdk_threads_leave();
 }
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/awt_Taskbar.h	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/awt_Taskbar.h	Thu Apr 28 23:08:16 2016 -0700
@@ -26,7 +26,7 @@
 #ifndef AWT_TASKBAR_H
 #define AWT_TASKBAR_H
 
-#include "gtk2_interface.h"
+#include "gtk_interface.h"
 
 typedef void UnityLauncherEntry;
 typedef void DbusmenuMenuitem;
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/gnome_interface.h	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/gnome_interface.h	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016 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,7 @@
 
 #ifndef _GNOME_INTERFACE_H
 #define _GNOME_INTERFACE_H
-#include "gtk2_interface.h"
+#include "gtk_interface.h"
 #include <dlfcn.h>
 #include <jvm_md.h>
 #include <jni.h>
--- a/jdk/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java	Thu Apr 28 23:08:16 2016 -0700
@@ -41,7 +41,6 @@
 import static sun.awt.shell.Win32ShellFolder2.*;
 import sun.awt.OSInfo;
 import sun.awt.util.ThreadGroupUtils;
-import sun.misc.ManagedLocalsThread;
 // NOTE: This class supersedes Win32ShellFolderManager, which was removed
 //       from distribution after version 1.4.2.
 
@@ -524,8 +523,9 @@
                 return null;
             });
             AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
-                Thread t = new ManagedLocalsThread(
-                        ThreadGroupUtils.getRootThreadGroup(), shutdownHook);
+                Thread t = new Thread(
+                        ThreadGroupUtils.getRootThreadGroup(), shutdownHook,
+                        "ShellFolder", 0, false);
                 Runtime.getRuntime().addShutdownHook(t);
                 return null;
             });
@@ -548,8 +548,9 @@
                   * which will not get GCed before VM exit.
                   * Make its parent the top-level thread group.
                   */
-                Thread thread = new ManagedLocalsThread(
-                        ThreadGroupUtils.getRootThreadGroup(), comRun, name);
+                Thread thread = new Thread(
+                        ThreadGroupUtils.getRootThreadGroup(), comRun, name,
+                        0, false);
                 thread.setDaemon(true);
                 return thread;
             });
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WComponentPeer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WComponentPeer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,6 @@
 import java.awt.peer.*;
 import java.awt.image.VolatileImage;
 import sun.awt.RepaintArea;
-import sun.awt.CausedFocusEvent;
 import sun.awt.image.SunVolatileImage;
 import sun.awt.image.ToolkitImage;
 import java.awt.image.BufferedImage;
@@ -321,7 +320,7 @@
                   WKeyboardFocusManagerPeer.shouldFocusOnClick((Component)target))
               {
                   WKeyboardFocusManagerPeer.requestFocusFor((Component)target,
-                                                            CausedFocusEvent.Cause.MOUSE_EVENT);
+                                                            FocusEvent.Cause.MOUSE_EVENT);
               }
               break;
         }
@@ -687,7 +686,7 @@
     @Override
     public boolean requestFocus(Component lightweightChild, boolean temporary,
                                 boolean focusedWindowChangeAllowed, long time,
-                                CausedFocusEvent.Cause cause)
+                                FocusEvent.Cause cause)
     {
         if (WKeyboardFocusManagerPeer.
             processSynchronousLightweightTransfer((Component)target, lightweightChild, temporary,
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WFileDialogPeer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WFileDialogPeer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, 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,6 +25,7 @@
 package sun.awt.windows;
 
 import java.awt.*;
+import java.awt.event.FocusEvent.Cause;
 import java.awt.dnd.DropTarget;
 import java.awt.peer.*;
 import java.io.File;
@@ -34,9 +35,7 @@
 import java.util.ResourceBundle;
 import java.util.MissingResourceException;
 import java.util.Vector;
-import sun.awt.CausedFocusEvent;
 import sun.awt.AWTAccessor;
-import sun.misc.ManagedLocalsThread;
 
 final class WFileDialogPeer extends WWindowPeer implements FileDialogPeer {
 
@@ -98,7 +97,7 @@
 
     @Override
     public void show() {
-        new ManagedLocalsThread(this::_show).start();
+        new Thread(null, this::_show, "FileDialog", 0, false).start();
     }
 
     @Override
@@ -283,7 +282,7 @@
     @Override
     public boolean requestFocus
          (Component lightweightChild, boolean temporary,
-          boolean focusedWindowChangeAllowed, long time, CausedFocusEvent.Cause cause)
+          boolean focusedWindowChangeAllowed, long time, Cause cause)
     {
         return false;
     }
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WKeyboardFocusManagerPeer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WKeyboardFocusManagerPeer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2016, 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
@@ -32,7 +32,7 @@
 import sun.awt.AWTAccessor;
 import sun.awt.AWTAccessor.ComponentAccessor;
 import sun.awt.KeyboardFocusManagerPeerImpl;
-import sun.awt.CausedFocusEvent;
+import java.awt.event.FocusEvent.Cause;
 
 final class WKeyboardFocusManagerPeer extends KeyboardFocusManagerPeerImpl {
     static native void setNativeFocusOwner(ComponentPeer peer);
@@ -75,7 +75,7 @@
                                        boolean temporary,
                                        boolean focusedWindowChangeAllowed,
                                        long time,
-                                       CausedFocusEvent.Cause cause)
+                                       Cause cause)
     {
         // TODO: do something to eliminate this forwarding
         return KeyboardFocusManagerPeerImpl.deliverFocus(lightweightChild,
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPageDialogPeer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPageDialogPeer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,8 +25,6 @@
 
 package sun.awt.windows;
 
-import sun.misc.ManagedLocalsThread;
-
 final class WPageDialogPeer extends WPrintDialogPeer {
 
     WPageDialogPeer(WPageDialog target) {
@@ -53,6 +51,6 @@
             }
             ((WPrintDialog)target).setVisible(false);
         };
-        new ManagedLocalsThread(runnable).start();
+        new Thread(null, runnable, "PageDialog", 0, false).start();
     }
 }
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPrintDialogPeer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPrintDialogPeer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, 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,13 +26,12 @@
 package sun.awt.windows;
 
 import java.awt.*;
+import java.awt.event.FocusEvent.Cause;
 import java.awt.peer.DialogPeer;
 import java.awt.peer.ComponentPeer;
 import java.awt.dnd.DropTarget;
 import java.util.Vector;
-import sun.awt.CausedFocusEvent;
 import sun.awt.AWTAccessor;
-import sun.misc.ManagedLocalsThread;
 
 class WPrintDialogPeer extends WWindowPeer implements DialogPeer {
 
@@ -78,7 +77,7 @@
             }
             ((WPrintDialog)target).setVisible(false);
         };
-        new ManagedLocalsThread(runnable).start();
+        new Thread(null, runnable, "PrintDialog", 0, false).start();
     }
 
     synchronized void setHWnd(long hwnd) {
@@ -154,7 +153,7 @@
     @Override
     public boolean requestFocus
          (Component lightweightChild, boolean temporary,
-          boolean focusedWindowChangeAllowed, long time, CausedFocusEvent.Cause cause)
+          boolean focusedWindowChangeAllowed, long time, Cause cause)
     {
 
         return false;
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java	Thu Apr 28 23:08:16 2016 -0700
@@ -52,7 +52,6 @@
 import sun.java2d.d3d.D3DRenderQueue;
 import sun.java2d.opengl.OGLRenderQueue;
 
-import sun.misc.ManagedLocalsThread;
 import sun.print.PrintJob2D;
 
 import java.awt.dnd.DragSource;
@@ -256,7 +255,7 @@
                 (PrivilegedAction<ThreadGroup>) ThreadGroupUtils::getRootThreadGroup);
         if (!startToolkitThread(this, rootTG)) {
             String name = "AWT-Windows";
-            Thread toolkitThread = new ManagedLocalsThread(rootTG, this, name);
+            Thread toolkitThread = new Thread(rootTG, this, name, 0, false);
             toolkitThread.setDaemon(true);
             toolkitThread.start();
         }
@@ -283,8 +282,9 @@
 
     private void registerShutdownHook() {
         AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
-            Thread shutdown = new ManagedLocalsThread(
-                    ThreadGroupUtils.getRootThreadGroup(), this::shutdown);
+            Thread shutdown = new Thread(
+                    ThreadGroupUtils.getRootThreadGroup(), this::shutdown,
+                    "ToolkitShutdown", 0, false);
             shutdown.setContextClassLoader(null);
             Runtime.getRuntime().addShutdownHook(shutdown);
             return null;
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, 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
@@ -300,11 +300,11 @@
         return getNativeWindowSize();
     }
 
-    public boolean requestWindowFocus(CausedFocusEvent.Cause cause) {
+    public boolean requestWindowFocus(FocusEvent.Cause cause) {
         if (!focusAllowedFor()) {
             return false;
         }
-        return requestWindowFocus(cause == CausedFocusEvent.Cause.MOUSE_EVENT);
+        return requestWindowFocus(cause == FocusEvent.Cause.MOUSE_EVENT);
     }
     private native boolean requestWindowFocus(boolean isMouseEventCause);
 
--- a/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java	Thu Apr 28 23:08:16 2016 -0700
@@ -49,7 +49,6 @@
 import sun.java2d.windows.GDIWindowSurfaceData;
 import sun.java2d.d3d.D3DSurfaceData.D3DWindowSurfaceData;
 import sun.java2d.windows.WindowsFlags;
-import sun.misc.ManagedLocalsThread;
 
 /**
  * This class handles rendering to the screen with the D3D pipeline.
@@ -99,8 +98,9 @@
                 done = true;
                 wakeUpUpdateThread();
             };
-            Thread shutdown = new ManagedLocalsThread(
-                    ThreadGroupUtils.getRootThreadGroup(), shutdownRunnable);
+            Thread shutdown = new Thread(
+                    ThreadGroupUtils.getRootThreadGroup(), shutdownRunnable,
+                    "ScreenUpdater", 0, false);
             shutdown.setContextClassLoader(null);
             try {
                 Runtime.getRuntime().addShutdownHook(shutdown);
@@ -348,8 +348,9 @@
         if (screenUpdater == null) {
             screenUpdater = AccessController.doPrivileged((PrivilegedAction<Thread>) () -> {
                 String name = "D3D Screen Updater";
-                Thread t = new ManagedLocalsThread(
-                        ThreadGroupUtils.getRootThreadGroup(), this, name);
+                Thread t = new Thread(
+                        ThreadGroupUtils.getRootThreadGroup(), this, name,
+                        0, false);
                 // REMIND: should it be higher?
                 t.setPriority(Thread.NORM_PRIORITY + 2);
                 t.setDaemon(true);
--- a/jdk/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,8 +25,6 @@
 
 package sun.print;
 
-import sun.misc.ManagedLocalsThread;
-
 import java.io.BufferedReader;
 import java.io.InputStream;
 import java.io.InputStreamReader;
@@ -99,7 +97,8 @@
                 return;
             }
             // start the printer listener thread
-            Thread thr = new ManagedLocalsThread(new PrinterChangeListener());
+            Thread thr = new Thread(null, new PrinterChangeListener(),
+                                    "PrinterListener", 0, false);
             thr.setDaemon(true);
             thr.start();
         } /* else condition ought to never happen! */
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Button.cpp	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Button.cpp	Thu Apr 28 23:08:16 2016 -0700
@@ -187,7 +187,7 @@
 AwtButton::NotifyListeners()
 {
     DoCallback("handleAction", "(JI)V", ::JVM_CurrentTimeMillis(NULL, 0),
-               (jint)AwtComponent::GetJavaModifiers());
+               (jint)AwtComponent::GetActionModifiers());
 }
 
 MsgRouting
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp	Thu Apr 28 23:08:16 2016 -0700
@@ -60,6 +60,7 @@
 #include <java_awt_Insets.h>
 #include <sun_awt_windows_WPanelPeer.h>
 #include <java_awt_event_InputEvent.h>
+#include <java_awt_event_ActionEvent.h>
 #include <java_awt_event_InputMethodEvent.h>
 #include <sun_awt_windows_WInputMethod.h>
 #include <java_awt_event_MouseEvent.h>
@@ -2587,6 +2588,27 @@
     return java_awt_event_KeyEvent_KEY_LOCATION_LEFT;
 }
 
+/* Returns Java ActionEvent modifieres.
+ * When creating ActionEvent, modifiers provided by ActionEvent
+ * class should be set.
+ */
+jint
+AwtComponent::GetActionModifiers()
+{
+    jint modifiers = GetJavaModifiers();
+
+    if (modifiers & java_awt_event_InputEvent_CTRL_DOWN_MASK) {
+        modifiers |= java_awt_event_ActionEvent_CTRL_MASK;
+    }
+    if (modifiers & java_awt_event_InputEvent_SHIFT_DOWN_MASK) {
+        modifiers |= java_awt_event_ActionEvent_SHIFT_MASK;
+    }
+    if (modifiers & java_awt_event_InputEvent_ALT_DOWN_MASK) {
+        modifiers |= java_awt_event_ActionEvent_ALT_MASK;
+    }
+    return modifiers;
+}
+
 /* Returns Java extended InputEvent modifieres.
  * Since ::GetKeyState returns current state and Java modifiers represent
  * state before event, modifier on changed key are inverted.
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.h	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.h	Thu Apr 28 23:08:16 2016 -0700
@@ -438,6 +438,7 @@
     static void InitDynamicKeyMapTable();
     static void BuildDynamicKeyMapTable();
     static jint GetJavaModifiers();
+    static jint GetActionModifiers();
     static jint GetButton(int mouseButton);
     static UINT GetButtonMK(int mouseButton);
     static UINT WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers, UINT character, BOOL isDeadKey);
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_List.cpp	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_List.cpp	Thu Apr 28 23:08:16 2016 -0700
@@ -536,7 +536,7 @@
             else if (notifyCode == LBN_DBLCLK) {
                 DoCallback("handleAction", "(IJI)V", nCurrentSelection,
                            ::JVM_CurrentTimeMillis(NULL, 0),
-                           (jint)AwtComponent::GetJavaModifiers());
+                           (jint)AwtComponent::GetActionModifiers());
             }
         }
     }
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_List.h	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_List.h	Thu Apr 28 23:08:16 2016 -0700
@@ -56,6 +56,7 @@
     }
     INLINE void Deselect(int pos) {
         if (isMultiSelect) {
+            SendListMessage(LB_SETCARETINDEX, pos, FALSE);
             SendListMessage(LB_SETSEL, FALSE, pos);
         }
         else {
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuItem.cpp	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuItem.cpp	Thu Apr 28 23:08:16 2016 -0700
@@ -667,7 +667,7 @@
         DoCallback("handleAction", "(Z)V", ((nState & MF_CHECKED) == 0));
     } else {
         DoCallback("handleAction", "(JI)V", ::JVM_CurrentTimeMillis(NULL, 0),
-                   (jint)AwtComponent::GetJavaModifiers());
+                   (jint)AwtComponent::GetActionModifiers());
     }
 }
 
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_TrayIcon.cpp	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_TrayIcon.cpp	Thu Apr 28 23:08:16 2016 -0700
@@ -409,7 +409,7 @@
         MSG msg;
         AwtComponent::InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);
         SendActionEvent(java_awt_event_ActionEvent_ACTION_PERFORMED, ::JVM_CurrentTimeMillis(NULL, 0),
-                        AwtComponent::GetJavaModifiers(), &msg);
+                        AwtComponent::GetActionModifiers(), &msg);
     }
     return mrConsume;
 }
@@ -425,7 +425,7 @@
         MSG msg;
         AwtComponent::InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);
         SendActionEvent(java_awt_event_ActionEvent_ACTION_PERFORMED, ::JVM_CurrentTimeMillis(NULL, 0),
-                        AwtComponent::GetJavaModifiers(), &msg);
+                        AwtComponent::GetActionModifiers(), &msg);
     }
     lastKeySelectTime = now;
 
@@ -442,7 +442,7 @@
         MSG msg;
         AwtComponent::InitMessage(&msg, lastMessage, flags, MAKELPARAM(x, y), x, y);
         SendActionEvent(java_awt_event_ActionEvent_ACTION_PERFORMED, ::JVM_CurrentTimeMillis(NULL, 0),
-                        AwtComponent::GetJavaModifiers(), &msg);
+                        AwtComponent::GetActionModifiers(), &msg);
     }
     return mrConsume;
 }
--- a/jdk/src/java.desktop/windows/native/libfontmanager/lcdglyph.c	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.desktop/windows/native/libfontmanager/lcdglyph.c	Thu Apr 28 23:08:16 2016 -0700
@@ -157,6 +157,9 @@
     if (hBitmap != 0) { \
         DeleteObject(hBitmap); \
     } \
+    if (tmpBitmap != 0) { \
+        DeleteObject(tmpBitmap); \
+    } \
     if (dibImage != NULL) { \
         free(dibImage); \
     } \
@@ -196,6 +199,7 @@
     int bmWidth, bmHeight;
     int x, y;
     HBITMAP hBitmap = NULL, hOrigBM;
+    HBITMAP tmpBitmap = NULL;
     int gamma, orient;
 
     HWND hWnd = NULL;
@@ -250,6 +254,12 @@
     }
     oldFont = SelectObject(hMemoryDC, hFont);
 
+    tmpBitmap = CreateCompatibleBitmap(hDesktopDC, 1, 1);
+    if (tmpBitmap == NULL) {
+        FREE_AND_RETURN;
+    }
+    hOrigBM = (HBITMAP)SelectObject(hMemoryDC, tmpBitmap);
+
     memset(&textMetric, 0, sizeof(TEXTMETRIC));
     err = GetTextMetrics(hMemoryDC, &textMetric);
     if (err == 0) {
@@ -334,7 +344,7 @@
     if (hBitmap == NULL) {
         FREE_AND_RETURN;
     }
-    hOrigBM = (HBITMAP)SelectObject(hMemoryDC, hBitmap);
+    SelectObject(hMemoryDC, hBitmap);
 
     /* Fill in black */
     rect.left = 0;
@@ -478,6 +488,7 @@
     ReleaseDC(hWnd, hDesktopDC);
     DeleteObject(hMemoryDC);
     DeleteObject(hBitmap);
+    DeleteObject(tmpBitmap);
 
     return ptr_to_jlong(glyphInfo);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/AsyncConnection.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2015, 2016, 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
+ */
+package java.net.http;
+
+import java.nio.ByteBuffer;
+import java.util.function.Consumer;
+
+/**
+ * Implemented by classes that offer an asynchronous interface.
+ *
+ * PlainHttpConnection, AsyncSSLConnection AsyncSSLDelegate.
+ *
+ * setAsyncCallbacks() is called to set the callback for reading
+ * and error notification. Reads all happen on the selector thread, which
+ * must not block.
+ *
+ * Writing uses the same write() methods as used in blocking mode.
+ * Queues are employed on the writing side to buffer data while it is waiting
+ * to be sent. This strategy relies on HTTP/2 protocol flow control to stop
+ * outgoing queue from continually growing. Writes can be initiated by the
+ * calling thread, but if socket becomes full then the queue is emptied by
+ * the selector thread
+ *
+ */
+interface AsyncConnection {
+
+    /**
+     * Enables asynchronous sending and receiving mode. The given async
+     * receiver will receive all incoming data. asyncInput() will be called
+     * to trigger reads. asyncOutput() will be called to drive writes.
+     *
+     * The errorReceiver callback must be called when any fatal exception
+     * occurs. Connection is assumed to be closed afterwards.
+     *
+     * @param asyncReceiver
+     * @param errorReceiver
+     */
+    void setAsyncCallbacks(
+            Consumer<ByteBuffer> asyncReceiver,
+            Consumer<Throwable> errorReceiver);
+
+    /**
+     * Does whatever is required to start reading. Usually registers
+     * an event with the selector thread.
+     */
+    void startReading();
+}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/AsyncEvent.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/AsyncEvent.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,24 +25,27 @@
 package java.net.http;
 
 import java.nio.channels.SelectableChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.SocketChannel;
 
 /**
  * Event handling interface from HttpClientImpl's selector.
  *
- * <p> If blockingChannel is true, then the channel will be put in blocking
+ * If BLOCKING is set, then the channel will be put in blocking
  * mode prior to handle() being called. If false, then it remains non-blocking.
+ *
+ * If REPEATING is set then the event is not cancelled after being posted.
  */
 abstract class AsyncEvent {
 
-    /**
-     * Implement this if channel should be made blocking before calling handle()
-     */
-    public interface Blocking { }
+    public static final int BLOCKING = 0x1; // non blocking if not set
+    public static final int REPEATING = 0x2; // one off event if not set
 
-    /**
-     * Implement this if channel should remain non-blocking before calling handle()
-     */
-    public interface NonBlocking { }
+    protected final int flags;
+
+    AsyncEvent(int flags) {
+        this.flags = flags;
+    }
 
     /** Returns the channel */
     public abstract SelectableChannel channel();
@@ -55,4 +58,12 @@
 
     /** Called when selector is shutting down. Abort all exchanges. */
     public abstract void abort();
+
+    public boolean blocking() {
+        return (flags & BLOCKING) != 0;
+    }
+
+    public boolean repeating() {
+        return (flags & REPEATING) != 0;
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/AsyncSSLConnection.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2015, 2016, 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
+ */
+package java.net.http;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Consumer;
+
+/**
+ * Asynchronous version of SSLConnection.
+ */
+class AsyncSSLConnection extends HttpConnection implements AsyncConnection {
+    final AsyncSSLDelegate sslDelegate;
+    final PlainHttpConnection delegate;
+
+    AsyncSSLConnection(InetSocketAddress addr, HttpClientImpl client, String[] ap) {
+        super(addr, client);
+        delegate = new PlainHttpConnection(addr, client);
+        sslDelegate = new AsyncSSLDelegate(delegate, client, ap);
+    }
+
+    @Override
+    public void connect() throws IOException, InterruptedException {
+        delegate.connect();
+    }
+
+    @Override
+    public CompletableFuture<Void> connectAsync() {
+        return delegate.connectAsync();
+    }
+
+    @Override
+    boolean connected() {
+        return delegate.connected();
+    }
+
+    @Override
+    boolean isSecure() {
+        return true;
+    }
+
+    @Override
+    boolean isProxied() {
+        return false;
+    }
+
+    @Override
+    SocketChannel channel() {
+        return delegate.channel();
+    }
+
+    @Override
+    ConnectionPool.CacheKey cacheKey() {
+        return ConnectionPool.cacheKey(address, null);
+    }
+
+    @Override
+    synchronized long write(ByteBuffer[] buffers, int start, int number) throws IOException {
+        ByteBuffer[] bufs = Utils.reduce(buffers, start, number);
+        long n = Utils.remaining(bufs);
+        sslDelegate.write(bufs);
+        return n;
+    }
+
+    @Override
+    long write(ByteBuffer buffer) throws IOException {
+        long n = buffer.remaining();
+        sslDelegate.write(buffer);
+        return n;
+    }
+
+    @Override
+    public void close() {
+        Utils.close(sslDelegate, delegate.channel());
+    }
+
+    @Override
+    public void setAsyncCallbacks(Consumer<ByteBuffer> asyncReceiver, Consumer<Throwable> errorReceiver) {
+        sslDelegate.setAsyncCallbacks(asyncReceiver, errorReceiver);
+        delegate.setAsyncCallbacks(sslDelegate::lowerRead, errorReceiver);
+    }
+
+    // Blocking read functions not used here
+
+    @Override
+    protected ByteBuffer readImpl(int length) throws IOException {
+        throw new UnsupportedOperationException("Not supported.");
+    }
+
+    @Override
+    protected int readImpl(ByteBuffer buffer) throws IOException {
+        throw new UnsupportedOperationException("Not supported.");
+    }
+
+    @Override
+    CompletableFuture<Void> whenReceivingResponse() {
+        throw new UnsupportedOperationException("Not supported.");
+    }
+
+    @Override
+    public void startReading() {
+        delegate.startReading();
+        sslDelegate.startReading();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/AsyncSSLDelegate.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,598 @@
+/*
+ * Copyright (c) 2015, 2016, 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
+ */
+package java.net.http;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.concurrent.ExecutorService;
+import java.util.function.Consumer;
+import static javax.net.ssl.SSLEngineResult.Status.*;
+import javax.net.ssl.*;
+import static javax.net.ssl.SSLEngineResult.HandshakeStatus.*;
+
+/**
+ * Asynchronous wrapper around SSLEngine. send and receive is fully non
+ * blocking. When handshaking is required, a thread is created to perform
+ * the handshake and application level sends do not take place during this time.
+ *
+ * Is implemented using queues and functions operating on the receiving end
+ * of each queue.
+ *
+ * Application writes to:
+ *        ||
+ *        \/
+ *     appOutputQ
+ *        ||
+ *        \/
+ * appOutputQ read by "upperWrite" method which does SSLEngine.wrap
+ * and writes to
+ *        ||
+ *        \/
+ *     channelOutputQ
+ *        ||
+ *        \/
+ * channelOutputQ is read by "lowerWrite" method which is invoked from
+ * OP_WRITE events on the socket (from selector thread)
+ *
+ * Reading side is as follows
+ * --------------------------
+ *
+ * "upperRead" method reads off channelInputQ and calls SSLEngine.unwrap and
+ * when decrypted data is returned, it is passed to the user's Consumer<ByteBuffer>
+ *        /\
+ *        ||
+ *     channelInputQ
+ *        /\
+ *        ||
+ * "lowerRead" method puts buffers into channelInputQ. It is invoked from
+ * OP_READ events from the selector.
+ *
+ * Whenever handshaking is required, the doHandshaking() method is called
+ * which creates a thread to complete the handshake. It takes over the
+ * channelInputQ from upperRead, and puts outgoing packets on channelOutputQ.
+ * Selector events are delivered to lowerRead and lowerWrite as normal.
+ *
+ * Errors
+ *
+ * Any exception thrown by the engine or channel, causes all Queues to be closed
+ * the channel to be closed, and the error is reported to the user's
+ * Consumer<Throwable>
+ */
+public class AsyncSSLDelegate implements Closeable, AsyncConnection {
+
+    // outgoing buffers put in this queue first and may remain here
+    // while SSL handshaking happening.
+    final Queue<ByteBuffer> appOutputQ;
+
+    // queue of wrapped ByteBuffers waiting to be sent on socket channel
+    //final Queue<ByteBuffer> channelOutputQ;
+
+    // Bytes read into this queue before being unwrapped. Backup on this
+    // Q should only happen when the engine is stalled due to delegated tasks
+    final Queue<ByteBuffer> channelInputQ;
+
+    // input occurs through the read() method which is expected to be called
+    // when the selector signals some data is waiting to be read. All incoming
+    // handshake data is handled in this method, which means some calls to
+    // read() may return zero bytes of user data. This is not a sign of spinning,
+    // just that the handshake mechanics are being executed.
+
+    final SSLEngine engine;
+    final SSLParameters sslParameters;
+    //final SocketChannel chan;
+    final HttpConnection lowerOutput;
+    final HttpClientImpl client;
+    final ExecutorService executor;
+    final BufferHandler bufPool;
+    Consumer<ByteBuffer> receiver;
+    Consumer<Throwable> errorHandler;
+    // Locks.
+    final Object reader = new Object();
+    final Object writer = new Object();
+    // synchronizing handshake state
+    final Object handshaker = new Object();
+    // flag set when reader or writer is blocked waiting for handshake to finish
+    boolean writerBlocked;
+    boolean readerBlocked;
+
+    // some thread is currently doing the handshake
+    boolean handshaking;
+
+    // alpn[] may be null. upcall is callback which receives incoming decoded bytes off socket
+
+    AsyncSSLDelegate(HttpConnection lowerOutput, HttpClientImpl client, String[] alpn)
+    {
+        SSLContext context = client.sslContext();
+        executor = client.executorService();
+        bufPool = client;
+        appOutputQ = new Queue<>();
+        appOutputQ.registerPutCallback(this::upperWrite);
+        //channelOutputQ = new Queue<>();
+        //channelOutputQ.registerPutCallback(this::lowerWrite);
+        engine = context.createSSLEngine();
+        engine.setUseClientMode(true);
+        SSLParameters sslp = client.sslParameters().orElse(null);
+        if (sslp == null) {
+            sslp = context.getSupportedSSLParameters();
+            //sslp = context.getDefaultSSLParameters();
+            //printParams(sslp);
+        }
+        sslParameters = Utils.copySSLParameters(sslp);
+        if (alpn != null) {
+            sslParameters.setApplicationProtocols(alpn);
+            Log.logSSL("Setting application protocols: " + Arrays.toString(alpn));
+        } else {
+            Log.logSSL("No application protocols proposed");
+        }
+        engine.setSSLParameters(sslParameters);
+        engine.setEnabledCipherSuites(sslp.getCipherSuites());
+        engine.setEnabledProtocols(sslp.getProtocols());
+        this.lowerOutput = lowerOutput;
+        this.client = client;
+        this.channelInputQ = new Queue<>();
+        this.channelInputQ.registerPutCallback(this::upperRead);
+    }
+
+    /**
+     * Put buffers to appOutputQ, and call upperWrite() if q was empty.
+     *
+     * @param src
+     */
+    public void write(ByteBuffer[] src) throws IOException {
+        appOutputQ.putAll(src);
+    }
+
+    public void write(ByteBuffer buf) throws IOException {
+        ByteBuffer[] a = new ByteBuffer[1];
+        a[0] = buf;
+        write(a);
+    }
+
+    @Override
+    public void close() {
+        Utils.close(appOutputQ, channelInputQ, lowerOutput);
+    }
+
+    /**
+     * Attempts to wrap buffers from appOutputQ and place them on the
+     * channelOutputQ for writing. If handshaking is happening, then the
+     * process stalls and last buffers taken off the appOutputQ are put back
+     * into it until handshaking completes.
+     *
+     * This same method is called to try and resume output after a blocking
+     * handshaking operation has completed.
+     */
+    private void upperWrite() {
+        try {
+            EngineResult r = null;
+            ByteBuffer[] buffers = appOutputQ.pollAll(Utils.EMPTY_BB_ARRAY);
+            int bytes = Utils.remaining(buffers);
+            while (bytes > 0) {
+                synchronized (writer) {
+                    r = wrapBuffers(buffers);
+                    int bytesProduced = r.bytesProduced();
+                    int bytesConsumed = r.bytesConsumed();
+                    bytes -= bytesConsumed;
+                    if (bytesProduced > 0) {
+                        // pass destination buffer to channelOutputQ.
+                        lowerOutput.write(r.destBuffer);
+                    }
+                    synchronized (handshaker) {
+                        if (r.handshaking()) {
+                            // handshaking is happening or is needed
+                            // so we put the buffers back on Q to process again
+                            // later. It's possible that some may have already
+                            // been processed, which is ok.
+                            appOutputQ.pushbackAll(buffers);
+                            writerBlocked = true;
+                            if (!handshaking()) {
+                                // execute the handshake in another thread.
+                                // This method will be called again to resume sending
+                                // later
+                                doHandshake(r);
+                            }
+                            return;
+                        }
+                    }
+                }
+            }
+            returnBuffers(buffers);
+        } catch (Throwable t) {
+            t.printStackTrace();
+            close();
+        }
+    }
+
+    private void doHandshake(EngineResult r) {
+        handshaking = true;
+        channelInputQ.registerPutCallback(null);
+        executor.execute(() -> {
+            try {
+                doHandshakeImpl(r);
+                channelInputQ.registerPutCallback(this::upperRead);
+            } catch (Throwable t) {
+                t.printStackTrace();
+                close();
+            }
+        });
+    }
+
+    private void returnBuffers(ByteBuffer[] bufs) {
+        for (ByteBuffer buf : bufs)
+            client.returnBuffer(buf);
+    }
+
+    /**
+     * Return true if some thread is currently doing the handshake
+     *
+     * @return
+     */
+    boolean handshaking() {
+        synchronized(handshaker) {
+            return handshaking;
+        }
+    }
+
+    /**
+     * Executes entire handshake in calling thread.
+     * Returns after handshake is completed or error occurs
+     * @param r
+     * @throws IOException
+     */
+    private void doHandshakeImpl(EngineResult r) throws IOException {
+        while (true) {
+            SSLEngineResult.HandshakeStatus status = r.handshakeStatus();
+            if (status == NEED_TASK) {
+                LinkedList<Runnable> tasks = obtainTasks();
+                for (Runnable task : tasks)
+                    task.run();
+                r = handshakeWrapAndSend();
+            } else if (status == NEED_WRAP) {
+                r = handshakeWrapAndSend();
+            } else if (status == NEED_UNWRAP) {
+                r = handshakeReceiveAndUnWrap();
+            }
+            if (!r.handshaking())
+                break;
+        }
+        boolean dowrite = false;
+        boolean doread = false;
+        // Handshake is finished. Now resume reading and/or writing
+        synchronized(handshaker) {
+            handshaking = false;
+            if (writerBlocked) {
+                writerBlocked = false;
+                dowrite = true;
+            }
+            if (readerBlocked) {
+                readerBlocked = false;
+                doread = true;
+            }
+        }
+        if (dowrite)
+            upperWrite();
+        if (doread)
+            upperRead();
+    }
+
+    // acknowledge a received CLOSE request from peer
+    void doClosure() throws IOException {
+        //while (!wrapAndSend(emptyArray))
+            //;
+    }
+
+    LinkedList<Runnable> obtainTasks() {
+        LinkedList<Runnable> l = new LinkedList<>();
+        Runnable r;
+        while ((r = engine.getDelegatedTask()) != null)
+            l.add(r);
+        return l;
+    }
+
+    @Override
+    public synchronized void setAsyncCallbacks(Consumer<ByteBuffer> asyncReceiver, Consumer<Throwable> errorReceiver) {
+        this.receiver = asyncReceiver;
+        this.errorHandler = errorReceiver;
+    }
+
+    @Override
+    public void startReading() {
+        // maybe this class does not need to implement AsyncConnection
+    }
+
+    static class EngineResult {
+        ByteBuffer destBuffer;
+        ByteBuffer srcBuffer;
+        SSLEngineResult result;
+        Throwable t;
+
+        boolean handshaking() {
+            SSLEngineResult.HandshakeStatus s = result.getHandshakeStatus();
+            return s != FINISHED && s != NOT_HANDSHAKING;
+        }
+
+        int bytesConsumed() {
+            return result.bytesConsumed();
+        }
+
+        int bytesProduced() {
+            return result.bytesProduced();
+        }
+
+        Throwable exception() {
+            return t;
+        }
+
+        SSLEngineResult.HandshakeStatus handshakeStatus() {
+            return result.getHandshakeStatus();
+        }
+
+        SSLEngineResult.Status status() {
+            return result.getStatus();
+        }
+    }
+
+    EngineResult handshakeWrapAndSend() throws IOException {
+        EngineResult r = wrapBuffer(Utils.EMPTY_BYTEBUFFER);
+        if (r.bytesProduced() > 0) {
+            lowerOutput.write(r.destBuffer);
+        }
+        return r;
+    }
+
+    // called during handshaking. It blocks until a complete packet
+    // is available, unwraps it and returns.
+    EngineResult handshakeReceiveAndUnWrap() throws IOException {
+        ByteBuffer buf = channelInputQ.take();
+        while (true) {
+            // block waiting for input
+            EngineResult r = unwrapBuffer(buf);
+            SSLEngineResult.Status status = r.status();
+            if (status == BUFFER_UNDERFLOW) {
+                // wait for another buffer to arrive
+                ByteBuffer buf1 = channelInputQ.take();
+                buf = combine (buf, buf1);
+                continue;
+            }
+            // OK
+            // theoretically possible we could receive some user data
+            if (r.bytesProduced() > 0) {
+                receiver.accept(r.destBuffer);
+            }
+            if (!buf.hasRemaining())
+                return r;
+        }
+    }
+
+    EngineResult wrapBuffer(ByteBuffer src) throws SSLException {
+        ByteBuffer[] bufs = new ByteBuffer[1];
+        bufs[0] = src;
+        return wrapBuffers(bufs);
+    }
+
+    EngineResult wrapBuffers(ByteBuffer[] src) throws SSLException {
+        EngineResult r = new EngineResult();
+        ByteBuffer dst = bufPool.getBuffer();
+        while (true) {
+            r.result = engine.wrap(src, dst);
+            switch (r.result.getStatus()) {
+                case BUFFER_OVERFLOW:
+                    dst = getPacketBuffer();
+                    break;
+                case CLOSED:
+                case OK:
+                    dst.flip();
+                    r.destBuffer = dst;
+                    return r;
+                case BUFFER_UNDERFLOW:
+                    // underflow handled externally
+                    bufPool.returnBuffer(dst);
+                    return r;
+                default:
+                    assert false;
+            }
+        }
+    }
+
+    EngineResult unwrapBuffer(ByteBuffer srcbuf) throws IOException {
+        EngineResult r = new EngineResult();
+        r.srcBuffer = srcbuf;
+
+        ByteBuffer dst = bufPool.getBuffer();
+        while (true) {
+            r.result = engine.unwrap(srcbuf, dst);
+            switch (r.result.getStatus()) {
+                case BUFFER_OVERFLOW:
+                    // dest buffer not big enough. Reallocate
+                    int oldcap = dst.capacity();
+                    dst = getApplicationBuffer();
+                    assert dst.capacity() > oldcap;
+                    break;
+                case CLOSED:
+                    doClosure();
+                    throw new IOException("Engine closed");
+                case BUFFER_UNDERFLOW:
+                    bufPool.returnBuffer(dst);
+                    return r;
+                case OK:
+                    dst.flip();
+                    r.destBuffer = dst;
+                    return r;
+            }
+        }
+    }
+
+    /**
+     * Asynchronous read input. Call this when selector fires.
+     * Unwrap done in upperRead because it also happens in
+     * doHandshake() when handshake taking place
+     */
+    public void lowerRead(ByteBuffer buffer) {
+        try {
+            channelInputQ.put(buffer);
+        } catch (Throwable t) {
+            close();
+            errorHandler.accept(t);
+        }
+    }
+
+    public void upperRead() {
+        EngineResult r;
+        ByteBuffer srcbuf;
+        synchronized (reader) {
+            try {
+                srcbuf = channelInputQ.poll();
+                if (srcbuf == null) {
+                    return;
+                }
+                while (true) {
+                    r = unwrapBuffer(srcbuf);
+                    switch (r.result.getStatus()) {
+                        case BUFFER_UNDERFLOW:
+                            // Buffer too small. Need to combine with next buf
+                            ByteBuffer nextBuf = channelInputQ.poll();
+                            if (nextBuf == null) {
+                                // no data available. push buffer back until more data available
+                                channelInputQ.pushback(srcbuf);
+                                return;
+                            } else {
+                                srcbuf = combine(srcbuf, nextBuf);
+                            }
+                            break;
+                        case OK:
+                            // check for any handshaking work
+                            synchronized (handshaker) {
+                                if (r.handshaking()) {
+                                    // handshaking is happening or is needed
+                                    // so we put the buffer back on Q to process again
+                                    // later.
+                                    channelInputQ.pushback(srcbuf);
+                                    readerBlocked = true;
+                                    if (!handshaking()) {
+                                        // execute the handshake in another thread.
+                                        // This method will be called again to resume sending
+                                        // later
+                                        doHandshake(r);
+                                    }
+                                    return;
+                                }
+                            }
+                            ByteBuffer dst = r.destBuffer;
+                            if (dst.hasRemaining()) {
+                                receiver.accept(dst);
+                            }
+                    }
+                    if (srcbuf.hasRemaining()) {
+                        continue;
+                    }
+                    srcbuf = channelInputQ.poll();
+                    if (srcbuf == null) {
+                        return;
+                    }
+                }
+            } catch (Throwable t) {
+                Utils.close(lowerOutput);
+                errorHandler.accept(t);
+            }
+        }
+    }
+
+    /**
+     * Get a new buffer that is the right size for application buffers.
+     *
+     * @return
+     */
+    ByteBuffer getApplicationBuffer() {
+        SSLSession session = engine.getSession();
+        int appBufsize = session.getApplicationBufferSize();
+        bufPool.setMinBufferSize(appBufsize);
+        return bufPool.getBuffer(appBufsize);
+    }
+
+    ByteBuffer getPacketBuffer() {
+        SSLSession session = engine.getSession();
+        int packetBufSize = session.getPacketBufferSize();
+        bufPool.setMinBufferSize(packetBufSize);
+        return bufPool.getBuffer(packetBufSize);
+    }
+
+    ByteBuffer combine(ByteBuffer buf1, ByteBuffer buf2) {
+        int avail1 = buf1.capacity() - buf1.remaining();
+        if (buf2.remaining() < avail1) {
+            buf1.compact();
+            buf1.put(buf2);
+            buf1.flip();
+            return buf1;
+        }
+        int newsize = buf1.remaining() + buf2.remaining();
+        ByteBuffer newbuf = bufPool.getBuffer(newsize);
+        newbuf.put(buf1);
+        newbuf.put(buf2);
+        newbuf.flip();
+        return newbuf;
+    }
+
+    SSLParameters getSSLParameters() {
+        return sslParameters;
+    }
+
+    static void printParams(SSLParameters p) {
+        System.out.println("SSLParameters:");
+        if (p == null) {
+            System.out.println("Null params");
+            return;
+        }
+        for (String cipher : p.getCipherSuites()) {
+                System.out.printf("cipher: %s\n", cipher);
+        }
+        for (String approto : p.getApplicationProtocols()) {
+                System.out.printf("application protocol: %s\n", approto);
+        }
+        for (String protocol : p.getProtocols()) {
+                System.out.printf("protocol: %s\n", protocol);
+        }
+        if (p.getServerNames() != null)
+        for (SNIServerName sname : p.getServerNames()) {
+                System.out.printf("server name: %s\n", sname.toString());
+        }
+    }
+
+    String getSessionInfo() {
+        StringBuilder sb = new StringBuilder();
+        String application = engine.getApplicationProtocol();
+        SSLSession sess = engine.getSession();
+        String cipher = sess.getCipherSuite();
+        String protocol = sess.getProtocol();
+        sb.append("Handshake complete alpn: ")
+                .append(application)
+                .append(", Cipher: ")
+                .append(cipher)
+                .append(", Protocol: ")
+                .append(protocol);
+        return sb.toString();
+    }
+}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/AuthenticationFilter.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/AuthenticationFilter.java	Thu Apr 28 23:08:16 2016 -0700
@@ -45,7 +45,7 @@
     static final int DEFAULT_RETRY_LIMIT = 3;
 
     static final int retry_limit = Utils.getIntegerNetProperty(
-            "sun.net.httpclient.auth.retrylimit", DEFAULT_RETRY_LIMIT);
+            "java.net.httpclient.auth.retrylimit", DEFAULT_RETRY_LIMIT);
 
     static final int UNAUTHORIZED = 401;
     static final int PROXY_UNAUTHORIZED = 407;
--- a/jdk/src/java.httpclient/share/classes/java/net/http/BufferHandler.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/BufferHandler.java	Thu Apr 28 23:08:16 2016 -0700
@@ -27,11 +27,23 @@
 import java.nio.ByteBuffer;
 
 /**
- * Implemented by buffer pools.
+ * Implemented by buffer pools. A buffer pool has a current buffer size
+ * (number of bytes in each buffer) which may increase over time.
  */
 interface BufferHandler {
 
-    ByteBuffer getBuffer();
+    default ByteBuffer getBuffer() {
+        return getBuffer(-1);
+    }
+
+    void setMinBufferSize(int size);
+
+    /**
+     * size == -1 means return any sized buffer. Any other value means
+     * @param size
+     * @return
+     */
+    ByteBuffer getBuffer(int size);
 
     void returnBuffer(ByteBuffer buffer);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/ByteBufferConsumer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2015, 2016, 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
+ */
+
+package java.net.http;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.function.Supplier;
+
+/**
+ * Takes a List<ByteBuffer> which is assumed to contain at least one HTTP/2
+ * frame and allows it to be processed supplying bytes, ints, shorts, byte[] etc.
+ * from the list. As each ByteBuffer is consumed it is removed from the List<>.
+ *
+ * NOTE. shorts and bytes returned are UNSIGNED ints
+ *
+ * When finished processing the frame, the List may be empty or may contain
+ * partially read or unread ByteBuffers. A new ByteBufferConsumer can be
+ * created with the List<>
+ */
+class ByteBufferConsumer {
+
+    ByteBuffer currentBuffer;
+
+    final List<ByteBuffer> buffers;
+    final ListIterator<ByteBuffer> iterator;
+    final Supplier<ByteBuffer> newBufferSupplier;
+
+    ByteBufferConsumer(List<ByteBuffer> buffers,
+                       Supplier<ByteBuffer> newBufferSupplier) {
+        this.buffers = buffers;
+        this.newBufferSupplier = newBufferSupplier;
+        this.iterator = buffers.listIterator();
+        if (!iterator.hasNext()) {
+            throw new IllegalArgumentException("Empty buffer list");
+        }
+        currentBuffer = iterator.next();
+    }
+
+    private void dump() {
+        int l = 0;
+        System.err.printf("ByteBufferConsumer:\n");
+        for (ByteBuffer buf : buffers) {
+            System.err.printf("\t%s\n", buf.toString());
+            l+= buf.remaining();
+        }
+        System.err.printf("BBC contains %d bytes\n", l);
+    }
+
+    private synchronized ByteBuffer getBuffer(boolean exception) throws IOException {
+        while (currentBuffer == null || !currentBuffer.hasRemaining()) {
+            if (currentBuffer != null) {
+                iterator.remove();
+            }
+            if (!iterator.hasNext()) {
+                currentBuffer = null;
+                if (exception) {
+                    throw new IOException ("Connection closed unexpectedly");
+                }
+                return null;
+            }
+            currentBuffer = iterator.next();
+        }
+        return currentBuffer;
+    }
+
+    // call this to check if the data has all been consumed
+
+    public boolean consumed() {
+        try {
+            return getBuffer(false) == null;
+        } catch (IOException e) {
+            /* CAN'T HAPPEN */
+            throw new InternalError();
+        }
+    }
+
+    public int getByte() throws IOException {
+        // TODO: what to do if connection is closed. Throw NPE?
+        ByteBuffer buf = getBuffer(true);
+        return buf.get() & 0xff;
+    }
+
+    public byte[] getBytes(int n) throws IOException {
+        return getBytes(n, null);
+    }
+
+    public byte[] getBytes(int n, byte[] buf) throws IOException {
+        if (buf == null) {
+            buf = new byte[n];
+        } else if (buf.length < n) {
+            throw new IllegalArgumentException("getBytes: buffer too small");
+        }
+        int offset = 0;
+        while (n > 0) {
+            ByteBuffer b = getBuffer(true);
+            int length = Math.min(n, b.remaining());
+            b.get(buf, offset, length);
+            offset += length;
+            n -= length;
+        }
+        return buf;
+    }
+
+    public int getShort() throws IOException {
+        ByteBuffer buf = getBuffer(true);
+        int rem = buf.remaining();
+        if (rem >= 2) {
+            return buf.getShort() & 0xffff;
+        }
+        // Slow path. Not common
+        int val = 0;
+        val = (val << 8) + getByte();
+        val = (val << 8) + getByte();
+        return val;
+    }
+
+    public int getInt() throws IOException {
+        ByteBuffer buf = getBuffer(true);
+        int rem = buf.remaining();
+        if (rem >= 4) {
+            return buf.getInt();
+        }
+        // Slow path. Not common
+        int val = 0;
+        for (int nbytes = 0; nbytes < 4; nbytes++) {
+            val = (val << 8) + getByte();
+        }
+        return val;
+    }
+
+    private static final ByteBuffer[] EMPTY = new ByteBuffer[0];
+
+    /**
+     * Extracts whatever number of ByteBuffers from list to get required number
+     * of bytes. Any remaining buffers are 'tidied up' so reading can continue.
+     */
+    public ByteBuffer[] getBuffers(int bytecount) throws IOException {
+        LinkedList<ByteBuffer> l = new LinkedList<>();
+        while (bytecount > 0) {
+            ByteBuffer buffer = getBuffer(true);
+            int remaining = buffer.remaining();
+            if (remaining > bytecount) {
+                int difference = remaining - bytecount;
+                // split
+                ByteBuffer newb = newBufferSupplier.get();
+                newb.clear();
+                int limit = buffer.limit();
+                buffer.limit(limit - difference);
+                newb.put(buffer);
+                newb.flip();
+                buffer.limit(limit);
+                l.add(newb);
+                bytecount = 0;
+            } else {
+                l.add(buffer);
+                currentBuffer = null;
+                iterator.remove();
+                bytecount -= remaining;
+            }
+        }
+        return l.toArray(EMPTY);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/ByteBufferGenerator.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2015, 2016, 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
+ */
+
+package java.net.http;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+
+/**
+ * Manages a ByteBuffer[] for writing frames into for output. The last
+ * ByteBuffer in the list is always unflipped (able to receive more bytes for
+ * sending) until getBufferArray() is called, which calls finish().
+ *
+ * This allows multiple frames to be written to the same BBG.
+ *
+ * Buffers added with addByteBuffer() must be already flipped.
+ */
+class ByteBufferGenerator {
+
+    ByteBuffer currentBuffer;
+    // source is assumed to always return the same sized buffer
+    final BufferHandler pool;
+    final ArrayList<ByteBuffer> buflist;
+    final int bufsize;
+    boolean finished;
+
+    ByteBufferGenerator(BufferHandler pool) {
+        this.buflist = new ArrayList<>();
+        this.pool = pool;
+        this.currentBuffer = pool.getBuffer();
+        this.bufsize = currentBuffer.capacity();
+    }
+
+    private static final ByteBuffer[] EMPTY = new ByteBuffer[0];
+
+    public ByteBuffer[] getBufferArray() {
+        finish();
+        return buflist.toArray(EMPTY);
+    }
+
+    public ArrayList<ByteBuffer> getBufferList() {
+        finish();
+        return buflist;
+    }
+
+    private synchronized void finish() {
+        if (finished) {
+            return;
+        }
+        finished = true;
+        currentBuffer.flip();
+        if (currentBuffer.hasRemaining()) {
+            buflist.add(currentBuffer);
+        } else {
+            pool.returnBuffer(currentBuffer);
+        }
+    }
+
+    // only used for SettingsFrame: offset is number of bytes to
+    // ignore at start (we only want the payload of the settings frame)
+    public byte[] asByteArray(int offset) {
+        ByteBuffer[] bufs = getBufferArray();
+        int size = 0;
+        for (ByteBuffer buf : bufs) {
+            size += buf.remaining();
+        }
+        byte[] bytes = new byte[size-offset];
+        int pos = 0;
+        for (ByteBuffer buf : bufs) {
+            int rem = buf.remaining();
+            int ignore = Math.min(rem, offset);
+            buf.position(buf.position()+ignore);
+            rem -= ignore;
+            offset -= ignore;
+            buf.get(bytes, pos, rem);
+            pos += rem;
+        }
+        return bytes;
+    }
+
+    ByteBuffer getBuffer(long n) {
+        if (currentBuffer.remaining() < n) {
+            getNewBuffer();
+            if (n > currentBuffer.capacity()) {
+                throw new IllegalArgumentException("requested buffer too large");
+            }
+        }
+        return currentBuffer;
+    }
+
+    void getNewBuffer() {
+        currentBuffer.flip();
+        if (currentBuffer.hasRemaining()) {
+            buflist.add(currentBuffer);
+        } else {
+            pool.returnBuffer(currentBuffer);
+        }
+        currentBuffer = pool.getBuffer();
+    }
+
+    void addByteBuffer(ByteBuffer buf) {
+        getNewBuffer();
+        buflist.add(buf);
+    }
+
+    void addPadding(int length) {
+        while (length > 0) {
+            int n = Math.min(length, bufsize);
+            ByteBuffer b = getBuffer(n);
+            // TODO: currently zeroed?
+            b.position(b.position() + n);
+            length -= n;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/CharsetToolkit.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2016, 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
+ */
+package java.net.http;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CoderResult;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+// The purpose of this class is to separate charset-related tasks from the main
+// WebSocket logic, simplifying where possible.
+//
+//     * Coders hide the differences between coding and flushing stages on the
+//       API level
+//     * Verifier abstracts the way the verification is performed
+//       (spoiler: it's a decoding into a throw-away buffer)
+//
+// Coding methods throw exceptions instead of returning coding result denoting
+// errors, since any kind of handling and recovery is not expected.
+final class CharsetToolkit {
+
+    private CharsetToolkit() { }
+
+    static final class Verifier {
+
+        private final CharsetDecoder decoder = UTF_8.newDecoder();
+        // A buffer used to check validity of UTF-8 byte stream by decoding it.
+        // The contents of this buffer are never used.
+        // The size is arbitrary, though it should probably be chosen from the
+        // performance perspective since it affects the total number of calls to
+        // decoder.decode() and amount of work in each of these calls
+        private final CharBuffer blackHole = CharBuffer.allocate(1024);
+
+        void verify(ByteBuffer in, boolean endOfInput)
+                throws CharacterCodingException {
+            while (true) {
+                // Since decoder.flush() cannot produce an error, it's not
+                // helpful for verification. Therefore this step is skipped.
+                CoderResult r = decoder.decode(in, blackHole, endOfInput);
+                if (r.isOverflow()) {
+                    blackHole.clear();
+                } else if (r.isUnderflow()) {
+                    break;
+                } else if (r.isError()) {
+                    r.throwException();
+                } else {
+                    // Should not happen
+                    throw new InternalError();
+                }
+            }
+        }
+
+        Verifier reset() {
+            decoder.reset();
+            return this;
+        }
+    }
+
+    static final class Encoder {
+
+        private final CharsetEncoder encoder = UTF_8.newEncoder();
+        private boolean coding = true;
+
+        CoderResult encode(CharBuffer in, ByteBuffer out, boolean endOfInput)
+                throws CharacterCodingException {
+
+            if (coding) {
+                CoderResult r = encoder.encode(in, out, endOfInput);
+                if (r.isOverflow()) {
+                    return r;
+                } else if (r.isUnderflow()) {
+                    if (endOfInput) {
+                        coding = false;
+                    } else {
+                        return r;
+                    }
+                } else if (r.isError()) {
+                    r.throwException();
+                } else {
+                    // Should not happen
+                    throw new InternalError();
+                }
+            }
+            assert !coding;
+            return encoder.flush(out);
+        }
+
+        Encoder reset() {
+            coding = true;
+            encoder.reset();
+            return this;
+        }
+    }
+
+    static CharBuffer decode(ByteBuffer in) throws CharacterCodingException {
+        return UTF_8.newDecoder().decode(in);
+    }
+
+    static final class Decoder {
+
+        private final CharsetDecoder decoder = UTF_8.newDecoder();
+        private boolean coding = true; // Either coding or flushing
+
+        CoderResult decode(ByteBuffer in, CharBuffer out, boolean endOfInput)
+                throws CharacterCodingException {
+
+            if (coding) {
+                CoderResult r = decoder.decode(in, out, endOfInput);
+                if (r.isOverflow()) {
+                    return r;
+                } else if (r.isUnderflow()) {
+                    if (endOfInput) {
+                        coding = false;
+                    } else {
+                        return r;
+                    }
+                } else if (r.isError()) {
+                    r.throwException();
+                } else {
+                    // Should not happen
+                    throw new InternalError();
+                }
+            }
+            assert !coding;
+            return decoder.flush(out);
+        }
+
+        Decoder reset() {
+            coding = true;
+            decoder.reset();
+            return this;
+        }
+    }
+}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/ConnectionPool.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/ConnectionPool.java	Thu Apr 28 23:08:16 2016 -0700
@@ -35,7 +35,7 @@
 class ConnectionPool {
 
     static final long KEEP_ALIVE = Utils.getIntegerNetProperty(
-            "sun.net.httpclient.keepalive.timeout", 1200); // seconds
+            "java.net.httpclient.keepalive.timeout", 1200); // seconds
 
     // Pools of idle connections
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/ContinuationFrame.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2015, 2016, 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
+ */
+
+package java.net.http;
+
+import java.io.IOException;
+
+class ContinuationFrame extends HeaderFrame {
+
+    public static final int TYPE = 0x9;
+
+    ContinuationFrame() {
+        type = TYPE;
+    }
+
+    @Override
+    void readIncomingImpl(ByteBufferConsumer bc) throws IOException {
+        headerBlocks = bc.getBuffers(length);
+    }
+
+    @Override
+    void writeOutgoing(ByteBufferGenerator bg) {
+        super.writeOutgoing(bg);
+        for (int i=0; i<headerBlocks.length; i++) {
+            bg.addByteBuffer(headerBlocks[i]);
+        }
+    }
+
+    @Override
+    public boolean endHeaders() {
+        return getFlag(END_HEADERS);
+    }
+
+    @Override
+    void computeLength() {
+        length = headerLength;
+    }
+}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/CookieFilter.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/CookieFilter.java	Thu Apr 28 23:08:16 2016 -0700
@@ -44,7 +44,7 @@
     @Override
     public void request(HttpRequestImpl r) throws IOException {
         Map<String,List<String>> userheaders, cookies;
-        userheaders = r.getUserHeaders().directMap();
+        userheaders = r.getUserHeaders().map();
         cookies = cookieMan.get(r.uri(), userheaders);
         // add the returned cookies
         HttpHeadersImpl systemHeaders = r.getSystemHeaders();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/DataFrame.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2015, 2016, 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
+ */
+
+package java.net.http;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+class DataFrame extends Http2Frame {
+
+    public final static int TYPE = 0x0;
+
+    DataFrame() {
+        type = TYPE;
+    }
+
+    // Flags
+    public static final int END_STREAM = 0x1;
+    public static final int PADDED = 0x8;
+
+    int padLength;
+    int dataLength;
+    ByteBuffer[] data;
+
+    public void setData(ByteBuffer[] data) {
+        this.data = data;
+        setDataLength();
+    }
+
+    @Override
+    String flagAsString(int flag) {
+        switch (flag) {
+        case END_STREAM:
+            return "END_STREAM";
+        case PADDED:
+            return "PADDED";
+        }
+        return super.flagAsString(flag);
+    }
+
+    public synchronized void setData(ByteBuffer data) {
+        ByteBuffer[] bb;
+        if (data == null) {
+            bb = new ByteBuffer[0];
+        } else {
+            bb = new ByteBuffer[1];
+            bb[0] = data;
+        }
+        setData(bb);
+    }
+
+    public synchronized ByteBuffer[] getData() {
+        return data;
+    }
+
+    private void setDataLength() {
+        int len = 0;
+        for (ByteBuffer buf : data) {
+            len += buf.remaining();
+        }
+        dataLength = len;
+    }
+
+    @Override
+    void readIncomingImpl(ByteBufferConsumer bc) throws IOException {
+        if ((flags & PADDED) != 0) {
+            padLength = bc.getByte();
+            dataLength = length - (padLength + 1);
+        } else {
+            dataLength = length;
+        }
+        data = bc.getBuffers(dataLength);
+    }
+
+    int getPadLength() {
+        return padLength;
+    }
+
+    int getDataLength() {
+        return dataLength;
+    }
+
+    @Override
+    void writeOutgoing(ByteBufferGenerator bg) {
+        super.writeOutgoing(bg);
+        if ((flags & PADDED) != 0) {
+            ByteBuffer buf = bg.getBuffer(1);
+            buf.put((byte)getPadLength());
+        }
+        for (int i=0; i<data.length; i++) {
+            bg.addByteBuffer(data[i]);
+        }
+        if ((flags & PADDED) != 0) {
+            bg.addPadding(padLength);
+        }
+    }
+
+    @Override
+    void computeLength() {
+        length = dataLength;
+        if ((flags & PADDED) != 0) {
+            length += (1 + padLength);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/ErrorFrame.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2015, 2016, 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
+ */
+
+package java.net.http;
+
+abstract class ErrorFrame extends Http2Frame {
+
+    // error codes
+    public static final int NO_ERROR = 0x0;
+    public static final int PROTOCOL_ERROR = 0x1;
+    public static final int INTERNAL_ERROR = 0x2;
+    public static final int FLOW_CONTROL_ERROR = 0x3;
+    public static final int SETTINGS_TIMEOUT = 0x4;
+    public static final int STREAM_CLOSED = 0x5;
+    public static final int FRAME_SIZE_ERROR = 0x6;
+    public static final int REFUSED_STREAM = 0x7;
+    public static final int CANCEL = 0x8;
+    public static final int COMPRESSION_ERROR = 0x9;
+    public static final int CONNECT_ERROR = 0xa;
+    public static final int ENHANCE_YOUR_CALM = 0xb;
+    public static final int INADEQUATE_SECURITY = 0xc;
+    public static final int HTTP_1_1_REQUIRED = 0xd;
+    static final int LAST_ERROR = 0xd;
+
+    static final String[] errorStrings = {
+        "Not an error",
+        "Protocol error",
+        "Internal error",
+        "Flow control error",
+        "Settings timeout",
+        "Stream is closed",
+        "Frame size error",
+        "Stream not processed",
+        "Stream cancelled",
+        "Compression state not updated",
+        "TCP Connection error on CONNECT",
+        "Processing capacity exceeded",
+        "Negotiated TLS parameters not acceptable",
+        "Use HTTP/1.1 for request"
+    };
+
+    public static String stringForCode(int code) {
+        if (code < 0)
+            throw new IllegalArgumentException();
+
+        if (code > LAST_ERROR) {
+            return "Error: " + Integer.toString(code);
+        } else {
+            return errorStrings[code];
+        }
+    }
+
+    int errorCode;
+
+    @Override
+    public String toString() {
+        return super.toString() + " Error: " + stringForCode(errorCode);
+    }
+
+    public int getErrorCode() {
+        return this.errorCode;
+    }
+
+    public void setErrorCode(int errorCode) {
+        this.errorCode = errorCode;
+    }
+}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/Exchange.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/Exchange.java	Thu Apr 28 23:08:16 2016 -0700
@@ -128,7 +128,7 @@
         }
     }
 
-    HttpResponseImpl responseImpl0(HttpConnection connection)
+    private HttpResponseImpl responseImpl0(HttpConnection connection)
         throws IOException, InterruptedException
     {
         exchImpl = ExchangeImpl.get(this, connection);
@@ -136,7 +136,7 @@
             request.addSystemHeader("Expect", "100-Continue");
             exchImpl.sendHeadersOnly();
             HttpResponseImpl resp = exchImpl.getResponse();
-            logResponse(resp);
+            Utils.logResponse(resp);
             if (resp.statusCode() != 100) {
                 return resp;
             }
@@ -145,7 +145,7 @@
         } else {
             exchImpl.sendRequest();
             HttpResponseImpl resp = exchImpl.getResponse();
-            logResponse(resp);
+            Utils.logResponse(resp);
             return checkForUpgrade(resp, exchImpl);
         }
     }
@@ -163,9 +163,7 @@
         }
         SecurityException e = securityCheck(acc);
         if (e != null) {
-            CompletableFuture<HttpResponseImpl> cf = new CompletableFuture<>();
-            cf.completeExceptionally(e);
-            return cf;
+            return CompletableFuture.failedFuture(e);
         }
         if (permissions.size() > 0) {
             return AccessController.doPrivileged(
@@ -182,9 +180,7 @@
         try {
             exchImpl = ExchangeImpl.get(this, connection);
         } catch (IOException | InterruptedException e) {
-            CompletableFuture<HttpResponseImpl> cf = new CompletableFuture<>();
-            cf.completeExceptionally(e);
-            return cf;
+            return CompletableFuture.failedFuture(e);
         }
         if (request.expectContinue()) {
             request.addSystemHeader("Expect", "100-Continue");
@@ -200,23 +196,19 @@
                             return exchImpl.sendBodyAsync()
                                 .thenCompose(exchImpl::getResponseAsync)
                                 .thenApply((r) -> {
-                                    logResponse(r);
+                                    Utils.logResponse(r);
                                     return r;
                                 });
                         } else {
                             Exchange.this.response = r1;
-                            logResponse(r1);
+                            Utils.logResponse(r1);
                             return CompletableFuture.completedFuture(r1);
                         }
                     });
         } else {
             return exchImpl
-                .sendHeadersAsync()
-                .thenCompose((Void v) -> {
-                    // send body and get response at same time
-                    return exchImpl.sendBodyAsync()
-                                   .thenCompose(exchImpl::getResponseAsync);
-                })
+                .sendRequestAsync()
+                .thenCompose(exchImpl::getResponseAsync)
                 .thenCompose((HttpResponseImpl r1) -> {
                     int rcode = r1.statusCode();
                     CompletableFuture<HttpResponseImpl> cf =
@@ -225,13 +217,13 @@
                         return cf;
                     } else {
                         Exchange.this.response = r1;
-                        logResponse(r1);
+                        Utils.logResponse(r1);
                         return CompletableFuture.completedFuture(r1);
                     }
                 })
                 .thenApply((HttpResponseImpl response) -> {
                     this.response = response;
-                    logResponse(response);
+                    Utils.logResponse(response);
                     return response;
                 });
         }
@@ -254,9 +246,9 @@
                                                  client.client2(),
                                                  this)
                         .thenCompose((Http2Connection c) -> {
+                            c.putConnection();
                             Stream s = c.getStream(1);
                             exchImpl = s;
-                            c.putConnection();
                             return s.getResponseAsync(null);
                         })
                 );
@@ -294,21 +286,6 @@
     }
 
 
-    private void logResponse(HttpResponseImpl r) {
-        if (!Log.requests())
-            return;
-        StringBuilder sb = new StringBuilder();
-        String method = r.request().method();
-        URI uri = r.uri();
-        String uristring = uri == null ? "" : uri.toString();
-        sb.append('(')
-          .append(method)
-          .append(" ")
-          .append(uristring)
-          .append(") ")
-          .append(Integer.toString(r.statusCode()));
-        Log.logResponse(sb.toString());
-    }
 
     <T> CompletableFuture<T> responseBodyAsync(HttpResponse.BodyProcessor<T> processor) {
         return exchImpl.responseBodyAsync(processor);
@@ -352,9 +329,9 @@
         }
 
         String method = request.method();
-        HttpHeadersImpl userHeaders = request.getUserHeaders();
+        HttpHeaders userHeaders = request.getUserHeaders();
         URI u = getURIForSecurityCheck();
-        URLPermission p = Utils.getPermission(u, method, userHeaders.directMap());
+        URLPermission p = Utils.getPermission(u, method, userHeaders.map());
 
         try {
             assert acc != null;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/FrameReader.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,70 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package java.net.http;
+
+import java.nio.ByteBuffer;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Represents one frame. May be initialized with a leftover buffer from previous
+ * frame. Call {@code haveFrame()} to determine if buffers contains at least one
+ * frame. If false, the obtain another buffer and call {@code}input(ByteBuffer)}.
+ * There may be additional bytes at end of the frame list.
+ */
+class FrameReader {
+
+    final List<ByteBuffer> buffers;
+
+    FrameReader() {
+        buffers = new LinkedList<>();
+    }
+
+    FrameReader(FrameReader that) {
+        this.buffers = that.buffers;
+    }
+
+    FrameReader(ByteBuffer remainder) {
+        buffers = new LinkedList<>();
+        if (remainder != null) {
+            buffers.add(remainder);
+        }
+    }
+
+    public synchronized void input(ByteBuffer buffer) {
+        buffers.add(buffer);
+    }
+
+    public synchronized boolean haveFrame() {
+        //buffers = Utils.superCompact(buffers, () -> ByteBuffer.allocate(Utils.BUFSIZE));
+        int size = 0;
+        for (ByteBuffer buffer : buffers) {
+            size += buffer.remaining();
+        }
+        if (size < 3) {
+            return false; // don't have length yet
+        }
+        // we at least have length field
+        int length = 0;
+        int j = 0;
+        ByteBuffer b = buffers.get(j);
+        b.mark();
+        for (int i=0; i<3; i++) {
+            while (!b.hasRemaining()) {
+                b.reset();
+                b = buffers.get(++j);
+                b.mark();
+            }
+            length = (length << 8) + (b.get() & 0xff);
+        }
+        b.reset();
+        return (size >= length + 9); // frame length
+    }
+
+    synchronized List<ByteBuffer> frame() {
+        return buffers;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/GoAwayFrame.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2015, 2016, 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
+ */
+
+package java.net.http;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+class GoAwayFrame extends ErrorFrame {
+
+    GoAwayFrame() {
+        type = TYPE;
+    }
+
+    int lastStream;
+    byte[] debugData = new byte[0];
+
+    public static final int TYPE = 0x7;
+
+    // Flags
+    public static final int ACK = 0x1;
+
+    public void setDebugData(byte[] debugData) {
+        this.debugData = debugData;
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + " Debugdata: " + new String(debugData);
+    }
+
+    @Override
+    String flagAsString(int flag) {
+        switch (flag) {
+        case ACK:
+            return "ACK";
+        }
+        return super.flagAsString(flag);
+    }
+
+    public void setLastStream(int lastStream) {
+        this.lastStream = lastStream;
+    }
+
+    public int getLastStream() {
+        return this.lastStream;
+    }
+
+    public byte[] getDebugData() {
+        return debugData;
+    }
+
+    @Override
+    void readIncomingImpl(ByteBufferConsumer bc) throws IOException {
+        if (length < 8) {
+            throw new IOException("Invalid GoAway frame");
+        }
+        lastStream = bc.getInt() & 0x7fffffff;
+        errorCode = bc.getInt();
+        //debugData = bc.getBytes(8);
+        int datalen = length - 8;
+        if (datalen > 0) {
+            debugData = bc.getBytes(datalen);
+            Log.logError("GoAway debugData " + new String(debugData));
+        }
+    }
+
+    @Override
+    void writeOutgoing(ByteBufferGenerator bg) {
+        super.writeOutgoing(bg);
+        ByteBuffer buf = bg.getBuffer(length);
+        buf.putInt(lastStream);
+        buf.putInt(errorCode);
+        if (length > 8) {
+            buf.put(debugData);
+        }
+    }
+
+    @Override
+    void computeLength() {
+        length = 8 + debugData.length;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/HeaderFrame.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2015, 2016, 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
+ */
+
+package java.net.http;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Either a HeadersFrame or a ContinuationFrame
+ */
+abstract class HeaderFrame extends Http2Frame {
+
+    int offset;
+    int number;
+    int headerLength;
+    ByteBuffer[] headerBlocks;
+
+    public static final int END_HEADERS = 0x4;
+
+    @Override
+    String flagAsString(int flag) {
+        switch (flag) {
+        case END_HEADERS:
+            return "END_HEADERS";
+        }
+        return super.flagAsString(flag);
+    }
+
+    /**
+     * Sets the array of hpack encoded ByteBuffers
+     */
+    public void setHeaderBlock(ByteBuffer bufs[], int offset, int number) {
+        this.headerBlocks = bufs;
+        this.offset = offset;
+        this.number = number;
+        int length = 0;
+        for (int i=offset; i<offset+number; i++) {
+            length += headerBlocks[i].remaining();
+        }
+        this.headerLength = length;
+    }
+
+    public void setHeaderBlock(ByteBuffer bufs[]) {
+        setHeaderBlock(bufs, 0, bufs.length);
+    }
+
+    public ByteBuffer[] getHeaderBlock() {
+        return headerBlocks;
+    }
+
+    /**
+     * Returns true if this block is the final block of headers
+     */
+    public abstract boolean endHeaders();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/HeadersFrame.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2015, 2016, 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
+ */
+
+package java.net.http;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+class HeadersFrame extends HeaderFrame {
+
+    public final static int TYPE = 0x1;
+
+    // Flags
+    public static final int END_STREAM = 0x1;
+    public static final int PADDED = 0x8;
+    public static final int PRIORITY = 0x20;
+
+
+    int padLength;
+    int streamDependency;
+    int weight;
+    boolean exclusive;
+
+    HeadersFrame() {
+        type = TYPE;
+    }
+
+    @Override
+    String flagAsString(int flag) {
+        switch (flag) {
+            case END_STREAM:
+                return "END_STREAM";
+            case PADDED:
+                return "PADDED";
+            case PRIORITY:
+                return "PRIORITY";
+        }
+        return super.flagAsString(flag);
+    }
+
+    public void setPadLength(int padLength) {
+        this.padLength = padLength;
+        flags |= PADDED;
+    }
+
+    public void setPriority(int streamDependency, boolean exclusive, int weight) {
+        this.streamDependency = streamDependency;
+        this.exclusive = exclusive;
+        this.weight = weight;
+        this.flags |= PRIORITY;
+    }
+
+    public int getStreamDependency() {
+        return streamDependency;
+    }
+
+    public int getWeight() {
+        return weight;
+    }
+
+    @Override
+    public boolean endHeaders() {
+        return getFlag(END_HEADERS);
+    }
+
+    public boolean getExclusive() {
+        return exclusive;
+    }
+
+    @Override
+    void readIncomingImpl(ByteBufferConsumer bc) throws IOException {
+        if ((flags & PADDED) != 0) {
+            padLength = bc.getByte();
+        }
+        if ((flags & PRIORITY) != 0) {
+            int x = bc.getInt();
+            exclusive = (x & 0x80000000) != 0;
+            streamDependency = x & 0x7fffffff;
+            weight = bc.getByte();
+        }
+        headerLength = length - padLength;
+        headerBlocks = bc.getBuffers(headerLength);
+    }
+
+    @Override
+    void computeLength() {
+        int len = 0;
+        if ((flags & PADDED) != 0) {
+            len += (1 + padLength);
+        }
+        if ((flags & PRIORITY) != 0) {
+            len += 5;
+        }
+        len += headerLength;
+        this.length = len;
+    }
+
+    @Override
+    void writeOutgoing(ByteBufferGenerator bg) {
+        super.writeOutgoing(bg);
+        ByteBuffer buf = bg.getBuffer(6);
+        if ((flags & PADDED) != 0) {
+            buf.put((byte)padLength);
+        }
+        if ((flags & PRIORITY) != 0) {
+            int x = exclusive ? 1 << 31 + streamDependency : streamDependency;
+            buf.putInt(x);
+            buf.put((byte)weight);
+        }
+        for (int i=0; i<headerBlocks.length; i++) {
+            bg.addByteBuffer(headerBlocks[i]);
+        }
+        if ((flags & PADDED) != 0) {
+            bg.addPadding(padLength);
+        }
+    }
+}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/Http1Exchange.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/Http1Exchange.java	Thu Apr 28 23:08:16 2016 -0700
@@ -64,32 +64,12 @@
         if (connection != null) {
             this.connection = connection;
         } else {
-            InetSocketAddress addr = getAddress(request);
+            InetSocketAddress addr = Utils.getAddress(request);
             this.connection = HttpConnection.getConnection(addr, request);
         }
         this.requestAction = new Http1Request(request, this.connection);
     }
 
-    private static InetSocketAddress getAddress(HttpRequestImpl req) {
-        URI uri = req.uri();
-        if (uri == null) {
-            return req.authority();
-        }
-        int port = uri.getPort();
-        if (port == -1) {
-            if (uri.getScheme().equalsIgnoreCase("https")) {
-                port = 443;
-            } else {
-                port = 80;
-            }
-        }
-        String host = uri.getHost();
-        if (req.proxy() == null) {
-            return new InetSocketAddress(host, port);
-        } else {
-            return InetSocketAddress.createUnresolved(host, port);
-        }
-    }
 
     HttpConnection connection() {
         return connection;
@@ -211,7 +191,7 @@
                                 connection.close();
                             }
                          },
-                         () -> request.getAccessControlContext());
+                request::getAccessControlContext);
         operations.add(cf);
         return cf;
     }
@@ -269,7 +249,7 @@
                 cf.completeExceptionally(e);
                 connection.close();
             }
-        }, () -> request.getAccessControlContext());
+        }, request::getAccessControlContext);
         operations.add(cf);
         return cf;
     }
@@ -302,7 +282,7 @@
                 cf.completeExceptionally(e);
                 connection.close();
             }
-        }, () -> request.getAccessControlContext());
+        }, request::getAccessControlContext);
         operations.add(cf);
         return cf;
     }
--- a/jdk/src/java.httpclient/share/classes/java/net/http/Http1Request.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/Http1Request.java	Thu Apr 28 23:08:16 2016 -0700
@@ -30,6 +30,7 @@
 import java.util.Map;
 import java.util.Set;
 import java.net.InetSocketAddress;
+import java.net.http.HttpConnection.Mode;
 import java.nio.charset.StandardCharsets;
 import java.util.function.LongConsumer;
 import static java.nio.charset.StandardCharsets.US_ASCII;
@@ -48,7 +49,8 @@
     // See line 206 and below for description
     final ByteBuffer[] buffers;
     final HttpRequest.BodyProcessor requestProc;
-    final HttpHeadersImpl userHeaders, systemHeaders;
+    final HttpHeaders userHeaders;
+    final HttpHeadersImpl systemHeaders;
     final LongConsumer flowController;
     boolean streaming;
     long contentLength;
@@ -91,10 +93,10 @@
 
     private void collectHeaders1(StringBuilder sb,
                                  HttpRequestImpl request,
-                                 HttpHeadersImpl headers)
+                                 HttpHeaders headers)
         throws IOException
     {
-        Map<String,List<String>> h = headers.directMap();
+        Map<String,List<String>> h = headers.map();
         Set<Map.Entry<String,List<String>>> entries = h.entrySet();
 
         for (Map.Entry<String,List<String>> entry : entries) {
@@ -112,8 +114,6 @@
         }
     }
 
-    private static final int BUFSIZE = 64 * 1024; // TODO: configurable?
-
     private String getPathAndQuery(URI uri) {
         String path = uri.getPath();
         String query = uri.getQuery();
@@ -134,6 +134,25 @@
         return addr.getHostString() + ":" + addr.getPort();
     }
 
+    private String hostString() {
+        URI uri = request.uri();
+        int port = uri.getPort();
+        String host = uri.getHost();
+
+        boolean defaultPort;
+        if (port == -1)
+            defaultPort = true;
+        else if (request.secure())
+            defaultPort = port == 443;
+        else
+            defaultPort = port == 80;
+
+        if (defaultPort)
+            return host;
+        else
+            return host + ":" + Integer.toString(port);
+    }
+
     private String requestURI() {
         URI uri = request.uri();
         String method = request.method();
@@ -161,6 +180,7 @@
 
     void sendRequest() throws IOException {
         collectHeaders();
+        chan.configureMode(Mode.BLOCKING);
         if (contentLength == 0) {
             chan.write(buffers, 0, 2);
         } else if (contentLength > 0) {
@@ -196,7 +216,7 @@
         buffers[0] = ByteBuffer.wrap(cmd.getBytes(StandardCharsets.US_ASCII));
         URI uri = request.uri();
         if (uri != null) {
-            systemHeaders.setHeader("Host", uri.getHost());
+            systemHeaders.setHeader("Host", hostString());
         }
         if (request == null) {
             // this is not a user request. No content
--- a/jdk/src/java.httpclient/share/classes/java/net/http/Http1Response.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/Http1Response.java	Thu Apr 28 23:08:16 2016 -0700
@@ -24,7 +24,6 @@
 package java.net.http;
 
 import java.io.IOException;
-import java.net.URI;
 import java.nio.ByteBuffer;
 import java.util.List;
 import java.util.Map;
--- a/jdk/src/java.httpclient/share/classes/java/net/http/Http2ClientImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/Http2ClientImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, 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
@@ -23,11 +23,133 @@
  */
 package java.net.http;
 
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import static java.net.http.SettingsFrame.INITIAL_WINDOW_SIZE;
+import static java.net.http.SettingsFrame.ENABLE_PUSH;
+import static java.net.http.SettingsFrame.HEADER_TABLE_SIZE;
+import static java.net.http.SettingsFrame.MAX_CONCURRENT_STREAMS;
+import static java.net.http.SettingsFrame.MAX_FRAME_SIZE;
+import java.util.Base64;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *  Http2 specific aspects of HttpClientImpl
+ */
 class Http2ClientImpl {
-    Http2ClientImpl(HttpClientImpl t) {}
-    String getSettingsString() {return "";}
-    void debugPrint() {}
-    Http2Connection getConnectionFor(HttpRequestImpl r) {
-        return null;
+
+    final private HttpClientImpl client;
+
+    Http2ClientImpl(HttpClientImpl client) {
+        this.client = client;
+    }
+
+    /* Map key is "scheme:host:port" */
+    final private Map<String,Http2Connection> connections =
+            Collections.synchronizedMap(new HashMap<>());
+
+    final private Set<String> opening = Collections.synchronizedSet(new HashSet<>());
+
+    synchronized boolean haveConnectionFor(URI uri, InetSocketAddress proxy) {
+        return connections.containsKey(Http2Connection.keyFor(uri,proxy));
+    }
+
+    /**
+     * If a https request then blocks and waits until a connection is opened.
+     * Returns null if the request is 'http' as a different (upgrade)
+     * mechanism is used.
+     *
+     * Only one connection per destination is created. Blocks when opening
+     * connection, or when waiting for connection to be opened.
+     * First thread opens the connection and notifies the others when done.
+     *
+     * If the request is secure (https) then we open the connection here.
+     * If not, then the more complicated upgrade from 1.1 to 2 happens (not here)
+     * In latter case, when the Http2Connection is connected, putConnection() must
+     * be called to store it.
+     */
+    Http2Connection getConnectionFor(HttpRequestImpl req)
+            throws IOException, InterruptedException {
+        URI uri = req.uri();
+        InetSocketAddress proxy = req.proxy();
+        String key = Http2Connection.keyFor(uri, proxy);
+        Http2Connection connection;
+        synchronized (opening) {
+            while ((connection = connections.get(key)) == null) {
+                if (!req.secure()) {
+                    return null;
+                }
+                if (!opening.contains(key)) {
+                    opening.add(key);
+                    break;
+                } else {
+                    opening.wait();
+                }
+            }
+        }
+        if (connection != null) {
+            return connection;
+        }
+        // we are opening the connection here blocking until it is done.
+        connection = new Http2Connection(req);
+        synchronized (opening) {
+            connections.put(key, connection);
+            opening.remove(key);
+            opening.notifyAll();
+        }
+        return connection;
+    }
+
+
+    /*
+     * TODO: If there isn't a connection to the same destination, then
+     * store it. If there is already a connection, then close it
+     */
+    synchronized void putConnection(Http2Connection c) {
+        String key = c.key();
+        connections.put(key, c);
+    }
+
+    synchronized void deleteConnection(Http2Connection c) {
+        String key = c.key();
+        connections.remove(key);
+    }
+
+    HttpClientImpl client() {
+        return client;
+    }
+
+    /** Returns the client settings as a base64 (url) encoded string */
+    String getSettingsString() {
+        SettingsFrame sf = getClientSettings();
+        ByteBufferGenerator bg = new ByteBufferGenerator(client);
+        sf.writeOutgoing(bg);
+        byte[] settings = bg.asByteArray(9); // without the header
+        Base64.Encoder encoder = Base64.getUrlEncoder()
+                                       .withoutPadding();
+        return encoder.encodeToString(settings);
+    }
+
+    private static final int K = 1024;
+
+    SettingsFrame getClientSettings() {
+        SettingsFrame frame = new SettingsFrame();
+        frame.setParameter(HEADER_TABLE_SIZE, Utils.getIntegerNetProperty(
+            "java.net.httpclient.hpack.maxheadertablesize", 16 * K));
+        frame.setParameter(ENABLE_PUSH, Utils.getIntegerNetProperty(
+            "java.net.httpclient.enablepush", 1));
+        frame.setParameter(MAX_CONCURRENT_STREAMS, Utils.getIntegerNetProperty(
+            "java.net.httpclient.maxstreams", 16));
+        frame.setParameter(INITIAL_WINDOW_SIZE, Utils.getIntegerNetProperty(
+            "java.net.httpclient.windowsize", 32 * K));
+        frame.setParameter(MAX_FRAME_SIZE, Utils.getIntegerNetProperty(
+            "java.net.httpclient.maxframesize", 16 * K));
+        frame.computeLength();
+        return frame;
     }
 }
--- a/jdk/src/java.httpclient/share/classes/java/net/http/Http2Connection.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/Http2Connection.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, 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,42 +24,767 @@
 package java.net.http;
 
 import java.io.IOException;
-import java.net.Authenticator;
-import java.net.CookieManager;
-import java.net.ProxySelector;
+import java.net.InetSocketAddress;
 import java.net.URI;
-import static java.net.http.Utils.BUFSIZE;
+import java.net.http.HttpConnection.Mode;
 import java.nio.ByteBuffer;
-import java.nio.channels.SelectableChannel;
-import java.nio.channels.SelectionKey;
-import static java.nio.channels.SelectionKey.OP_CONNECT;
-import static java.nio.channels.SelectionKey.OP_READ;
-import static java.nio.channels.SelectionKey.OP_WRITE;
-import java.nio.channels.Selector;
+import java.nio.charset.StandardCharsets;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Set;
-import java.util.concurrent.*;
-import java.security.NoSuchAlgorithmException;
-import java.util.ListIterator;
-import java.util.Optional;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ThreadFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLParameters;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import sun.net.httpclient.hpack.Encoder;
+import sun.net.httpclient.hpack.Decoder;
+import static java.net.http.SettingsFrame.*;
+import static java.net.http.Utils.BUFSIZE;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Formatter;
+import java.util.stream.Collectors;
+import sun.net.httpclient.hpack.DecodingCallback;
+
+/**
+ * An Http2Connection. Encapsulates the socket(channel) and any SSLEngine used
+ * over it. Contains an HttpConnection which hides the SocketChannel SSL stuff.
+ *
+ * Http2Connections belong to a Http2ClientImpl, (one of) which belongs
+ * to a HttpClientImpl.
+ *
+ * Creation cases:
+ * 1) upgraded HTTP/1.1 plain tcp connection
+ * 2) prior knowledge directly created plain tcp connection
+ * 3) directly created HTTP/2 SSL connection which uses ALPN.
+ *
+ * Sending is done by writing directly to underlying HttpConnection object which
+ * is operating in async mode. No flow control applies on output at this level
+ * and all writes are just executed as puts to an output Q belonging to HttpConnection
+ * Flow control is implemented by HTTP/2 protocol itself.
+ *
+ * Hpack header compression
+ * and outgoing stream creation is also done here, because these operations
+ * must be synchronized at the socket level. Stream objects send frames simply
+ * by placing them on the connection's output Queue. sendFrame() is called
+ * from a higher level (Stream) thread.
+ *
+ * asyncReceive(ByteBuffer) is always called from the selector thread. It assembles
+ * incoming Http2Frames, and directs them to the appropriate Stream.incoming()
+ * or handles them directly itself. This thread performs hpack decompression
+ * and incoming stream creation (Server push). Incoming frames destined for a
+ * stream are provided by calling Stream.incoming().
+ */
+class Http2Connection implements BufferHandler {
+
+    final Queue<Http2Frame> outputQ;
+    volatile boolean closed;
+
+    //-------------------------------------
+    final HttpConnection connection;
+    HttpClientImpl client;
+    final Http2ClientImpl client2;
+    Map<Integer,Stream> streams;
+    int nextstreamid = 3; // stream 1 is registered separately
+    int nextPushStream = 2;
+    Encoder hpackOut;
+    Decoder hpackIn;
+    SettingsFrame clientSettings, serverSettings;
+    ByteBufferConsumer bbc;
+    final LinkedList<ByteBuffer> freeList;
+    final String key; // for HttpClientImpl.connections map
+    FrameReader reader;
+
+    // Connection level flow control windows
+    int sendWindow = INITIAL_WINDOW_SIZE;
+
+    final static int DEFAULT_FRAME_SIZE = 16 * 1024;
+    private static ByteBuffer[] empty = Utils.EMPTY_BB_ARRAY;
+
+    final ExecutorWrapper executor;
+
+    /**
+     * This is established by the protocol spec and the peer will update it with
+     * WINDOW_UPDATEs, which affects the sendWindow.
+     */
+    final static int INITIAL_WINDOW_SIZE = 64 * 1024 - 1;
+
+    // TODO: need list of control frames from other threads
+    // that need to be sent
+
+    /**
+     * Case 1) Create from upgraded HTTP/1.1 connection.
+     * Is ready to use. Will not be SSL. exchange is the Exchange
+     * that initiated the connection, whose response will be delivered
+     * on a Stream.
+     */
+    Http2Connection(HttpConnection connection, Http2ClientImpl client2,
+            Exchange exchange) throws IOException, InterruptedException {
+        this.outputQ = new Queue<>();
+        String msg = "Connection send window size " + Integer.toString(sendWindow);
+        Log.logTrace(msg);
+
+        //this.initialExchange = exchange;
+        assert !(connection instanceof SSLConnection);
+        this.connection = connection;
+        this.client = client2.client();
+        this.client2 = client2;
+        this.executor = client.executorWrapper();
+        this.freeList = new LinkedList<>();
+        this.key = keyFor(connection);
+        streams = Collections.synchronizedMap(new HashMap<>());
+        initCommon();
+        //sendConnectionPreface();
+        Stream initialStream = createStream(exchange);
+        initialStream.registerStream(1);
+        initialStream.requestSent();
+        sendConnectionPreface();
+        connection.configureMode(Mode.ASYNC);
+        // start reading and writing
+        // start reading
+        AsyncConnection asyncConn = (AsyncConnection)connection;
+        asyncConn.setAsyncCallbacks(this::asyncReceive, this::shutdown);
+        asyncReceive(connection.getRemaining());
+        asyncConn.startReading();
+    }
+
+    // async style but completes immediately
+    static CompletableFuture<Http2Connection> createAsync(HttpConnection connection,
+            Http2ClientImpl client2, Exchange exchange) {
+        CompletableFuture<Http2Connection> cf = new CompletableFuture<>();
+        try {
+            Http2Connection c = new Http2Connection(connection, client2, exchange);
+            cf.complete(c);
+        } catch (IOException | InterruptedException e) {
+            cf.completeExceptionally(e);
+        }
+        return cf;
+    }
+
+    /**
+     * Cases 2) 3)
+     *
+     * request is request to be sent.
+     */
+    Http2Connection(HttpRequestImpl request) throws IOException, InterruptedException {
+        InetSocketAddress proxy = request.proxy();
+        URI uri = request.uri();
+        InetSocketAddress addr = Utils.getAddress(request);
+        String msg = "Connection send window size " + Integer.toString(sendWindow);
+        Log.logTrace(msg);
+        this.key = keyFor(uri, proxy);
+        this.connection = HttpConnection.getConnection(addr, request, this);
+        streams = Collections.synchronizedMap(new HashMap<>());
+        this.client = request.client();
+        this.client2 = client.client2();
+        this.executor = client.executorWrapper();
+        this.freeList = new LinkedList<>();
+        this.outputQ = new Queue<>();
+        nextstreamid = 1;
+        initCommon();
+        connection.connect();
+        connection.configureMode(Mode.ASYNC);
+        // start reading
+        AsyncConnection asyncConn = (AsyncConnection)connection;
+        asyncConn.setAsyncCallbacks(this::asyncReceive, this::shutdown);
+        sendConnectionPreface();
+        asyncConn.startReading();
+    }
+
+    // NEW
+    synchronized void obtainSendWindow(int amount) throws InterruptedException {
+        while (amount > 0) {
+            int n = Math.min(amount, sendWindow);
+            sendWindow -= n;
+            amount -= n;
+            if (amount > 0)
+                wait();
+        }
+    }
+
+    synchronized void updateSendWindow(int amount) {
+        if (sendWindow == 0) {
+            sendWindow += amount;
+            notifyAll();
+        } else
+            sendWindow += amount;
+    }
+
+    synchronized int sendWindow() {
+        return sendWindow;
+    }
+
+    static String keyFor(HttpConnection connection) {
+        boolean isProxy = connection.isProxied();
+        boolean isSecure = connection.isSecure();
+        InetSocketAddress addr = connection.address();
+
+        return keyString(isSecure, isProxy, addr.getHostString(), addr.getPort());
+    }
+
+    static String keyFor(URI uri, InetSocketAddress proxy) {
+        boolean isSecure = uri.getScheme().equalsIgnoreCase("https");
+        boolean isProxy = proxy != null;
+
+        String host;
+        int port;
+
+        if (isProxy) {
+            host = proxy.getHostString();
+            port = proxy.getPort();
+        } else {
+            host = uri.getHost();
+            port = uri.getPort();
+        }
+        return keyString(isSecure, isProxy, host, port);
+    }
+
+    // {C,S}:{H:P}:host:port
+    // C indicates clear text connection "http"
+    // S indicates secure "https"
+    // H indicates host (direct) connection
+    // P indicates proxy
+    // Eg: "S:H:foo.com:80"
+    static String keyString(boolean secure, boolean proxy, String host, int port) {
+        char c1 = secure ? 'S' : 'C';
+        char c2 = proxy ? 'P' : 'H';
+
+        StringBuilder sb = new StringBuilder(128);
+        sb.append(c1).append(':').append(c2).append(':')
+                .append(host).append(':').append(port);
+        return sb.toString();
+    }
+
+    String key() {
+        return this.key;
+    }
+
+    void putConnection() {
+        client2.putConnection(this);
+    }
+
+    private static String toHexdump1(ByteBuffer bb) {
+        bb.mark();
+        StringBuilder sb = new StringBuilder(512);
+        Formatter f = new Formatter(sb);
+
+        while (bb.hasRemaining()) {
+            int i =  Byte.toUnsignedInt(bb.get());
+            f.format("%02x:", i);
+        }
+        sb.deleteCharAt(sb.length()-1);
+        bb.reset();
+        return sb.toString();
+    }
+
+    private static String toHexdump(ByteBuffer bb) {
+        List<String> words = new ArrayList<>();
+        int i = 0;
+        bb.mark();
+        while (bb.hasRemaining()) {
+            if (i % 2 == 0) {
+                words.add("");
+            }
+            byte b = bb.get();
+            String hex = Integer.toHexString(256 + Byte.toUnsignedInt(b)).substring(1);
+            words.set(i / 2, words.get(i / 2) + hex);
+            i++;
+        }
+        bb.reset();
+        return words.stream().collect(Collectors.joining(" "));
+    }
+
+    private void decodeHeaders(HeaderFrame frame, DecodingCallback decoder) {
+        boolean endOfHeaders = frame.getFlag(HeaderFrame.END_HEADERS);
+
+        ByteBuffer[] buffers = frame.getHeaderBlock();
+        for (int i = 0; i < buffers.length; i++) {
+            hpackIn.decode(buffers[i], endOfHeaders, decoder);
+        }
+    }
+
+    int getInitialSendWindowSize() {
+        return serverSettings.getParameter(SettingsFrame.INITIAL_WINDOW_SIZE);
+    }
+
+    void close() {
+        GoAwayFrame f = new GoAwayFrame();
+        f.setDebugData("Requested by user".getBytes());
+        // TODO: set last stream. For now zero ok.
+        sendFrame(f);
+    }
+
+    // BufferHandler methods
+
+    @Override
+    public ByteBuffer getBuffer(int n) {
+        return client.getBuffer(n);
+    }
+
+    @Override
+    public void returnBuffer(ByteBuffer buf) {
+        client.returnBuffer(buf);
+    }
 
-class Http2Connection {
-    static CompletableFuture<Http2Connection> createAsync(
-        HttpConnection connection, Http2ClientImpl client2, Exchange exchange) {
-            return null;
+    @Override
+    public void setMinBufferSize(int n) {
+        client.setMinBufferSize(n);
+    }
+
+    private final Object readlock = new Object();
+
+    void asyncReceive(ByteBuffer buffer) {
+        synchronized (readlock) {
+            try {
+                if (reader == null) {
+                    reader = new FrameReader(buffer);
+                } else {
+                    reader.input(buffer);
+                }
+                while (true) {
+                    if (reader.haveFrame()) {
+                        List<ByteBuffer> buffers = reader.frame();
+
+                        ByteBufferConsumer bbc = new ByteBufferConsumer(buffers, this::getBuffer);
+                        processFrame(bbc);
+                        if (bbc.consumed()) {
+                            reader = new FrameReader();
+                            return;
+                        } else {
+                            reader = new FrameReader(reader);
+                        }
+                    } else
+                        return;
+                }
+            } catch (Throwable e) {
+                String msg = Utils.stackTrace(e);
+                Log.logTrace(msg);
+                shutdown(e);
+            }
+        }
+    }
+
+    void shutdown(Throwable t) {
+        System.err.println("Shutdown: " + t);
+        t.printStackTrace();
+        closed = true;
+        client2.deleteConnection(this);
+        Collection<Stream> c = streams.values();
+        for (Stream s : c) {
+            s.cancelImpl(t);
+        }
+        connection.close();
+    }
+
+    /**
+     * Handles stream 0 (common) frames that apply to whole connection and passes
+     * other stream specific frames to that Stream object.
+     *
+     * Invokes Stream.incoming() which is expected to process frame without
+     * blocking.
+     */
+    void processFrame(ByteBufferConsumer bbc) throws IOException, InterruptedException {
+        Http2Frame frame = Http2Frame.readIncoming(bbc);
+        Log.logFrames(frame, "IN");
+        int streamid = frame.streamid();
+        if (streamid == 0) {
+            handleCommonFrame(frame);
+        } else {
+            Stream stream = getStream(streamid);
+            if (stream == null) {
+                // should never receive a frame with unknown stream id
+                resetStream(streamid, ResetFrame.PROTOCOL_ERROR);
+            }
+            if (frame instanceof PushPromiseFrame) {
+                PushPromiseFrame pp = (PushPromiseFrame)frame;
+                handlePushPromise(stream, pp);
+            } else if (frame instanceof HeaderFrame) {
+                // decode headers (or continuation)
+                decodeHeaders((HeaderFrame) frame, stream.rspHeadersConsumer());
+                stream.incoming(frame);
+            } else
+                stream.incoming(frame);
+        }
+    }
+
+    private void handlePushPromise(Stream parent, PushPromiseFrame pp)
+            throws IOException, InterruptedException {
+
+        HttpRequestImpl parentReq = parent.request;
+        int promisedStreamid = pp.getPromisedStream();
+        if (promisedStreamid != nextPushStream) {
+            resetStream(promisedStreamid, ResetFrame.PROTOCOL_ERROR);
+            return;
+        } else {
+            nextPushStream += 2;
+        }
+        HeaderDecoder decoder = new HeaderDecoder();
+        decodeHeaders(pp, decoder);
+        HttpHeadersImpl headers = decoder.headers();
+        HttpRequestImpl pushReq = HttpRequestImpl.createPushRequest(parentReq, headers);
+
+        Stream.PushedStream pushStream = createPushStream(parent, pushReq);
+        pushStream.registerStream(promisedStreamid);
+        parent.incoming_pushPromise(pushReq, pushStream);
+    }
+
+    private void handleCommonFrame(Http2Frame frame)
+            throws IOException, InterruptedException {
+
+        switch (frame.type()) {
+          case SettingsFrame.TYPE:
+          { SettingsFrame f = (SettingsFrame)frame;
+            handleSettings(f);}
+            break;
+          case PingFrame.TYPE:
+          { PingFrame f = (PingFrame)frame;
+            handlePing(f);}
+            break;
+          case GoAwayFrame.TYPE:
+          { GoAwayFrame f = (GoAwayFrame)frame;
+            handleGoAway(f);}
+            break;
+          case WindowUpdateFrame.TYPE:
+          { WindowUpdateFrame f = (WindowUpdateFrame)frame;
+            handleWindowUpdate(f);}
+            break;
+          default:
+            protocolError(ErrorFrame.PROTOCOL_ERROR);
+        }
+    }
+
+    void resetStream(int streamid, int code) throws IOException, InterruptedException {
+        Log.logError(
+            "Resetting stream {0,number,integer} with error code {1,number,integer}",
+            streamid, code);
+        ResetFrame frame = new ResetFrame();
+        frame.streamid(streamid);
+        frame.setErrorCode(code);
+        sendFrame(frame);
+        streams.remove(streamid);
+    }
+
+    private void handleWindowUpdate(WindowUpdateFrame f)
+            throws IOException, InterruptedException {
+        updateSendWindow(f.getUpdate());
+    }
+
+    private void protocolError(int errorCode)
+            throws IOException, InterruptedException {
+        GoAwayFrame frame = new GoAwayFrame();
+        frame.setErrorCode(errorCode);
+        sendFrame(frame);
+        String msg = "Error code: " + errorCode;
+        shutdown(new IOException("protocol error"));
+    }
+
+    private void handleSettings(SettingsFrame frame)
+            throws IOException, InterruptedException {
+        if (frame.getFlag(SettingsFrame.ACK)) {
+            // ignore ack frames for now.
+            return;
+        }
+        serverSettings = frame;
+        SettingsFrame ack = getAckFrame(frame.streamid());
+        sendFrame(ack);
+    }
+
+    private void handlePing(PingFrame frame)
+            throws IOException, InterruptedException {
+        frame.setFlag(PingFrame.ACK);
+        sendFrame(frame);
+    }
+
+    private void handleGoAway(GoAwayFrame frame)
+            throws IOException, InterruptedException {
+        //System.err.printf("GoAWAY: %s\n", ErrorFrame.stringForCode(frame.getErrorCode()));
+        shutdown(new IOException("GOAWAY received"));
+    }
+
+    private void initCommon() {
+        clientSettings = client2.getClientSettings();
+
+        // serverSettings will be updated by server
+        serverSettings = SettingsFrame.getDefaultSettings();
+        hpackOut = new Encoder(serverSettings.getParameter(HEADER_TABLE_SIZE));
+        hpackIn = new Decoder(clientSettings.getParameter(HEADER_TABLE_SIZE));
+    }
+
+    /**
+     * Max frame size we are allowed to send
+     */
+    public int getMaxSendFrameSize() {
+        int param = serverSettings.getParameter(MAX_FRAME_SIZE);
+        if (param == -1) {
+            param = DEFAULT_FRAME_SIZE;
+        }
+        return param;
+    }
+
+    /**
+     * Max frame size we will receive
+     */
+    public int getMaxReceiveFrameSize() {
+        return clientSettings.getParameter(MAX_FRAME_SIZE);
+    }
+
+    // Not sure how useful this is.
+    public int getMaxHeadersSize() {
+        return serverSettings.getParameter(MAX_HEADER_LIST_SIZE);
+    }
+
+    private static final String CLIENT_PREFACE = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n";
+
+    private static final byte[] PREFACE_BYTES =
+        CLIENT_PREFACE.getBytes(StandardCharsets.ISO_8859_1);
+
+    /**
+     * Sends Connection preface and Settings frame with current preferred
+     * values
+     */
+    private void sendConnectionPreface() throws IOException {
+        ByteBufferGenerator bg = new ByteBufferGenerator(this);
+        bg.getBuffer(PREFACE_BYTES.length).put(PREFACE_BYTES);
+        ByteBuffer[] ba = bg.getBufferArray();
+        connection.write(ba, 0, ba.length);
+
+        bg = new ByteBufferGenerator(this);
+        SettingsFrame sf = client2.getClientSettings();
+        Log.logFrames(sf, "OUT");
+        sf.writeOutgoing(bg);
+        WindowUpdateFrame wup = new WindowUpdateFrame();
+        wup.streamid(0);
+        // send a Window update for the receive buffer we are using
+        // minus the initial 64 K specified in protocol
+        wup.setUpdate(client2.client().getReceiveBufferSize() - (64 * 1024 - 1));
+        wup.computeLength();
+        wup.writeOutgoing(bg);
+        Log.logFrames(wup, "OUT");
+        ba = bg.getBufferArray();
+        connection.write(ba, 0, ba.length);
+    }
+
+    /**
+     * Returns an existing Stream with given id, or null if doesn't exist
+     */
+    Stream getStream(int streamid) {
+        return streams.get(streamid);
+    }
+
+    /**
+     * Creates Stream with given id.
+     */
+    Stream createStream(Exchange exchange) {
+        Stream stream = new Stream(client, this, exchange);
+        return stream;
+    }
+
+    Stream.PushedStream createPushStream(Stream parent, HttpRequestImpl pushReq) {
+        Stream.PushGroup<?> pg = parent.request.pushGroup();
+        return new Stream.PushedStream(pg, client, this, parent, pushReq);
+    }
+
+    void putStream(Stream stream, int streamid) {
+        streams.put(streamid, stream);
+    }
+
+    void deleteStream(Stream stream) {
+        streams.remove(stream.streamid);
+    }
+
+    static final int MAX_STREAM = Integer.MAX_VALUE - 2;
+
+    // Number of header bytes in a Headers Frame
+    final static int HEADERS_HEADER_SIZE = 15;
+
+    // Number of header bytes in a Continuation frame
+    final static int CONTIN_HEADER_SIZE = 9;
+
+    /**
+     * Encode the headers into a List<ByteBuffer> and then create HEADERS
+     * and CONTINUATION frames from the list and return the List<Http2Frame>.
+     *
+     * @param frame
+     * @return
+     */
+    private LinkedList<Http2Frame> encodeHeaders(OutgoingHeaders frame) {
+        LinkedList<ByteBuffer> buffers = new LinkedList<>();
+        ByteBuffer buf = getBuffer();
+        buffers.add(buf);
+        encodeHeadersImpl(frame.stream.getRequestPseudoHeaders(), buffers);
+        encodeHeadersImpl(frame.getUserHeaders(), buffers);
+        encodeHeadersImpl(frame.getSystemHeaders(), buffers);
+
+        for (ByteBuffer b : buffers) {
+            b.flip();
         }
 
-    Http2Connection(HttpConnection connection, Http2ClientImpl client2,
-            Exchange exchange) throws IOException, InterruptedException {
+        LinkedList<Http2Frame> frames = new LinkedList<>();
+        int maxframesize = getMaxSendFrameSize();
+
+        HeadersFrame oframe = new HeadersFrame();
+        oframe.setFlags(frame.getFlags());
+        oframe.streamid(frame.streamid());
+
+        oframe.setHeaderBlock(getBufferArray(buffers, maxframesize));
+        frames.add(oframe);
+        // Any buffers left?
+        boolean done = buffers.isEmpty();
+        if (done) {
+            oframe.setFlag(HeaderFrame.END_HEADERS);
+        } else {
+            ContinuationFrame cf = null;
+            while (!done) {
+                cf = new ContinuationFrame();
+                cf.streamid(frame.streamid());
+                cf.setHeaderBlock(getBufferArray(buffers, maxframesize));
+                frames.add(cf);
+                done = buffers.isEmpty();
+            }
+            cf.setFlag(HeaderFrame.END_HEADERS);
+        }
+        return frames;
+    }
+
+    // should always return at least one buffer
+    private static ByteBuffer[] getBufferArray(LinkedList<ByteBuffer> list, int maxsize) {
+        assert maxsize >= BUFSIZE;
+        LinkedList<ByteBuffer> newlist = new LinkedList<>();
+        int size = list.size();
+        int nbytes = 0;
+        for (int i=0; i<size; i++) {
+            ByteBuffer buf = list.getFirst();
+            if (nbytes + buf.remaining() <= maxsize) {
+                nbytes += buf.remaining();
+                newlist.add(buf);
+                list.remove();
+            } else {
+                break;
+            }
+        }
+        return newlist.toArray(empty);
+    }
+
+    /**
+     * Encode all the headers from the given HttpHeadersImpl into the given List.
+     */
+    private void encodeHeadersImpl(HttpHeaders hdrs, LinkedList<ByteBuffer> buffers) {
+        ByteBuffer buffer;
+        if (!(buffer = buffers.getLast()).hasRemaining()) {
+            buffer = getBuffer();
+            buffers.add(buffer);
+        }
+        for (Map.Entry<String, List<String>> e : hdrs.map().entrySet()) {
+            String key = e.getKey();
+            String lkey = key.toLowerCase();
+            List<String> values = e.getValue();
+            for (String value : values) {
+                hpackOut.header(lkey, value);
+                boolean encoded = false;
+                do {
+                    encoded = hpackOut.encode(buffer);
+                    if (!encoded) {
+                        buffer = getBuffer();
+                        buffers.add(buffer);
+                    }
+                } while (!encoded);
+            }
+        }
+    }
+
+    public void sendFrames(List<Http2Frame> frames) throws IOException, InterruptedException {
+        for (Http2Frame frame : frames) {
+            sendFrame(frame);
+        }
     }
 
-    Stream getStream(int i) {return null;}
-    Stream createStream(Exchange ex) {return null;}
-    void putConnection() {}
+    static Throwable getExceptionFrom(CompletableFuture<?> cf) {
+        try {
+            cf.get();
+            return null;
+        } catch (Throwable e) {
+            if (e.getCause() != null)
+                return e.getCause();
+            else
+                return e;
+        }
+    }
+
+
+    void execute(Runnable r) {
+        executor.execute(r, null);
+    }
+
+    private final Object sendlock = new Object();
+
+    /**
+     *
+     */
+    void sendFrame(Http2Frame frame) {
+        synchronized (sendlock) {
+            try {
+                if (frame instanceof OutgoingHeaders) {
+                    OutgoingHeaders oh = (OutgoingHeaders) frame;
+                    Stream stream = oh.getStream();
+                    stream.registerStream(nextstreamid);
+                    oh.streamid(nextstreamid);
+                    nextstreamid += 2;
+                    // set outgoing window here. This allows thread sending
+                    // body to proceed.
+                    stream.updateOutgoingWindow(getInitialSendWindowSize());
+                    LinkedList<Http2Frame> frames = encodeHeaders(oh);
+                    for (Http2Frame f : frames) {
+                        sendOneFrame(f);
+                    }
+                } else {
+                    sendOneFrame(frame);
+                }
+
+            } catch (IOException e) {
+                if (!closed) {
+                    Log.logError(e);
+                    shutdown(e);
+                }
+            }
+        }
+    }
+
+    /**
+     * Send a frame.
+     *
+     * @param frame
+     * @throws IOException
+     */
+    private void sendOneFrame(Http2Frame frame) throws IOException {
+        ByteBufferGenerator bbg = new ByteBufferGenerator(this);
+        frame.computeLength();
+        Log.logFrames(frame, "OUT");
+        frame.writeOutgoing(bbg);
+        ByteBuffer[] currentBufs = bbg.getBufferArray();
+        connection.write(currentBufs, 0, currentBufs.length);
+    }
+
+
+    private SettingsFrame getAckFrame(int streamid) {
+        SettingsFrame frame = new SettingsFrame();
+        frame.setFlag(SettingsFrame.ACK);
+        frame.streamid(streamid);
+        return frame;
+    }
+
+    static class HeaderDecoder implements DecodingCallback {
+        HttpHeadersImpl headers;
+
+        HeaderDecoder() {
+            this.headers = new HttpHeadersImpl();
+        }
+
+        @Override
+        public void onDecoded(CharSequence name, CharSequence value) {
+            headers.addHeader(name.toString(), value.toString());
+        }
+
+        HttpHeadersImpl headers() {
+            return headers;
+        }
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/Http2Frame.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2015, 2016, 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
+ */
+package java.net.http;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * When sending a frame, the length field must be set in sub-class
+ * by calling computeLength()
+ */
+abstract class Http2Frame {
+
+    int length = -1;
+    int type;
+    int streamid;
+    int flags;
+
+    // called when reading in only
+    void initCommon(int length, int type, int streamid, int flags) {
+        this.length = length;
+        this.type = type;
+        this.streamid = streamid;
+        this.flags = flags;
+    }
+
+    public int length() {
+        return length;
+    }
+
+    public int type() {
+        return type;
+    }
+
+    public int streamid() {
+        return streamid;
+    }
+
+    public void setFlag(int flag) {
+        flags |= flag;
+    }
+
+    public void setFlags(int flags) {
+        this.flags = flags;
+    }
+
+    public int getFlags() {
+        return flags;
+    }
+
+    public boolean getFlag(int flag) {
+        return (flags & flag) != 0;
+    }
+
+    public void clearFlag(int flag) {
+        flags &= 0xffffffff ^ flag;
+    }
+
+    public void streamid(int streamid) {
+        this.streamid = streamid;
+    }
+
+    abstract void readIncomingImpl(ByteBufferConsumer bc) throws IOException;
+
+    /**
+     * assume given array contains at least one complete frame.
+     */
+    static Http2Frame readIncoming(ByteBufferConsumer bc) throws IOException {
+        int x = bc.getInt();
+        int length = x >> 8;
+        int type = x & 0xff;
+        int flags = bc.getByte();
+        int streamid = bc.getInt();
+        Http2Frame f = null;
+        switch (type) {
+          case DataFrame.TYPE:
+            f = new DataFrame();
+            break;
+          case HeadersFrame.TYPE:
+            f = new HeadersFrame();
+            break;
+          case ContinuationFrame.TYPE:
+            f = new ContinuationFrame();
+            break;
+          case ResetFrame.TYPE:
+            f = new ResetFrame();
+            break;
+          case PriorityFrame.TYPE:
+            f = new PriorityFrame();
+            break;
+          case SettingsFrame.TYPE:
+            f = new SettingsFrame();
+            break;
+          case GoAwayFrame.TYPE:
+            f = new GoAwayFrame();
+            break;
+          case PingFrame.TYPE:
+            f = new PingFrame();
+            break;
+          case PushPromiseFrame.TYPE:
+            f = new PushPromiseFrame();
+            break;
+          case WindowUpdateFrame.TYPE:
+            f = new WindowUpdateFrame();
+            break;
+          default:
+            String msg = Integer.toString(type);
+            throw new IOException("unknown frame type " + msg);
+        }
+        f.initCommon(length, type, streamid, flags);
+        f.readIncomingImpl(bc);
+        return f;
+    }
+
+    public String typeAsString() {
+        return asString(this.type);
+    }
+
+    public static String asString(int type) {
+        switch (type) {
+          case DataFrame.TYPE:
+            return "DATA";
+          case HeadersFrame.TYPE:
+            return "HEADERS";
+          case ContinuationFrame.TYPE:
+            return "CONTINUATION";
+          case ResetFrame.TYPE:
+            return "RESET";
+          case PriorityFrame.TYPE:
+            return "PRIORITY";
+          case SettingsFrame.TYPE:
+            return "SETTINGS";
+          case GoAwayFrame.TYPE:
+            return "GOAWAY";
+          case PingFrame.TYPE:
+            return "PING";
+          case PushPromiseFrame.TYPE:
+            return "PUSH_PROMISE";
+          case WindowUpdateFrame.TYPE:
+            return "WINDOW_UPDATE";
+          default:
+            return "UNKNOWN";
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(typeAsString())
+                .append(": length=")
+                .append(Integer.toString(length))
+                .append(", streamid=")
+                .append(streamid)
+                .append(", flags=");
+
+        int f = flags;
+        int i = 0;
+        if (f == 0) {
+            sb.append("0 ");
+        } else {
+            while (f != 0) {
+                if ((f & 1) == 1) {
+                    sb.append(flagAsString(1 << i))
+                      .append(' ');
+                }
+                f = f >> 1;
+                i++;
+            }
+        }
+        return sb.toString();
+    }
+
+    // Override
+    String flagAsString(int f) {
+        return "unknown";
+    }
+
+    abstract void computeLength();
+
+    void writeOutgoing(ByteBufferGenerator bg) {
+        if (length == -1) {
+            throw new InternalError("Length not set on outgoing frame");
+        }
+        ByteBuffer buf = bg.getBuffer(9);
+        int x = (length << 8) + type;
+        buf.putInt(x);
+        buf.put((byte)flags);
+        buf.putInt(streamid);
+    }
+}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/HttpClientImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/HttpClientImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -23,28 +23,32 @@
  */
 package java.net.http;
 
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLParameters;
 import java.io.IOException;
 import java.net.Authenticator;
 import java.net.CookieManager;
 import java.net.ProxySelector;
 import java.net.URI;
-import static java.net.http.Utils.BUFSIZE;
 import java.nio.ByteBuffer;
 import java.nio.channels.ClosedChannelException;
 import java.nio.channels.SelectableChannel;
 import java.nio.channels.SelectionKey;
-import static java.nio.channels.SelectionKey.OP_CONNECT;
-import static java.nio.channels.SelectionKey.OP_READ;
-import static java.nio.channels.SelectionKey.OP_WRITE;
 import java.nio.channels.Selector;
-import java.util.*;
-import java.util.stream.Stream;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Optional;
+import java.util.Set;
 import java.util.concurrent.ExecutorService;
-import java.security.NoSuchAlgorithmException;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ThreadFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLParameters;
+import java.util.stream.Stream;
+
+import static java.net.http.Utils.BUFSIZE;
 
 /**
  * Client implementation. Contains all configuration information and also
@@ -53,6 +57,9 @@
  */
 class HttpClientImpl extends HttpClient implements BufferHandler {
 
+    private static final ThreadFactory defaultFactory =
+            (r -> new Thread(null, r, "HttpClient_worker", 0, true));
+
     private final CookieManager cookieManager;
     private final Redirect followRedirects;
     private final ProxySelector proxySelector;
@@ -67,7 +74,6 @@
     private final SelectorManager selmgr;
     private final FilterFactory filters;
     private final Http2ClientImpl client2;
-    private static final ThreadFactory defaultFactory = Executors.defaultThreadFactory();
     private final LinkedList<TimeoutEvent> timeouts;
 
     public static HttpClientImpl create(HttpClientBuilderImpl builder) {
@@ -115,7 +121,6 @@
             throw new InternalError(e);
         }
         selmgr.setDaemon(true);
-        selmgr.setName("HttpSelector");
         filters = new FilterFactory();
         initFilters();
     }
@@ -135,7 +140,7 @@
      *  4)   - mark connection as blocking
      *  5)   - call AsyncEvent.handle()
      *
-     *  If exchange needs to block again, then call registerEvent() again
+     * If exchange needs to block again, then call registerEvent() again
      */
     void registerEvent(AsyncEvent exchange) throws IOException {
         selmgr.register(exchange);
@@ -145,35 +150,56 @@
         return client2;
     }
 
-    LinkedList<ByteBuffer> freelist = new LinkedList<>();
+    /**
+     * We keep one size of buffer on free list. That size may increase
+     * depending on demand. If that happens we dispose of free buffers
+     * that are smaller than new size.
+     */
+    private final LinkedList<ByteBuffer> freelist = new LinkedList<>();
+    int currentSize = BUFSIZE;
 
     @Override
-    public synchronized ByteBuffer getBuffer() {
-        if (freelist.isEmpty()) {
-            return ByteBuffer.allocate(BUFSIZE);
+    public synchronized ByteBuffer getBuffer(int size) {
+
+        ByteBuffer buf;
+        if (size == -1)
+            size = currentSize;
+
+        if (size > currentSize)
+            currentSize = size;
+
+        while (!freelist.isEmpty()) {
+            buf = freelist.removeFirst();
+            if (buf.capacity() < currentSize)
+                continue;
+            buf.clear();
+            return buf;
         }
-        return freelist.removeFirst();
+        return ByteBuffer.allocate(size);
     }
 
     @Override
     public synchronized void returnBuffer(ByteBuffer buffer) {
-        buffer.clear();
         freelist.add(buffer);
     }
 
+    @Override
+    public synchronized void setMinBufferSize(int n) {
+        currentSize = Math.max(n, currentSize);
+    }
 
     // Main loop for this client's selector
+    private final class SelectorManager extends Thread {
 
-    class SelectorManager extends Thread {
-        final Selector selector;
-        boolean closed;
-
-        final List<AsyncEvent> readyList;
-        final List<AsyncEvent> registrations;
+        private final Selector selector;
+        private volatile boolean closed;
+        private final List<AsyncEvent> readyList;
+        private final List<AsyncEvent> registrations;
 
         SelectorManager() throws IOException {
-            readyList = new LinkedList<>();
-            registrations = new LinkedList<>();
+            super(null, null, "SelectorManager", 0, false);
+            readyList = new ArrayList<>();
+            registrations = new ArrayList<>();
             selector = Selector.open();
         }
 
@@ -193,32 +219,13 @@
             closed = true;
             try {
                 selector.close();
-            } catch (IOException e) {}
-        }
-
-        private List<AsyncEvent> copy(List<AsyncEvent> list) {
-            LinkedList<AsyncEvent> c = new LinkedList<>();
-            for (AsyncEvent e : list) {
-                c.add(e);
-            }
-            return c;
-        }
-
-        String opvals(int i) {
-            StringBuilder sb = new StringBuilder();
-            if ((i & OP_READ) != 0)
-                sb.append("OP_READ ");
-            if ((i & OP_CONNECT) != 0)
-                sb.append("OP_CONNECT ");
-            if ((i & OP_WRITE) != 0)
-                sb.append("OP_WRITE ");
-            return sb.toString();
+            } catch (IOException ignored) { }
         }
 
         @Override
         public void run() {
             try {
-                while (true) {
+                while (!Thread.currentThread().isInterrupted()) {
                     synchronized (this) {
                         for (AsyncEvent exchange : registrations) {
                             SelectableChannel c = exchange.channel();
@@ -229,7 +236,7 @@
                                 if (key == null) {
                                     sa = new SelectorAttachment(c, selector);
                                 } else {
-                                    sa = (SelectorAttachment)key.attachment();
+                                    sa = (SelectorAttachment) key.attachment();
                                 }
                                 sa.register(exchange);
                             } catch (IOException e) {
@@ -243,6 +250,7 @@
                     }
                     long timeval = getTimeoutValue();
                     long now = System.currentTimeMillis();
+                    //debugPrint(selector);
                     int n = selector.select(timeval);
                     if (n == 0) {
                         signalTimeouts(now);
@@ -251,7 +259,7 @@
                     Set<SelectionKey> keys = selector.selectedKeys();
 
                     for (SelectionKey key : keys) {
-                        SelectorAttachment sa = (SelectorAttachment)key.attachment();
+                        SelectorAttachment sa = (SelectorAttachment) key.attachment();
                         int eventsOccurred = key.readyOps();
                         sa.events(eventsOccurred).forEach(readyList::add);
                         sa.resetInterestOps(eventsOccurred);
@@ -260,10 +268,8 @@
                     selector.selectedKeys().clear();
 
                     for (AsyncEvent exchange : readyList) {
-                        if (exchange instanceof AsyncEvent.Blocking) {
+                        if (exchange.blocking()) {
                             exchange.channel().configureBlocking(true);
-                        } else {
-                            assert exchange instanceof AsyncEvent.NonBlocking;
                         }
                         executor.synchronize();
                         handleEvent(exchange); // will be delegated to executor
@@ -272,14 +278,26 @@
                 }
             } catch (Throwable e) {
                 if (!closed) {
-                    System.err.println("HttpClientImpl terminating on error");
                     // This terminates thread. So, better just print stack trace
                     String err = Utils.stackTrace(e);
                     Log.logError("HttpClientImpl: fatal error: " + err);
                 }
+            } finally {
+                shutdown();
             }
         }
 
+        void debugPrint(Selector selector) {
+            System.err.println("Selector: debugprint start");
+            Set<SelectionKey> keys = selector.keys();
+            for (SelectionKey key : keys) {
+                SelectableChannel c = key.channel();
+                int ops = key.interestOps();
+                System.err.printf("selector chan:%s ops:%d\n", c, ops);
+            }
+            System.err.println("Selector: debugprint end");
+        }
+
         void handleEvent(AsyncEvent e) {
             if (closed) {
                 e.abort();
@@ -303,7 +321,7 @@
         private final SelectableChannel chan;
         private final Selector selector;
         private final ArrayList<AsyncEvent> pending;
-        private int interestops;
+        private int interestOps;
 
         SelectorAttachment(SelectableChannel chan, Selector selector) {
             this.pending = new ArrayList<>();
@@ -312,53 +330,53 @@
         }
 
         void register(AsyncEvent e) throws ClosedChannelException {
-            int newops = e.interestOps();
-            boolean reRegister = (interestops & newops) != newops;
-            interestops |= newops;
+            int newOps = e.interestOps();
+            boolean reRegister = (interestOps & newOps) != newOps;
+            interestOps |= newOps;
             pending.add(e);
             if (reRegister) {
                 // first time registration happens here also
-                chan.register(selector, interestops, this);
+                chan.register(selector, interestOps, this);
             }
         }
 
-        int interestOps() {
-            return interestops;
-        }
-
         /**
          * Returns a Stream<AsyncEvents> containing only events that are
-         * registered with the given {@code interestop}.
+         * registered with the given {@code interestOps}.
          */
-        Stream<AsyncEvent> events(int interestop) {
+        Stream<AsyncEvent> events(int interestOps) {
             return pending.stream()
-                          .filter(ev -> (ev.interestOps() & interestop) != 0);
+                    .filter(ev -> (ev.interestOps() & interestOps) != 0);
         }
 
         /**
-         * Removes any events with the given {@code interestop}, and if no
+         * Removes any events with the given {@code interestOps}, and if no
          * events remaining, cancels the associated SelectionKey.
          */
-        void resetInterestOps(int interestop) {
-            int newops = 0;
+        void resetInterestOps(int interestOps) {
+            int newOps = 0;
 
             Iterator<AsyncEvent> itr = pending.iterator();
             while (itr.hasNext()) {
                 AsyncEvent event = itr.next();
                 int evops = event.interestOps();
-                if ((evops & interestop) != 0) {
+                if (event.repeating()) {
+                    newOps |= evops;
+                    continue;
+                }
+                if ((evops & interestOps) != 0) {
                     itr.remove();
                 } else {
-                    newops |= evops;
+                    newOps |= evops;
                 }
             }
 
-            interestops = newops;
+            this.interestOps = newOps;
             SelectionKey key = chan.keyFor(selector);
-            if (newops == 0) {
+            if (newOps == 0) {
                 key.cancel();
             } else {
-                key.interestOps(newops);
+                key.interestOps(newOps);
             }
         }
     }
@@ -366,7 +384,8 @@
     /**
      * Creates a HttpRequest associated with this group.
      *
-     * @throws IllegalStateException if the group has been stopped
+     * @throws IllegalStateException
+     *         if the group has been stopped
      */
     @Override
     public HttpRequestBuilderImpl request() {
@@ -376,7 +395,8 @@
     /**
      * Creates a HttpRequest associated with this group.
      *
-     * @throws IllegalStateException if the group has been stopped
+     * @throws IllegalStateException
+     *         if the group has been stopped
      */
     @Override
     public HttpRequestBuilderImpl request(URI uri) {
@@ -444,16 +464,12 @@
         return version.equals(Version.HTTP_2);
     }
 
-    //void setHttp2NotSupported(String host) {
-        //http2NotSupported.put(host, false);
-    //}
-
-    final void initFilters() {
+    private void initFilters() {
         addFilter(AuthenticationFilter.class);
         addFilter(RedirectFilter.class);
     }
 
-    final void addFilter(Class<? extends HeaderFilter> f) {
+    private void addFilter(Class<? extends HeaderFilter> f) {
         filters.addFilter(f);
     }
 
@@ -479,14 +495,14 @@
                 iter.previous();
                 break;
             } else if (!iter.hasNext()) {
-                event.delta = event.timeval - listval ;
+                event.delta = event.timeval - listval;
             }
         }
         iter.add(event);
         selmgr.wakeupSelector();
     }
 
-    synchronized void signalTimeouts(long then) {
+    private synchronized void signalTimeouts(long then) {
         if (timeouts.isEmpty()) {
             return;
         }
@@ -532,12 +548,12 @@
     // used for the connection window
     int getReceiveBufferSize() {
         return Utils.getIntegerNetProperty(
-                "sun.net.httpclient.connectionWindowSize", 256 * 1024
+                "java.net.httpclient.connectionWindowSize", 256 * 1024
         );
     }
 
     // returns 0 meaning block forever, or a number of millis to block for
-    synchronized long getTimeoutValue() {
+    private synchronized long getTimeoutValue() {
         if (timeouts.isEmpty()) {
             return 0;
         } else {
--- a/jdk/src/java.httpclient/share/classes/java/net/http/HttpConnection.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/HttpConnection.java	Thu Apr 28 23:08:16 2016 -0700
@@ -23,9 +23,8 @@
  */
 package java.net.http;
 
-import java.io.FileOutputStream;
+import java.io.Closeable;
 import java.io.IOException;
-import java.io.PrintStream;
 import java.net.InetSocketAddress;
 import java.nio.ByteBuffer;
 import java.nio.channels.SocketChannel;
@@ -42,7 +41,17 @@
  *      SSLConnection: TLS channel direct to server
  *      SSLTunnelConnection: TLS channel via (CONNECT) proxy tunnel
  */
-abstract class HttpConnection implements BufferHandler {
+abstract class HttpConnection implements BufferHandler, Closeable {
+
+    protected final static ByteBuffer emptyBuf = Utils.EMPTY_BYTEBUFFER;
+
+    enum Mode {
+        BLOCKING,
+        NON_BLOCKING,
+        ASYNC
+    }
+
+    protected Mode mode;
 
     // address we are connected to. Could be a server or a proxy
     final InetSocketAddress address;
@@ -52,6 +61,7 @@
     HttpConnection(InetSocketAddress address, HttpClientImpl client) {
         this.address = address;
         this.client = client;
+        this.buffer = emptyBuf;
     }
 
     /**
@@ -68,7 +78,21 @@
      */
     public static HttpConnection getConnection(InetSocketAddress addr,
                                                HttpRequestImpl request) {
-        return getConnectionImpl(addr, request);
+        return getConnectionImpl(addr, request, null);
+    }
+
+    /**
+     * Called specifically to get an async connection for HTTP/2 over SSL.
+     *
+     * @param addr
+     * @param request
+     * @param http2
+     * @return
+     */
+    public static HttpConnection getConnection(InetSocketAddress addr,
+        HttpRequestImpl request, Http2Connection http2) {
+
+        return getConnectionImpl(addr, request, http2);
     }
 
     public abstract void connect() throws IOException, InterruptedException;
@@ -93,7 +117,7 @@
     // at beginning of response.
     ByteBuffer getRemaining() {
         ByteBuffer b = buffer;
-        buffer = null;
+        buffer = emptyBuf;
         return b;
     }
 
@@ -123,17 +147,18 @@
     }
 
     private static HttpConnection getSSLConnection(InetSocketAddress addr,
-                                                   InetSocketAddress proxy,
-                                                   HttpRequestImpl request,
-                                                   String[] alpn) {
+            InetSocketAddress proxy, HttpRequestImpl request,
+            String[] alpn, Http2Connection http2) {
         HttpClientImpl client = request.client();
         if (proxy != null) {
             return new SSLTunnelConnection(addr,
                                            client,
                                            proxy,
                                            request.getAccessControlContext());
+        } else if (http2 == null) {
+            return new SSLConnection(addr, client, alpn);
         } else {
-            return new SSLConnection(addr, client, alpn);
+            return new AsyncSSLConnection(addr, client, alpn);
         }
     }
 
@@ -142,7 +167,8 @@
      * none available.
      */
     private static HttpConnection getConnectionImpl(InetSocketAddress addr,
-                                                    HttpRequestImpl request) {
+            HttpRequestImpl request, Http2Connection http2) {
+
         HttpConnection c;
         HttpClientImpl client = request.client();
         InetSocketAddress proxy = request.proxy();
@@ -167,7 +193,7 @@
             if (c != null) {
                 return c;
             } else {
-                return getSSLConnection(addr, proxy, request, alpn);
+                return getSSLConnection(addr, proxy, request, alpn, http2);
             }
         }
     }
@@ -223,64 +249,16 @@
         return address;
     }
 
-    void configureBlocking(boolean mode) throws IOException {
-        channel().configureBlocking(mode);
+    synchronized void configureMode(Mode mode) throws IOException {
+        this.mode = mode;
+        if (mode == Mode.BLOCKING)
+            channel().configureBlocking(true);
+        else
+            channel().configureBlocking(false);
     }
 
     abstract ConnectionPool.CacheKey cacheKey();
 
-    /*
-    static PrintStream ps;
-
-    static {
-        try {
-            String propval = Utils.getNetProperty("java.net.httpclient.showData");
-            if (propval != null && propval.equalsIgnoreCase("true")) {
-                ps = new PrintStream(new FileOutputStream("/tmp/httplog.txt"), false);
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-    }
-
-    synchronized final void debugPrint(String s, ByteBuffer b) {
-        ByteBuffer[] bufs = new ByteBuffer[1];
-        bufs[0] = b;
-        debugPrint(s, bufs, 0, 1);
-    }
-
-    synchronized final void debugPrint(String s,
-                                       ByteBuffer[] bufs,
-                                       int start,
-                                       int number) {
-        if (ps == null) {
-            return;
-        }
-
-        ps.printf("\n%s:\n", s);
-
-        for (int i=start; i<start+number; i++) {
-            ByteBuffer b = bufs[i].duplicate();
-            while (b.hasRemaining()) {
-                int c = b.get();
-                if (c == 10) {
-                    ps.printf("LF \n");
-                } else if (c == 13) {
-                    ps.printf(" CR ");
-                } else if (c == 0x20) {
-                    ps.printf("_");
-                } else if (c > 0x20 && c <= 0x7F) {
-                    ps.printf("%c", (char)c);
-                } else {
-                    ps.printf("0x%02x ", c);
-                }
-            }
-        }
-        ps.printf("\n---------------------\n");
-    }
-
-    */
-
     // overridden in SSL only
     SSLParameters sslParameters() {
         return null;
@@ -296,7 +274,8 @@
     /**
      * Closes this connection, by returning the socket to its connection pool.
      */
-    abstract void close();
+    @Override
+    public abstract void close();
 
     /**
      * Returns a ByteBuffer with data, or null if EOF.
@@ -356,12 +335,17 @@
     }
 
     @Override
-    public final ByteBuffer getBuffer() {
-        return client.getBuffer();
+    public final ByteBuffer getBuffer(int n) {
+        return client.getBuffer(n);
     }
 
     @Override
     public final void returnBuffer(ByteBuffer buffer) {
         client.returnBuffer(buffer);
     }
+
+    @Override
+    public final void setMinBufferSize(int n) {
+        client.setMinBufferSize(n);
+    }
 }
--- a/jdk/src/java.httpclient/share/classes/java/net/http/HttpHeadersImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/HttpHeadersImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -24,44 +24,22 @@
 package java.net.http;
 
 import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
+import java.util.TreeMap;
 
 /**
  * Implementation of HttpHeaders.
  */
-class HttpHeadersImpl implements HttpHeaders1 {
+class HttpHeadersImpl implements HttpHeaders {
 
-    private final HashMap<String,List<String>> headers;
-    private boolean isUnmodifiable = false;
+    private final TreeMap<String,List<String>> headers;
 
     public HttpHeadersImpl() {
-        headers = new HashMap<>();
-    }
-
-    /**
-     * Replace all List<String> in headers with unmodifiable Lists. Call
-     * this only after all headers are added. The headers HashMap
-     * is wrapped with an unmodifiable HashMap in map()
-     */
-    @Override
-    public void makeUnmodifiable() {
-        if (isUnmodifiable)
-            return;
-
-        Set<String> keys = new HashSet<>(headers.keySet());
-        for (String key : keys) {
-            List<String> values = headers.remove(key);
-            if (values != null) {
-                headers.put(key, Collections.unmodifiableList(values));
-            }
-        }
-        isUnmodifiable = true;
+        headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
     }
 
     @Override
@@ -88,7 +66,7 @@
 
     public HttpHeadersImpl deepCopy() {
         HttpHeadersImpl h1 = new HttpHeadersImpl();
-        HashMap<String,List<String>> headers1 = h1.headers;
+        TreeMap<String,List<String>> headers1 = h1.headers;
         Set<String> keys = headers.keySet();
         for (String key : keys) {
             List<String> vals = headers.get(key);
@@ -98,22 +76,13 @@
         return h1;
     }
 
-    private List<String> getOrCreate(String name) {
-        List<String> l = headers.get(name);
-        if (l == null) {
-            l = new LinkedList<>();
-            headers.put(name, l);
-        }
-        return l;
-    }
-
     void addHeader(String name, String value) {
-        List<String> l = getOrCreate(name);
-        l.add(value);
+        headers.computeIfAbsent(name, k -> new LinkedList<>())
+               .add(value);
     }
 
     void setHeader(String name, String value) {
-        List<String> l = getOrCreate(name);
+        List<String> l = headers.computeIfAbsent(name, k -> new LinkedList<>());
         l.clear();
         l.add(value);
     }
@@ -122,7 +91,7 @@
     public Optional<Long> firstValueAsLong(String name) {
         List<String> l = headers.get(name);
         if (l == null) {
-            return Optional.ofNullable(null);
+            return Optional.empty();
         } else {
             String v = l.get(0);
             Long lv = Long.parseLong(v);
@@ -133,4 +102,4 @@
     void clear() {
         headers.clear();
     }
-}
+}
\ No newline at end of file
--- a/jdk/src/java.httpclient/share/classes/java/net/http/HttpRequestBuilderImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/HttpRequestBuilderImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -39,10 +39,11 @@
     private HttpClient.Version version;
     private final HttpClientImpl client;
     private ProxySelector proxy;
-    private long timeval = 0;
+    private long timeval;
 
     public HttpRequestBuilderImpl(HttpClientImpl client, URI uri) {
         this.client = client;
+        checkURI(uri);
         this.uri = uri;
         this.version = client.version();
         this.userHeaders = new HttpHeadersImpl();
@@ -58,10 +59,17 @@
     @Override
     public HttpRequestBuilderImpl uri(URI uri) {
         Objects.requireNonNull(uri);
+        checkURI(uri);
         this.uri = uri;
         return this;
     }
 
+    private static void checkURI(URI uri) {
+        String scheme = uri.getScheme().toLowerCase();
+        if (!scheme.equals("https") && !scheme.equals("http"))
+            throw new IllegalArgumentException("invalid URI scheme");
+    }
+
     @Override
     public HttpRequestBuilderImpl followRedirects(HttpClient.Redirect follow) {
         Objects.requireNonNull(follow);
--- a/jdk/src/java.httpclient/share/classes/java/net/http/HttpRequestImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/HttpRequestImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -30,16 +30,14 @@
 import java.net.http.HttpClient.Version;
 import java.net.http.HttpResponse.MultiProcessor;
 import java.util.concurrent.CompletableFuture;
-import java.net.SocketPermission;
 import java.security.AccessControlContext;
 import java.security.AccessController;
-import java.util.Set;
 import static java.net.http.HttpRedirectImpl.getRedirects;
 import java.util.Locale;
 
 class HttpRequestImpl extends HttpRequest {
 
-    private final HttpHeadersImpl userHeaders;
+    private final ImmutableHeaders userHeaders;
     private final HttpHeadersImpl systemHeaders;
     private final URI uri;
     private InetSocketAddress authority; // only used when URI not specified
@@ -56,6 +54,7 @@
     private boolean receiving;
     private AccessControlContext acc;
     private final long timeval;
+    private Stream.PushGroup<?> pushGroup;
 
     public HttpRequestImpl(HttpClientImpl client,
                            String method,
@@ -63,8 +62,8 @@
         this.client = client;
         this.method = method == null? "GET" : method;
         this.userHeaders = builder.headers() == null ?
-                new HttpHeadersImpl() : builder.headers();
-        dropDisallowedHeaders();
+                new ImmutableHeaders() :
+                new ImmutableHeaders(builder.headers(), Utils.ALLOWED_HEADERS);
         this.followRedirects = getRedirects(builder.followRedirects() == null ?
                 client.followRedirects() : builder.followRedirects());
         this.systemHeaders = new HttpHeadersImpl();
@@ -90,15 +89,13 @@
                            HttpRequestImpl other) {
         this.client = client;
         this.method = method == null? "GET" : method;
-        this.userHeaders = other.userHeaders == null ?
-                new HttpHeadersImpl() : other.userHeaders;
-        dropDisallowedHeaders();
+        this.userHeaders = other.userHeaders;
         this.followRedirects = getRedirects(other.followRedirects() == null ?
                 client.followRedirects() : other.followRedirects());
         this.systemHeaders = other.systemHeaders;
         this.uri = uri;
         this.expectContinue = other.expectContinue;
-        this.secure = other.secure;
+        this.secure = uri.getScheme().toLowerCase(Locale.US).equals("https");
         this.requestProcessor = other.requestProcessor;
         this.proxy = other.proxy;
         this.version = other.version;
@@ -115,7 +112,7 @@
         this.method = method;
         this.followRedirects = getRedirects(client.followRedirects());
         this.systemHeaders = new HttpHeadersImpl();
-        this.userHeaders = new HttpHeadersImpl();
+        this.userHeaders = new ImmutableHeaders();
         this.uri = null;
         this.proxy = null;
         this.requestProcessor = HttpRequest.noBody();
@@ -132,16 +129,52 @@
         return client;
     }
 
+    /**
+     * Creates a HttpRequestImpl from the given set of Headers and the associated
+     * "parent" request. Fields not taken from the headers are taken from the
+     * parent.
+     */
+    static HttpRequestImpl createPushRequest(HttpRequestImpl parent,
+            HttpHeadersImpl headers) throws IOException {
+
+        return new HttpRequestImpl(parent, headers);
+    }
+
+    // only used for push requests
+    private HttpRequestImpl(HttpRequestImpl parent, HttpHeadersImpl headers) throws IOException {
+        this.method = headers.firstValue(":method")
+                .orElseThrow(() -> new IOException("No method in Push Promise"));
+        String path = headers.firstValue(":path")
+                .orElseThrow(() -> new IOException("No path in Push Promise"));
+        String scheme = headers.firstValue(":scheme")
+                .orElseThrow(() -> new IOException("No scheme in Push Promise"));
+        String authority = headers.firstValue(":authority")
+                .orElseThrow(() -> new IOException("No authority in Push Promise"));
+        StringBuilder sb = new StringBuilder();
+        sb.append(scheme).append("://").append(authority).append(path);
+        this.uri = URI.create(sb.toString());
+
+        this.client = parent.client;
+        this.userHeaders = new ImmutableHeaders(headers, Utils.ALLOWED_HEADERS);
+        this.followRedirects = parent.followRedirects;
+        this.systemHeaders = parent.systemHeaders;
+        this.expectContinue = parent.expectContinue;
+        this.secure = parent.secure;
+        this.requestProcessor = parent.requestProcessor;
+        this.proxy = parent.proxy;
+        this.version = parent.version;
+        this.acc = parent.acc;
+        this.exchange = parent.exchange;
+        this.timeval = parent.timeval;
+    }
 
     @Override
     public String toString() {
-        return (uri == null ? "" : uri.toString()) + "/" + method + "("
-                + hashCode() + ")";
+        return (uri == null ? "" : uri.toString()) + " " + method;
     }
 
     @Override
     public HttpHeaders headers() {
-        userHeaders.makeUnmodifiable();
         return userHeaders;
     }
 
@@ -154,21 +187,6 @@
         systemHeaders.setHeader("HTTP2-Settings", h2client.getSettingsString());
     }
 
-    private static final Set<String>  DISALLOWED_HEADERS_SET = Set.of(
-        "authorization", "connection", "cookie", "content-length",
-        "date", "expect", "from", "host", "origin", "proxy-authorization",
-        "referer", "user-agent", "upgrade", "via", "warning");
-
-
-    // we silently drop headers that are disallowed
-    private void dropDisallowedHeaders() {
-        Set<String> hdrnames = userHeaders.directMap().keySet();
-
-        hdrnames.removeIf((s) ->
-              DISALLOWED_HEADERS_SET.contains(s.toLowerCase())
-        );
-    }
-
     private synchronized void receiving() {
         if (receiving) {
             throw new IllegalStateException("already receiving response");
@@ -176,6 +194,10 @@
         receiving = true;
     }
 
+    synchronized Stream.PushGroup<?> pushGroup() {
+        return pushGroup;
+    }
+
     /*
      * Response filters may result in a new HttpRequestImpl being created
      * (but still associated with the same API HttpRequest) and the process
@@ -200,10 +222,25 @@
             .thenApply((r) -> (HttpResponse)r);
     }
 
-    public <U> CompletableFuture<U>
-    sendAsyncMulti(HttpResponse.MultiProcessor<U> rspproc) {
-        // To change body of generated methods, choose Tools | Templates.
-        throw new UnsupportedOperationException("Not supported yet.");
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public synchronized <U> CompletableFuture<U>
+    multiResponseAsync(MultiProcessor<U> rspproc) {
+        if (System.getSecurityManager() != null) {
+            acc = AccessController.getContext();
+        }
+        this.pushGroup = new Stream.PushGroup<>(rspproc, this);
+        CompletableFuture<HttpResponse> cf = pushGroup.mainResponse();
+        responseAsync()
+            .whenComplete((HttpResponse r, Throwable t) -> {
+                if (r != null)
+                    cf.complete(r);
+                else
+                    cf.completeExceptionally(t);
+                pushGroup.pushError(t);
+            });
+        return (CompletableFuture<U>)pushGroup.groupResult();
     }
 
     @Override
@@ -255,7 +292,7 @@
     @Override
     public URI uri() { return uri; }
 
-    HttpHeadersImpl getUserHeaders() { return userHeaders; }
+    HttpHeaders getUserHeaders() { return userHeaders; }
 
     HttpHeadersImpl getSystemHeaders() { return systemHeaders; }
 
@@ -275,11 +312,4 @@
     }
 
     long timeval() { return timeval; }
-
-    @Override
-    public <U> CompletableFuture<U>
-    multiResponseAsync(MultiProcessor<U> rspproc) {
-        //To change body of generated methods, choose Tools | Templates.
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
 }
--- a/jdk/src/java.httpclient/share/classes/java/net/http/HttpResponse.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/HttpResponse.java	Thu Apr 28 23:08:16 2016 -0700
@@ -200,8 +200,12 @@
                 if (n == -1) {
                     throw new IOException("Bad Content-Disposition type");
                 }
-                String disposition = dispoHeader.substring(n + 9,
-                                                           dispoHeader.lastIndexOf(';'));
+                int lastsemi = dispoHeader.lastIndexOf(';');
+                String disposition;
+                if (lastsemi < n)
+                    disposition = dispoHeader.substring(n + 9);
+                else
+                    disposition = dispoHeader.substring(n + 9, lastsemi);
                 file = Paths.get(directory.toString(), disposition);
                 fc = FileChannel.open(file, openOptions);
                 return null;
@@ -727,11 +731,14 @@
             }
 
             private CompletableFuture<Path> getBody(HttpRequest req,
-                                                    CompletableFuture<HttpResponse> cf) {
+                                                    CompletableFuture<? extends HttpResponse> cf) {
                 URI u = req.uri();
                 String path = u.getPath();
+                if (path.startsWith("/"))
+                    path = path.substring(1);
+                final String fpath = path;
                 return cf.thenCompose((HttpResponse resp) -> {
-                    return resp.bodyAsync(HttpResponse.asFile(destination.resolve(path)));
+                    return resp.bodyAsync(HttpResponse.asFile(destination.resolve(fpath)));
                 });
             }
 
--- a/jdk/src/java.httpclient/share/classes/java/net/http/HttpResponseImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/HttpResponseImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -26,6 +26,7 @@
 package java.net.http;
 
 import java.io.IOException;
+import java.io.UncheckedIOException;
 import java.net.URI;
 import java.nio.ByteBuffer;
 import java.security.AccessControlContext;
@@ -42,17 +43,18 @@
     int responseCode;
     Exchange exchange;
     HttpRequestImpl request;
-    HttpHeaders1 headers;
-    HttpHeaders1 trailers;
+    HttpHeaders headers;
+    HttpHeaders trailers;
     SSLParameters sslParameters;
     URI uri;
     HttpClient.Version version;
     AccessControlContext acc;
     RawChannel rawchan;
     HttpConnection connection;
+    final Stream stream;
 
-    public HttpResponseImpl(int responseCode, Exchange exch, HttpHeaders1 headers,
-            HttpHeaders1 trailers, SSLParameters sslParameters,
+    public HttpResponseImpl(int responseCode, Exchange exch, HttpHeaders headers,
+            HttpHeaders trailers, SSLParameters sslParameters,
             HttpClient.Version version, HttpConnection connection) {
         this.responseCode = responseCode;
         this.exchange = exch;
@@ -63,6 +65,23 @@
         this.uri = request.uri();
         this.version = version;
         this.connection = connection;
+        this.stream = null;
+    }
+
+    // A response to a PUSH_PROMISE
+    public HttpResponseImpl(int responseCode, HttpRequestImpl pushRequest,
+            ImmutableHeaders headers,
+            Stream stream, SSLParameters sslParameters) {
+        this.responseCode = responseCode;
+        this.exchange = null;
+        this.request = pushRequest;
+        this.headers = headers;
+        this.trailers = null;
+        this.sslParameters = sslParameters;
+        this.uri = request.uri(); // TODO: take from headers
+        this.version = HttpClient.Version.HTTP_2;
+        this.connection = null;
+        this.stream = stream;
     }
 
     @Override
@@ -77,26 +96,35 @@
 
     @Override
     public HttpHeaders headers() {
-        headers.makeUnmodifiable();
         return headers;
     }
 
     @Override
     public HttpHeaders trailers() {
-        trailers.makeUnmodifiable();
         return trailers;
     }
 
 
     @Override
     public <T> T body(java.net.http.HttpResponse.BodyProcessor<T> processor) {
-        return exchange.responseBody(processor);
+        try {
+            if (exchange != null) {
+                return exchange.responseBody(processor);
+            } else {
+                return stream.responseBody(processor);
+            }
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
     }
 
     @Override
     public <T> CompletableFuture<T> bodyAsync(java.net.http.HttpResponse.BodyProcessor<T> processor) {
         acc = AccessController.getContext();
-        return exchange.responseBodyAsync(processor);
+        if (exchange != null)
+            return exchange.responseBodyAsync(processor);
+        else
+            return stream.responseBodyAsync(processor);
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/ImmutableHeaders.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2015, 2016, 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
+ */
+
+package java.net.http;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.TreeMap;
+import java.util.function.Predicate;
+
+/**
+ * Immutable HttpHeaders constructed from mutable HttpHeadersImpl.
+ */
+
+class ImmutableHeaders implements HttpHeaders {
+
+    private final Map<String,List<String>> map;
+
+    @SuppressWarnings("unchecked")
+    ImmutableHeaders() {
+        map = (Map<String,List<String>>)Collections.EMPTY_MAP;
+    }
+    // TODO: fix lower case issue. Must be lc for http/2 compares ignoreCase for http/1
+    ImmutableHeaders(HttpHeadersImpl h, Predicate<String> keyAllowed) {
+        Map<String,List<String>> src = h.directMap();
+        Map<String,List<String>> m = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+
+        src.forEach((key, value) -> {
+            if (keyAllowed.test(key))
+                m.put(key, Collections.unmodifiableList(value));
+        });
+        map = Collections.unmodifiableMap(m);
+    }
+
+    @Override
+    public Optional<String> firstValue(String name) {
+        List<String> l = map.get(name);
+        String v = l == null ? null : l.get(0);
+        return Optional.ofNullable(v);
+    }
+
+    @Override
+    public Optional<Long> firstValueAsLong(String name) {
+        return firstValue(name).map((v -> Long.parseLong(v)));
+    }
+
+    @Override
+    public List<String> allValues(String name) {
+        return map.get(name);
+    }
+
+    @Override
+    public Map<String, List<String>> map() {
+        return map;
+    }
+}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/Log.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/Log.java	Thu Apr 28 23:08:16 2016 -0700
@@ -26,7 +26,9 @@
 import java.util.Locale;
 
 /**
- * -Djava.net.HttpClient.log=errors,requests,headers,frames[:type:type2:..],content
+ * -Djava.net.HttpClient.log=
+ *          errors,requests,headers,
+ *          frames[:type:type2:..],content,ssl,trace
  *
  * Any of errors, requests, headers or content are optional.
  *
@@ -47,6 +49,7 @@
     public static final int CONTENT = 0x8;
     public static final int FRAMES = 0x10;
     public static final int SSL = 0x20;
+    public static final int TRACE = 0x40;
     static int logging;
 
     // Frame types: "control", "data", "window", "all"
@@ -81,8 +84,11 @@
                     case "ssl":
                         logging |= SSL;
                         break;
+                    case "trace":
+                        logging |= TRACE;
+                        break;
                     case "all":
-                        logging |= CONTENT|HEADERS|REQUESTS|FRAMES|ERRORS;
+                        logging |= CONTENT|HEADERS|REQUESTS|FRAMES|ERRORS|TRACE;
                         break;
                 }
                 if (val.startsWith("frames")) {
@@ -130,6 +136,10 @@
         return (logging & HEADERS) != 0;
     }
 
+    static boolean trace() {
+        return (logging & TRACE) != 0;
+    }
+
     static boolean ssl() {
         return (logging & SSL) != 0;
     }
@@ -138,9 +148,9 @@
         return (logging & FRAMES) != 0;
     }
 
-    static void logError(String s) {
+    static void logError(String s, Object... s1) {
         if (errors())
-            logger.log(Level.INFO, "ERROR: " + s);
+            logger.log(Level.INFO, "ERROR: " + s, s1);
     }
 
     static void logError(Throwable t) {
@@ -150,24 +160,50 @@
         }
     }
 
-    static void logSSL(String s) {
+    static void logSSL(String s, Object... s1) {
         if (ssl())
-            logger.log(Level.INFO, "SSL: " + s);
+            logger.log(Level.INFO, "SSL: " + s, s1);
+    }
+
+    static void logTrace(String s, Object... s1) {
+        if (trace()) {
+            String format = "TRACE: " + s;
+            logger.log(Level.INFO, format, s1);
+        }
+    }
+
+    static void logRequest(String s, Object... s1) {
+        if (requests())
+            logger.log(Level.INFO, "REQUEST: " + s, s1);
+    }
+
+    static void logResponse(String s, Object... s1) {
+        if (requests())
+            logger.log(Level.INFO, "RESPONSE: " + s, s1);
     }
 
-    static void logRequest(String s) {
-        if (requests())
-            logger.log(Level.INFO, "REQUEST: " + s);
+    static void logHeaders(String s, Object... s1) {
+        if (headers())
+            logger.log(Level.INFO, "HEADERS: " + s, s1);
+    }
+// START HTTP2
+    static boolean loggingFrame(Class<? extends Http2Frame> clazz) {
+        if (frametypes == ALL) {
+            return true;
+        }
+        if (clazz == DataFrame.class) {
+            return (frametypes & DATA) != 0;
+        } else if (clazz == WindowUpdateFrame.class) {
+            return (frametypes & WINDOW_UPDATES) != 0;
+        } else {
+            return (frametypes & CONTROL) != 0;
+        }
     }
 
-    static void logResponse(String s) {
-        if (requests())
-            logger.log(Level.INFO, "RESPONSE: " + s);
-    }
-
-    static void logHeaders(String s) {
-        if (headers())
-            logger.log(Level.INFO, "HEADERS: " + s);
+    static void logFrames(Http2Frame f, String direction) {
+        if (frames() && loggingFrame(f.getClass())) {
+            logger.log(Level.INFO, "FRAME: " + direction + ": " + f.toString());
+        }
     }
 
     // not instantiable
--- a/jdk/src/java.httpclient/share/classes/java/net/http/MultiExchange.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/MultiExchange.java	Thu Apr 28 23:08:16 2016 -0700
@@ -54,7 +54,7 @@
 
     final static int DEFAULT_MAX_ATTEMPTS = 5;
     final static int max_attempts = Utils.getIntegerNetProperty(
-            "sun.net.httpclient.redirects.retrylimit", DEFAULT_MAX_ATTEMPTS
+            "java.net.httpclient.redirects.retrylimit", DEFAULT_MAX_ATTEMPTS
     );
 
     private final List<HeaderFilter> filters;
@@ -187,8 +187,7 @@
     public CompletableFuture<HttpResponseImpl> responseAsync(Void v) {
         CompletableFuture<HttpResponseImpl> cf;
         if (++attempts > max_attempts) {
-            cf = new CompletableFuture<>();
-            cf.completeExceptionally(new IOException("Too many retries"));
+            cf = CompletableFuture.failedFuture(new IOException("Too many retries"));
         } else {
             if (currentreq.timeval() != 0) {
                 // set timer
@@ -241,7 +240,6 @@
      * completed exceptionally.
      */
     private CompletableFuture<HttpResponseImpl> getExceptionalCF(Throwable t) {
-        CompletableFuture<HttpResponseImpl> error = new CompletableFuture<>();
         if ((t instanceof CompletionException) || (t instanceof ExecutionException)) {
             if (t.getCause() != null) {
                 t = t.getCause();
@@ -250,8 +248,7 @@
         if (cancelled && t instanceof IOException) {
             t = new HttpTimeoutException("request timed out");
         }
-        error.completeExceptionally(t);
-        return error;
+        return CompletableFuture.failedFuture(t);
     }
 
     <T> T responseBody(HttpResponse.BodyProcessor<T> processor) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/OutgoingHeaders.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2015, 2016, 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
+ */
+
+package java.net.http;
+
+import java.io.IOException;
+
+/**
+ * Contains all parameters for outgoing headers. Is converted to
+ * HeadersFrame and ContinuationFrames by Http2Connection.
+ */
+class OutgoingHeaders extends Http2Frame {
+
+    int streamDependency;
+    int weight;
+    boolean exclusive;
+    Stream stream;
+
+    public static final int PRIORITY = 0x20;
+
+    HttpHeaders user, system;
+
+    OutgoingHeaders(HttpHeaders hdrs1, HttpHeaders hdrs2, Stream stream) {
+        this.user = hdrs2;
+        this.system = hdrs1;
+        this.stream = stream;
+    }
+
+    public void setPriority(int streamDependency, boolean exclusive, int weight) {
+        this.streamDependency = streamDependency;
+        this.exclusive = exclusive;
+        this.weight = weight;
+        this.flags |= PRIORITY;
+    }
+
+    public int getStreamDependency() {
+        return streamDependency;
+    }
+
+    public int getWeight() {
+        return weight;
+    }
+
+    public boolean getExclusive() {
+        return exclusive;
+    }
+
+    public Stream getStream() {
+        return stream;
+    }
+
+    public HttpHeaders getUserHeaders() {
+        return user;
+    }
+
+    public HttpHeaders getSystemHeaders() {
+        return system;
+    }
+
+    @Override
+    void readIncomingImpl(ByteBufferConsumer bc) throws IOException {
+        throw new UnsupportedOperationException("Not supported.");
+    }
+
+    @Override
+    void computeLength() {
+        //To change body of generated methods, choose Tools | Templates.
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/Pair.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/Pair.java	Thu Apr 28 23:08:16 2016 -0700
@@ -43,4 +43,9 @@
     static <T, U> Pair<T, U> pair(T first, U second) {
         return new Pair<>(first, second);
     }
+
+    @Override
+    public String toString() {
+        return "(" + first + ", " + second + ")";
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/PingFrame.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2015, 2016, 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
+ */
+
+package java.net.http;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+class PingFrame extends Http2Frame {
+
+    PingFrame() {
+        type = TYPE;
+    }
+
+    byte[] data;
+
+    public final static int TYPE = 0x6;
+
+    // Flags
+    public static final int ACK = 0x1;
+
+    @Override
+    String flagAsString(int flag) {
+        switch (flag) {
+        case ACK:
+            return "ACK";
+        }
+        return super.flagAsString(flag);
+    }
+
+    public void setData(byte[] data) {
+        if (data.length != 8) {
+            throw new IllegalArgumentException("Ping data not 8 bytes");
+        }
+        this.data = data;
+    }
+
+    public byte[] getData() {
+        return data;
+    }
+
+    @Override
+    void readIncomingImpl(ByteBufferConsumer bc) throws IOException {
+        if (length != 8) {
+            throw new IOException("Invalid Ping frame");
+        }
+        data = bc.getBytes(8);
+    }
+
+    @Override
+    void writeOutgoing(ByteBufferGenerator bg) {
+        if (data == null) {
+            data = new byte[] {0, 0, 0, 0, 0 ,0, 0, 0};
+        }
+        super.writeOutgoing(bg);
+        ByteBuffer buf = bg.getBuffer(8);
+        buf.put(data);
+    }
+
+    @Override
+    void computeLength() {
+        length = 8;
+    }
+}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/PlainHttpConnection.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/PlainHttpConnection.java	Thu Apr 28 23:08:16 2016 -0700
@@ -31,20 +31,43 @@
 import java.nio.channels.SelectionKey;
 import java.nio.channels.SocketChannel;
 import java.util.concurrent.CompletableFuture;
+import java.util.function.Consumer;
 
 /**
- * Plain raw TCP connection direct to destination
+ * Plain raw TCP connection direct to destination. 2 modes
+ * 1) Blocking used by http/1. In this case the connect is actually non
+ *    blocking but the request is sent blocking. The first byte of a response
+ *    is received non-blocking and the remainder of the response is received
+ *    blocking
+ * 2) Non-blocking. In this case (for http/2) the connection is actually opened
+ *    blocking but all reads and writes are done non-blocking under the
+ *    control of a Http2Connection object.
  */
-class PlainHttpConnection extends HttpConnection {
+class PlainHttpConnection extends HttpConnection implements AsyncConnection {
 
     protected SocketChannel chan;
     private volatile boolean connected;
     private boolean closed;
+    Consumer<ByteBuffer> asyncReceiver;
+    Consumer<Throwable> errorReceiver;
+    Queue<ByteBuffer> asyncOutputQ;
+    final Object reading = new Object();
+    final Object writing = new Object();
 
-    class ConnectEvent extends AsyncEvent implements AsyncEvent.Blocking {
+    @Override
+    public void startReading() {
+        try {
+            client.registerEvent(new ReadEvent());
+        } catch (IOException e) {
+            shutdown();
+        }
+    }
+
+    class ConnectEvent extends AsyncEvent {
         CompletableFuture<Void> cf;
 
         ConnectEvent(CompletableFuture<Void> cf) {
+            super(AsyncEvent.BLOCKING);
             this.cf = cf;
         }
 
@@ -112,14 +135,62 @@
 
     @Override
     long write(ByteBuffer[] buffers, int start, int number) throws IOException {
-        //debugPrint("Send", buffers, start, number);
-        return chan.write(buffers, start, number);
+        if (mode != Mode.ASYNC)
+            return chan.write(buffers, start, number);
+        // async
+        synchronized(writing) {
+            int qlen = asyncOutputQ.size();
+            ByteBuffer[] bufs = Utils.reduce(buffers, start, number);
+            long n = Utils.remaining(bufs);
+            asyncOutputQ.putAll(bufs);
+            if (qlen == 0)
+                asyncOutput();
+            return n;
+        }
+    }
+
+    ByteBuffer asyncBuffer = null;
+
+    void asyncOutput() {
+        synchronized (writing) {
+            try {
+                while (true) {
+                    if (asyncBuffer == null) {
+                        asyncBuffer = asyncOutputQ.poll();
+                        if (asyncBuffer == null) {
+                            return;
+                        }
+                    }
+                    if (!asyncBuffer.hasRemaining()) {
+                        asyncBuffer = null;
+                        continue;
+                    }
+                    int n = chan.write(asyncBuffer);
+                    //System.err.printf("Written %d bytes to chan\n", n);
+                    if (n == 0) {
+                        client.registerEvent(new WriteEvent());
+                        return;
+                    }
+                }
+            } catch (IOException e) {
+                shutdown();
+            }
+        }
     }
 
     @Override
     long write(ByteBuffer buffer) throws IOException {
-        //debugPrint("Send", buffer);
-        return chan.write(buffer);
+        if (mode != Mode.ASYNC)
+            return chan.write(buffer);
+        // async
+        synchronized(writing) {
+            int qlen = asyncOutputQ.size();
+            long n = buffer.remaining();
+            asyncOutputQ.put(buffer);
+            if (qlen == 0)
+                asyncOutput();
+            return n;
+        }
     }
 
     @Override
@@ -131,7 +202,7 @@
      * Close this connection
      */
     @Override
-    synchronized void close() {
+    public synchronized void close() {
         if (closed)
             return;
         closed = true;
@@ -155,14 +226,49 @@
         return buf;
     }
 
+    void shutdown() {
+        close();
+        errorReceiver.accept(new IOException("Connection aborted"));
+    }
+
+    void asyncRead() {
+        synchronized (reading) {
+            try {
+                while (true) {
+                    ByteBuffer buf = getBuffer();
+                    int n = chan.read(buf);
+                    //System.err.printf("Read %d bytes from chan\n", n);
+                    if (n == -1) {
+                        throw new IOException();
+                    }
+                    if (n == 0) {
+                        returnBuffer(buf);
+                        return;
+                    }
+                    buf.flip();
+                    asyncReceiver.accept(buf);
+                }
+            } catch (IOException e) {
+                shutdown();
+            }
+        }
+    }
+
     @Override
     protected int readImpl(ByteBuffer buf) throws IOException {
         int mark = buf.position();
-        int n = chan.read(buf);
+        int n;
+        // FIXME: this hack works in conjunction with the corresponding change
+        // in java.net.http.RawChannel.registerEvent
+        if ((n = buffer.remaining()) != 0) {
+            buf.put(buffer);
+        } else {
+            n = chan.read(buf);
+        }
         if (n == -1) {
             return -1;
         }
-        Utils.flipToMark(buffer, mark);
+        Utils.flipToMark(buf, mark);
         String s = "Receive (" + n + " bytes) ";
         //debugPrint(s, buf);
         return n;
@@ -178,10 +284,67 @@
         return connected;
     }
 
-    class ReceiveResponseEvent extends AsyncEvent implements AsyncEvent.Blocking {
+    // used for all output in HTTP/2
+    class WriteEvent extends AsyncEvent {
+        WriteEvent() {
+            super(0);
+        }
+
+        @Override
+        public SelectableChannel channel() {
+            return chan;
+        }
+
+        @Override
+        public int interestOps() {
+            return SelectionKey.OP_WRITE;
+        }
+
+        @Override
+        public void handle() {
+            asyncOutput();
+        }
+
+        @Override
+        public void abort() {
+            shutdown();
+        }
+    }
+
+    // used for all input in HTTP/2
+    class ReadEvent extends AsyncEvent {
+        ReadEvent() {
+            super(AsyncEvent.REPEATING); // && !BLOCKING
+        }
+
+        @Override
+        public SelectableChannel channel() {
+            return chan;
+        }
+
+        @Override
+        public int interestOps() {
+            return SelectionKey.OP_READ;
+        }
+
+        @Override
+        public void handle() {
+            asyncRead();
+        }
+
+        @Override
+        public void abort() {
+            shutdown();
+        }
+
+    }
+
+    // used in blocking channels only
+    class ReceiveResponseEvent extends AsyncEvent {
         CompletableFuture<Void> cf;
 
         ReceiveResponseEvent(CompletableFuture<Void> cf) {
+            super(AsyncEvent.BLOCKING);
             this.cf = cf;
         }
         @Override
@@ -216,6 +379,15 @@
     }
 
     @Override
+    public synchronized void setAsyncCallbacks(Consumer<ByteBuffer> asyncReceiver,
+            Consumer<Throwable> errorReceiver) {
+        this.asyncReceiver = asyncReceiver;
+        this.errorReceiver = errorReceiver;
+        asyncOutputQ = new Queue<>();
+        asyncOutputQ.registerPutCallback(this::asyncOutput);
+    }
+
+    @Override
     CompletableFuture<Void> whenReceivingResponse() {
         CompletableFuture<Void> cf = new CompletableFuture<>();
         try {
--- a/jdk/src/java.httpclient/share/classes/java/net/http/PlainTunnelingConnection.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/PlainTunnelingConnection.java	Thu Apr 28 23:08:16 2016 -0700
@@ -111,7 +111,7 @@
     }
 
     @Override
-    void close() {
+    public void close() {
         delegate.close();
         connected = false;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/PriorityFrame.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2015, 2016, 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
+ */
+
+package java.net.http;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+class PriorityFrame extends Http2Frame {
+
+    int streamDependency;
+    int weight;
+    boolean exclusive;
+
+    public final static int TYPE = 0x2;
+
+    PriorityFrame() {
+        type = TYPE;
+    }
+
+    public PriorityFrame(int streamDependency, boolean exclusive, int weight) {
+        this.streamDependency = streamDependency;
+        this.exclusive = exclusive;
+        this.weight = weight;
+        this.type = TYPE;
+    }
+
+    int streamDependency() {
+        return streamDependency;
+    }
+
+    int weight() {
+        return weight;
+    }
+
+    boolean exclusive() {
+        return exclusive;
+    }
+
+    @Override
+    void readIncomingImpl(ByteBufferConsumer bc) throws IOException {
+        int x = bc.getInt();
+        exclusive = (x & 0x80000000) != 0;
+        streamDependency = x & 0x7fffffff;
+        weight = bc.getByte();
+    }
+
+    @Override
+    void writeOutgoing(ByteBufferGenerator bg) {
+        super.writeOutgoing(bg);
+        ByteBuffer buf = bg.getBuffer(5);
+        int x = exclusive ? (1 << 31) + streamDependency : streamDependency;
+        buf.putInt(x);
+        buf.put((byte)weight);
+    }
+
+    @Override
+    void computeLength() {
+        length = 5;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/PushPromiseFrame.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2015, 2016, 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
+ */
+
+package java.net.http;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+class PushPromiseFrame extends HeaderFrame {
+
+    int padLength;
+    int promisedStream;
+
+    PushPromiseFrame() {
+        type = TYPE;
+    }
+
+    public static final int TYPE = 0x5;
+
+    // Flags
+    public static final int END_HEADERS = 0x4;
+    public static final int PADDED = 0x8;
+
+    @Override
+    public String toString() {
+        return super.toString() + " promisedStreamid: " + promisedStream
+                + " headerLength: " + headerLength;
+    }
+
+    @Override
+    String flagAsString(int flag) {
+        switch (flag) {
+        case PADDED:
+            return "PADDED";
+        case END_HEADERS:
+            return "END_HEADERS";
+        }
+        return super.flagAsString(flag);
+    }
+
+    public void setPadLength(int padLength) {
+        this.padLength = padLength;
+        flags |= PADDED;
+    }
+
+    public void setPromisedStream(int stream) {
+        this.promisedStream = stream;
+    }
+
+    public int getPromisedStream() {
+        return promisedStream;
+    }
+
+    /**
+     */
+    @Override
+    void readIncomingImpl(ByteBufferConsumer bc) throws IOException {
+        if ((flags & PADDED) != 0) {
+            padLength = bc.getByte();
+            headerLength = length - (padLength + 5);
+        } else
+            headerLength = length - 4;
+
+        promisedStream = bc.getInt() & 0x7fffffff;
+        headerBlocks = bc.getBuffers(headerLength);
+    }
+
+    @Override
+    void computeLength() {
+        int len = 0;
+        if ((flags & PADDED) != 0) {
+            len += (1 + padLength);
+        }
+        len += (4 + headerLength);
+        this.length = len;
+    }
+
+    @Override
+    void writeOutgoing(ByteBufferGenerator bg) {
+        super.writeOutgoing(bg);
+        ByteBuffer buf = bg.getBuffer(length);
+        if ((flags & PADDED) != 0) {
+            buf.put((byte)padLength);
+        }
+        buf.putInt(promisedStream);
+        for (int i=0; i<headerBlocks.length; i++) {
+            bg.addByteBuffer(headerBlocks[i]);
+        }
+        if ((flags & PADDED) != 0) {
+            bg.addPadding(padLength);
+        }
+    }
+
+    @Override
+    public boolean endHeaders() {
+        return getFlag(END_HEADERS);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/Queue.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2015, 2016, 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
+ */
+
+package java.net.http;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.LinkedList;
+
+// Each stream has one of these for input. Each Http2Connection has one
+// for output. Can be used blocking or asynchronously.
+
+class Queue<T> implements Closeable {
+
+    private final LinkedList<T> q = new LinkedList<>();
+    private volatile boolean closed = false;
+    private Runnable callback;
+    private boolean forceCallback;
+    private int waiters; // true if someone waiting
+
+    synchronized void putAll(T[] objs) throws IOException {
+        if (closed) {
+            throw new IOException("stream closed");
+        }
+        boolean wasEmpty = q.isEmpty();
+
+        for (T obj : objs) {
+            q.add(obj);
+        }
+
+        if (waiters > 0)
+            notifyAll();
+
+        if (wasEmpty || forceCallback) {
+            forceCallback = false;
+            if (callback != null) {
+                callback.run();
+            }
+        }
+    }
+
+    synchronized int size() {
+        return q.size();
+    }
+
+    synchronized void put(T obj) throws IOException {
+        if (closed) {
+            throw new IOException("stream closed");
+        }
+
+        q.add(obj);
+        if (waiters > 0)
+            notifyAll();
+
+        if (q.size() == 1 || forceCallback) {
+            forceCallback = false;
+            if (callback != null) {
+                callback.run();
+            }
+        }
+    }
+
+    /**
+     * callback is invoked any time put is called where
+     * the Queue was empty.
+     */
+    synchronized void registerPutCallback(Runnable callback) {
+        this.callback = callback;
+        if (callback != null && q.size() > 0)
+            callback.run();
+    }
+
+    @Override
+    public synchronized void close() {
+        closed = true;
+        notifyAll();
+    }
+
+    synchronized T take() throws IOException {
+        if (closed) {
+            throw new IOException("stream closed");
+        }
+        try {
+            while (q.size() == 0) {
+                waiters++;
+                wait();
+                waiters--;
+            }
+            return q.removeFirst();
+        } catch (InterruptedException ex) {
+            throw new IOException(ex);
+        }
+    }
+
+    public synchronized T poll() throws IOException {
+        if (closed)
+            throw new IOException("stream closed");
+
+        if (q.isEmpty())
+            return null;
+        T res = q.removeFirst();
+        return res;
+    }
+
+    public synchronized T[] pollAll(T[] type) throws IOException {
+        T[] ret = q.toArray(type);
+        q.clear();
+        return ret;
+    }
+
+    public synchronized void pushback(T v) {
+        forceCallback = true;
+        q.addFirst(v);
+    }
+
+    public synchronized void pushbackAll(T[] v) {
+        forceCallback = true;
+        for (int i=v.length-1; i>=0; i--) {
+            q.addFirst(v[i]);
+        }
+    }
+}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/RawChannel.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/RawChannel.java	Thu Apr 28 23:08:16 2016 -0700
@@ -28,18 +28,18 @@
 import java.nio.channels.ByteChannel;
 import java.nio.channels.GatheringByteChannel;
 import java.nio.channels.SelectableChannel;
+import java.nio.channels.SelectionKey;
 
-/**
- * Used to implement WebSocket. Each RawChannel corresponds to
- * a TCP connection (SocketChannel) but is connected to a Selector
- * and an ExecutorService for invoking the send and receive callbacks
- * Also includes SSL processing.
- */
-class RawChannel implements ByteChannel, GatheringByteChannel {
+//
+// Used to implement WebSocket. Each RawChannel corresponds to a TCP connection
+// (SocketChannel) but is connected to a Selector and an ExecutorService for
+// invoking the send and receive callbacks. Also includes SSL processing.
+//
+final class RawChannel implements ByteChannel, GatheringByteChannel {
 
     private final HttpClientImpl client;
     private final HttpConnection connection;
-    private boolean closed;
+    private volatile boolean closed;
 
     private interface RawEvent {
 
@@ -50,8 +50,6 @@
         void handle();
     }
 
-    interface BlockingEvent extends RawEvent { }
-
     interface NonBlockingEvent extends RawEvent { }
 
     RawChannel(HttpClientImpl client, HttpConnection connection) {
@@ -64,39 +62,40 @@
         private final RawEvent re;
 
         RawAsyncEvent(RawEvent re) {
+            super(AsyncEvent.BLOCKING); // BLOCKING & !REPEATING
             this.re = re;
         }
 
+        RawAsyncEvent(RawEvent re, int flags) {
+            super(flags);
+            this.re = re;
+        }
+
+        @Override
         public SelectableChannel channel() {
             return connection.channel();
         }
 
         // must return the selector interest op flags OR'd
+        @Override
         public int interestOps() {
             return re.interestOps();
         }
 
         // called when event occurs
+        @Override
         public void handle() {
             re.handle();
         }
 
-        public void abort() {}
+        @Override
+        public void abort() { }
     }
 
-    private class BlockingRawAsyncEvent extends RawAsyncEvent
-            implements AsyncEvent.Blocking {
-
-        BlockingRawAsyncEvent(RawEvent re) {
-            super(re);
-        }
-    }
-
-    private class NonBlockingRawAsyncEvent extends RawAsyncEvent
-            implements AsyncEvent.NonBlocking {
+    private class NonBlockingRawAsyncEvent extends RawAsyncEvent {
 
         NonBlockingRawAsyncEvent(RawEvent re) {
-            super(re);
+            super(re, 0); // !BLOCKING & !REPEATING
         }
     }
 
@@ -105,17 +104,24 @@
      * (i.e. register new event for each callback)
      */
     public void registerEvent(RawEvent event) throws IOException {
-        if (event instanceof BlockingEvent) {
-            client.registerEvent(new BlockingRawAsyncEvent(event));
-        } else if (event instanceof NonBlockingEvent) {
+        if (!(event instanceof NonBlockingEvent)) {
+            throw new InternalError();
+        }
+        if ((event.interestOps() & SelectionKey.OP_READ) != 0
+                && connection.buffer.hasRemaining()) {
+            // FIXME: a hack to deal with leftovers from previous reads into an
+            // internal buffer (works in conjunction with change in
+            // java.net.http.PlainHttpConnection.readImpl(java.nio.ByteBuffer)
+            connection.channel().configureBlocking(false);
+            event.handle();
+        } else {
             client.registerEvent(new NonBlockingRawAsyncEvent(event));
-        } else {
-            throw new InternalError();
         }
     }
 
     @Override
     public int read(ByteBuffer dst) throws IOException {
+        assert !connection.channel().isBlocking();
         return connection.read(dst);
     }
 
--- a/jdk/src/java.httpclient/share/classes/java/net/http/RedirectFilter.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/RedirectFilter.java	Thu Apr 28 23:08:16 2016 -0700
@@ -33,17 +33,19 @@
     HttpRequestImpl requestImpl;
     HttpRequest request;
     HttpClientImpl client;
+    HttpClient.Redirect policy;
     String method;
     final static int DEFAULT_MAX_REDIRECTS = 5;
     URI uri;
 
     final static int max_redirects = Utils.getIntegerNetProperty(
-            "sun.net.httpclient.redirects.retrylimit", DEFAULT_MAX_REDIRECTS
+            "java.net.httpclient.redirects.retrylimit", DEFAULT_MAX_REDIRECTS
     );
 
     @Override
     public void request(HttpRequestImpl r) throws IOException {
         this.request = r;
+        this.policy = request.followRedirects();
         this.client = r.getClient();
         this.method = r.method();
         this.requestImpl = r;
@@ -61,7 +63,7 @@
      */
     private HttpRequestImpl handleResponse(HttpResponseImpl r) {
         int rcode = r.statusCode();
-        if (rcode == 200) {
+        if (rcode == 200 || policy == HttpClient.Redirect.NEVER) {
             return null;
         }
         if (rcode >= 300 && rcode <= 399) {
@@ -79,6 +81,7 @@
 
     private URI getRedirectedURI(HttpHeaders headers) {
         URI redirectedURI;
+        String ss = headers.firstValue("Location").orElse("Not present");
         redirectedURI = headers.firstValue("Location")
                 .map((s) -> URI.create(s))
                 .orElseThrow(() -> new UncheckedIOException(
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/ResetFrame.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2015, 2016, 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
+ */
+
+package java.net.http;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+class ResetFrame extends ErrorFrame {
+
+    public final static int TYPE = 0x3;
+
+    // See ErrorFrame for error values
+
+    ResetFrame() {
+        type = TYPE;
+    }
+
+    public ResetFrame(int errorCode) {
+        this.errorCode = errorCode;
+        this.type = TYPE;
+    }
+
+    @Override
+    void readIncomingImpl(ByteBufferConsumer bc) throws IOException {
+        errorCode = bc.getInt();
+    }
+
+    @Override
+    void writeOutgoing(ByteBufferGenerator bg) {
+        super.writeOutgoing(bg);
+        ByteBuffer buf = bg.getBuffer(4);
+        buf.putInt(errorCode);
+    }
+
+    @Override
+    void computeLength() {
+        length = 4;
+    }
+}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/ResponseHeaders.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/ResponseHeaders.java	Thu Apr 28 23:08:16 2016 -0700
@@ -48,7 +48,7 @@
  *
  * This class is not thread-safe
  */
-class ResponseHeaders implements HttpHeaders1 {
+class ResponseHeaders implements HttpHeaders {
 
     static final int DATA_SIZE = 16 * 1024;  // initial space for headers
     static final int NUM_HEADERS = 50; // initial expected max number of headers
@@ -368,10 +368,6 @@
         return Collections.unmodifiableList(l);
     }
 
-    @Override
-    public void makeUnmodifiable() {
-    }
-
     // Delegates map to HashMap but converts keys to lower case
 
     static class HeaderMap implements Map<String,List<String>> {
--- a/jdk/src/java.httpclient/share/classes/java/net/http/SSLConnection.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/SSLConnection.java	Thu Apr 28 23:08:16 2016 -0700
@@ -121,13 +121,8 @@
     }
 
     @Override
-    void close() {
-        try {
-            //System.err.println ("Closing: " + this);
-            delegate.channel().close(); // TODO: proper close
-        } catch (IOException ex) {
-            Log.logError(ex.toString());
-        }
+    public void close() {
+        Utils.close(delegate.channel());
     }
 
     @Override
--- a/jdk/src/java.httpclient/share/classes/java/net/http/SSLDelegate.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/SSLDelegate.java	Thu Apr 28 23:08:16 2016 -0700
@@ -29,13 +29,9 @@
 import java.util.Arrays;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLEngineResult;
 import javax.net.ssl.SSLEngineResult.HandshakeStatus;
 import javax.net.ssl.SSLEngineResult.Status;
-import javax.net.ssl.SSLParameters;
-import javax.net.ssl.SSLSession;
+import javax.net.ssl.*;
 import static javax.net.ssl.SSLEngineResult.HandshakeStatus.*;
 
 /**
@@ -60,16 +56,18 @@
         engine.setUseClientMode(true);
         SSLParameters sslp = client.sslParameters().orElse(null);
         if (sslp == null) {
-            sslp = context.getDefaultSSLParameters();
+            sslp = context.getSupportedSSLParameters();
         }
         sslParameters = Utils.copySSLParameters(sslp);
         if (alpn != null) {
             sslParameters.setApplicationProtocols(alpn);
             Log.logSSL("Setting application protocols: " + Arrays.toString(alpn));
         } else {
-            Log.logSSL("Warning no application protocols proposed!");
+            Log.logSSL("No application protocols proposed");
         }
         engine.setSSLParameters(sslParameters);
+        engine.setEnabledCipherSuites(sslp.getCipherSuites());
+        engine.setEnabledProtocols(sslp.getProtocols());
         wrapper = new EngineWrapper(chan, engine);
         this.chan = chan;
         this.client = client;
@@ -268,7 +266,7 @@
                 do {
                     if (needData) {
                         do {
-                        x = chan.read (unwrap_src);
+                            x = chan.read (unwrap_src);
                         } while (x == 0);
                         if (x == -1) {
                             throw new IOException ("connection closed for reading");
@@ -440,6 +438,27 @@
         }
     }
 
+    static void printParams(SSLParameters p) {
+        System.out.println("SSLParameters:");
+        if (p == null) {
+            System.out.println("Null params");
+            return;
+        }
+        for (String cipher : p.getCipherSuites()) {
+                System.out.printf("cipher: %s\n", cipher);
+        }
+        for (String approto : p.getApplicationProtocols()) {
+                System.out.printf("application protocol: %s\n", approto);
+        }
+        for (String protocol : p.getProtocols()) {
+                System.out.printf("protocol: %s\n", protocol);
+        }
+        if (p.getServerNames() != null)
+        for (SNIServerName sname : p.getServerNames()) {
+                System.out.printf("server name: %s\n", sname.toString());
+        }
+    }
+
     String getSessionInfo() {
         StringBuilder sb = new StringBuilder();
         String application = engine.getApplicationProtocol();
--- a/jdk/src/java.httpclient/share/classes/java/net/http/SSLTunnelConnection.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/SSLTunnelConnection.java	Thu Apr 28 23:08:16 2016 -0700
@@ -130,12 +130,8 @@
     }
 
     @Override
-    void close() {
-        try {
-            //System.err.println ("Closing: " + this);
-            delegate.channel().close(); // TODO: proper close
-        } catch (IOException ex) {
-        }
+    public void close() {
+        Utils.close(delegate.channel());
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/SettingsFrame.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2015, 2016, 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
+ */
+
+package java.net.http;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+class SettingsFrame extends Http2Frame {
+
+    int[] parameters;
+
+    public static final int TYPE = 0x4;
+
+    // Flags
+    public static final int ACK = 0x1;
+
+    @Override
+    String flagAsString(int flag) {
+        switch (flag) {
+        case ACK:
+            return "ACK";
+        }
+        return super.flagAsString(flag);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(super.toString())
+          .append(" Settings: ");
+
+        for (int i = 0; i < MAX_PARAM; i++) {
+            if (parameters[i] != -1) {
+                sb.append(name(i))
+                  .append("=")
+                  .append(Integer.toString(parameters[i]))
+                  .append(' ');
+            }
+        }
+        return sb.toString();
+    }
+
+    // Parameters
+    public static final int HEADER_TABLE_SIZE = 0x1;
+    public static final int ENABLE_PUSH = 0x2;
+    public static final int MAX_CONCURRENT_STREAMS = 0x3;
+    public static final int INITIAL_WINDOW_SIZE = 0x4;
+    public static final int MAX_FRAME_SIZE = 0x5;
+    public static final int MAX_HEADER_LIST_SIZE = 0x6;
+
+    private String name(int i) {
+        switch (i+1) {
+        case HEADER_TABLE_SIZE:
+            return "HEADER_TABLE_SIZE";
+        case ENABLE_PUSH:
+            return "ENABLE_PUSH";
+        case MAX_CONCURRENT_STREAMS:
+            return "MAX_CONCURRENT_STREAMS";
+        case INITIAL_WINDOW_SIZE:
+            return "INITIAL_WINDOW_SIZE";
+        case MAX_FRAME_SIZE:
+            return "MAX_FRAME_SIZE";
+        case MAX_HEADER_LIST_SIZE:
+            return "MAX_HEADER_LIST_SIZE";
+        }
+        return "unknown parameter";
+    }
+    public static final int MAX_PARAM = 0x6;
+
+    public SettingsFrame() {
+        type = TYPE;
+        parameters = new int [MAX_PARAM];
+        for (int i=0; i < parameters.length; i++) {
+            parameters[i] = -1;
+        }
+    }
+
+    public int getParameter(int paramID) {
+        if (paramID > MAX_PARAM) {
+            throw new IllegalArgumentException("illegal parameter");
+        }
+        return parameters[paramID-1];
+    }
+
+    public SettingsFrame setParameter(int paramID, int value) {
+        if (paramID > MAX_PARAM) {
+            throw new IllegalArgumentException("illegal parameter");
+        }
+        parameters[paramID-1] = value;
+        return this;
+    }
+
+    @Override
+    void readIncomingImpl(ByteBufferConsumer bc) throws IOException {
+        if (length % 6 != 0) {
+            throw new IOException("Protocol error: invalid settings frame");
+        }
+        int n = length / 6;
+        for (int i=0; i<n; i++) {
+            int id = bc.getShort();
+            int val = bc.getInt();
+            if (id > 0 || id <= MAX_PARAM) {
+                // a known parameter. Ignore otherwise
+                parameters[id-1] = val;
+            }
+        }
+    }
+
+    @Override
+    void computeLength() {
+        length = 0;
+        for (int i : parameters) {
+            if (i != -1) {
+                length += 6;
+            }
+        }
+    }
+
+    @Override
+    void writeOutgoing(ByteBufferGenerator bg) {
+        super.writeOutgoing(bg);
+        ByteBuffer buf = bg.getBuffer(length);
+        for (int i = 0; i < MAX_PARAM; i++) {
+            if (parameters[i] != -1) {
+                buf.putShort((short)(i+1));
+                buf.putInt(parameters[i]);
+            }
+        }
+    }
+
+    private static final int K = 1024;
+
+    public static SettingsFrame getDefaultSettings() {
+        SettingsFrame f = new SettingsFrame();
+        // TODO: check these values
+        f.setParameter(ENABLE_PUSH, 1);
+        f.setParameter(HEADER_TABLE_SIZE, 4 * K);
+        f.setParameter(MAX_CONCURRENT_STREAMS, 35);
+        f.setParameter(INITIAL_WINDOW_SIZE, 16 * K);
+        f.setParameter(MAX_FRAME_SIZE, 16 * K);
+        return f;
+    }
+}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/Stream.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/Stream.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, 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,78 +24,819 @@
 
 package java.net.http;
 
+import sun.net.httpclient.hpack.DecodingCallback;
+
 import java.io.IOException;
-import java.io.UncheckedIOException;
 import java.net.URI;
 import java.nio.ByteBuffer;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.CompletionException;
+import java.util.function.BiFunction;
 import java.util.function.LongConsumer;
 
 /**
- * Http/2 Stream
+ * Http/2 Stream handling.
+ *
+ * REQUESTS
+ *
+ * sendHeadersOnly() -- assembles HEADERS frame and puts on connection outbound Q
+ *
+ * sendRequest() -- sendHeadersOnly() + sendBody()
+ *
+ * sendBody() -- in calling thread: obeys all flow control (so may block)
+ *               obtains data from request body processor and places on connection
+ *               outbound Q.
+ *
+ * sendBodyAsync() -- calls sendBody() in an executor thread.
+ *
+ * sendHeadersAsync() -- calls sendHeadersOnly() which does not block
+ *
+ * sendRequestAsync() -- calls sendRequest() in an executor thread
+ *
+ * RESPONSES
+ *
+ * Multiple responses can be received per request. Responses are queued up on
+ * a LinkedList of CF<HttpResponse> and the the first one on the list is completed
+ * with the next response
+ *
+ * getResponseAsync() -- queries list of response CFs and returns first one
+ *               if one exists. Otherwise, creates one and adds it to list
+ *               and returns it. Completion is achieved through the
+ *               incoming() upcall from connection reader thread.
+ *
+ * getResponse() -- calls getResponseAsync() and waits for CF to complete
+ *
+ * responseBody() -- in calling thread: blocks for incoming DATA frames on
+ *               stream inputQ. Obeys remote and local flow control so may block.
+ *               Calls user response body processor with data buffers.
+ *
+ * responseBodyAsync() -- calls responseBody() in an executor thread.
+ *
+ * incoming() -- entry point called from connection reader thread. Frames are
+ *               either handled immediately without blocking or for data frames
+ *               placed on the stream's inputQ which is consumed by the stream's
+ *               reader thread.
+ *
+ * PushedStream sub class
+ * ======================
+ * Sending side methods are not used because the request comes from a PUSH_PROMISE
+ * frame sent by the server. When a PUSH_PROMISE is received the PushedStream
+ * is created. PushedStream does not use responseCF list as there can be only
+ * one response. The CF is created when the object created and when the response
+ * HEADERS frame is received the object is completed.
  */
 class Stream extends ExchangeImpl {
 
-    void debugPrint() {
-    }
+    final Queue<Http2Frame> inputQ;
+
+    volatile int streamid;
+
+    long responseContentLen = -1;
+    long responseBytesProcessed = 0;
+    long requestContentLen;
+
+    Http2Connection connection;
+    HttpClientImpl client;
+    final HttpRequestImpl request;
+    final DecodingCallback rspHeadersConsumer;
+    HttpHeadersImpl responseHeaders;
+    final HttpHeadersImpl requestHeaders;
+    final HttpHeadersImpl requestPseudoHeaders;
+    HttpResponse.BodyProcessor<?> responseProcessor;
+    final HttpRequest.BodyProcessor requestProcessor;
+    HttpResponse response;
+
+    // state flags
+    boolean requestSent, responseReceived;
+
+    final FlowController userRequestFlowController =
+            new FlowController();
+    final FlowController remoteRequestFlowController =
+            new FlowController();
+    final FlowController responseFlowController =
+            new FlowController();
+
+    final ExecutorWrapper executor;
 
     @Override
     @SuppressWarnings("unchecked")
     <T> CompletableFuture<T> responseBodyAsync(HttpResponse.BodyProcessor<T> processor) {
-            return null;
+        this.responseProcessor = processor;
+        CompletableFuture<T> cf;
+        try {
+            T body = processor.onResponseBodyStart(
+                    responseContentLen, responseHeaders,
+                    responseFlowController); // TODO: filter headers
+            if (body != null) {
+                cf = CompletableFuture.completedFuture(body);
+                receiveDataAsync(processor);
+            } else
+                cf = receiveDataAsync(processor);
+        } catch (IOException e) {
+            cf = CompletableFuture.failedFuture(e);
+        }
+        PushGroup<?> pg = request.pushGroup();
+        if (pg != null) {
+            // if an error occurs make sure it is recorded in the PushGroup
+            cf = cf.whenComplete((t,e) -> pg.pushError(e));
+        }
+        return cf;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("streamid: ")
+                .append(streamid);
+        return sb.toString();
+    }
+
+    // pushes entire response body into response processor
+    // blocking when required by local or remote flow control
+    void receiveData() throws IOException {
+        Http2Frame frame;
+        DataFrame df = null;
+        try {
+            do {
+                frame = inputQ.take();
+                if (!(frame instanceof DataFrame)) {
+                    assert false;
+                    continue;
+                }
+                df = (DataFrame) frame;
+                int len = df.getDataLength();
+                ByteBuffer[] buffers = df.getData();
+                for (ByteBuffer b : buffers) {
+                    responseFlowController.take();
+                    responseProcessor.onResponseBodyChunk(b);
+                }
+                sendWindowUpdate(len);
+            } while (!df.getFlag(DataFrame.END_STREAM));
+        } catch (InterruptedException e) {
+            throw new IOException(e);
+        }
+    }
+
+    private <T> CompletableFuture<T> receiveDataAsync(HttpResponse.BodyProcessor<T> processor) {
+        CompletableFuture<T> cf = new CompletableFuture<>();
+        executor.execute(() -> {
+            try {
+                receiveData();
+                T body = processor.onResponseComplete();
+                cf.complete(body);
+                responseReceived();
+            } catch (Throwable t) {
+                cf.completeExceptionally(t);
+            }
+        }, null);
+        return cf;
+    }
+
+    private void sendWindowUpdate(int increment)
+            throws IOException, InterruptedException {
+        if (increment == 0)
+            return;
+        LinkedList<Http2Frame> list = new LinkedList<>();
+        WindowUpdateFrame frame = new WindowUpdateFrame();
+        frame.streamid(streamid);
+        frame.setUpdate(increment);
+        list.add(frame);
+        frame = new WindowUpdateFrame();
+        frame.streamid(0);
+        frame.setUpdate(increment);
+        list.add(frame);
+        connection.sendFrames(list);
+    }
+
+    @Override
+    CompletableFuture<Void> sendBodyAsync() {
+        final CompletableFuture<Void> cf = new CompletableFuture<>();
+        executor.execute(() -> {
+            try {
+                sendBodyImpl();
+                cf.complete(null);
+            } catch (IOException | InterruptedException e) {
+                cf.completeExceptionally(e);
+            }
+        }, null);
+        return cf;
+    }
+
+    @SuppressWarnings("unchecked")
+    Stream(HttpClientImpl client, Http2Connection connection, Exchange e) {
+        super(e);
+        this.client = client;
+        this.connection = connection;
+        this.request = e.request();
+        this.requestProcessor = request.requestProcessor();
+        responseHeaders = new HttpHeadersImpl();
+        requestHeaders = new HttpHeadersImpl();
+        rspHeadersConsumer = (name, value) -> {
+            responseHeaders.addHeader(name.toString(), value.toString());
+        };
+        this.executor = client.executorWrapper();
+        //this.response_cf = new CompletableFuture<HttpResponseImpl>();
+        this.requestPseudoHeaders = new HttpHeadersImpl();
+        // NEW
+        this.inputQ = new Queue<>();
+    }
+
+    @SuppressWarnings("unchecked")
+    Stream(HttpClientImpl client, Http2Connection connection, HttpRequestImpl req) {
+        super(null);
+        this.client = client;
+        this.connection = connection;
+        this.request = req;
+        this.requestProcessor = null;
+        responseHeaders = new HttpHeadersImpl();
+        requestHeaders = new HttpHeadersImpl();
+        rspHeadersConsumer = (name, value) -> {
+            responseHeaders.addHeader(name.toString(), value.toString());
+        };
+        this.executor = client.executorWrapper();
+        //this.response_cf = new CompletableFuture<HttpResponseImpl>();
+        this.requestPseudoHeaders = new HttpHeadersImpl();
+        // NEW
+        this.inputQ = new Queue<>();
     }
 
-    Stream(HttpClientImpl client, Http2Connection connection, Exchange e) {
-        super(e);
+    /**
+     * Entry point from Http2Connection reader thread.
+     *
+     * Data frames will be removed by response body thread.
+     *
+     * @param frame
+     * @throws IOException
+     */
+    void incoming(Http2Frame frame) throws IOException, InterruptedException {
+        if ((frame instanceof HeaderFrame) && ((HeaderFrame)frame).endHeaders()) {
+            // Complete headers accumulated. handle response.
+            // It's okay if there are multiple HeaderFrames.
+            handleResponse();
+        } else if (frame instanceof DataFrame) {
+            inputQ.put(frame);
+        } else {
+            otherFrame(frame);
+        }
+    }
+
+    void otherFrame(Http2Frame frame) throws IOException {
+        switch (frame.type()) {
+            case WindowUpdateFrame.TYPE:
+                incoming_windowUpdate((WindowUpdateFrame) frame);
+                break;
+            case ResetFrame.TYPE:
+                incoming_reset((ResetFrame) frame);
+                break;
+            case PriorityFrame.TYPE:
+                incoming_priority((PriorityFrame) frame);
+                break;
+            default:
+                String msg = "Unexpected frame: " + frame.toString();
+                throw new IOException(msg);
+        }
+    }
+
+    // The Hpack decoder decodes into one of these consumers of name,value pairs
+
+    DecodingCallback rspHeadersConsumer() {
+        return rspHeadersConsumer;
+    }
+
+    // create and return the HttpResponseImpl
+    protected void handleResponse() throws IOException {
+        HttpConnection c = connection.connection; // TODO: improve
+        long statusCode = responseHeaders
+                .firstValueAsLong(":status")
+                .orElseThrow(() -> new IOException("no statuscode in response"));
+
+        this.response = new HttpResponseImpl((int)statusCode, exchange, responseHeaders, null,
+                c.sslParameters(), HttpClient.Version.HTTP_2, c);
+        this.responseContentLen = responseHeaders
+                .firstValueAsLong("content-length")
+                .orElse(-1L);
+        // different implementations for normal streams and pushed streams
+        completeResponse(response);
+    }
+
+    void incoming_reset(ResetFrame frame) {
+        // TODO: implement reset
+        int error = frame.getErrorCode();
+        IOException e = new IOException(ErrorFrame.stringForCode(error));
+        completeResponseExceptionally(e);
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    void incoming_priority(PriorityFrame frame) {
+        // TODO: implement priority
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    void incoming_windowUpdate(WindowUpdateFrame frame) {
+        int amount = frame.getUpdate();
+        if (amount > 0)
+            remoteRequestFlowController.accept(amount);
+    }
+
+    void incoming_pushPromise(HttpRequestImpl pushReq, PushedStream pushStream) throws IOException {
+        if (Log.requests()) {
+            Log.logRequest("PUSH_PROMISE: " + pushReq.toString());
+        }
+        PushGroup<?> pushGroup = request.pushGroup();
+        if (pushGroup == null) {
+            cancelImpl(new IllegalStateException("unexpected push promise"));
+        }
+        // get the handler and call it.
+        BiFunction<HttpRequest,CompletableFuture<HttpResponse>,Boolean> ph =
+            pushGroup.pushHandler();
+
+        CompletableFuture<HttpResponse> pushCF = pushStream
+                .getResponseAsync(null)
+                .thenApply(r -> (HttpResponse)r);
+        boolean accept = ph.apply(pushReq, pushCF);
+        if (!accept) {
+            IOException ex = new IOException("Stream cancelled by user");
+            cancelImpl(ex);
+            pushCF.completeExceptionally(ex);
+        } else {
+            pushStream.requestSent();
+            pushGroup.addPush();
+        }
+    }
+
+    private OutgoingHeaders headerFrame(long contentLength) {
+        HttpHeadersImpl h = request.getSystemHeaders();
+        if (contentLength > 0) {
+            h.setHeader("content-length", Long.toString(contentLength));
+        }
+        setPseudoHeaderFields();
+        OutgoingHeaders f = new OutgoingHeaders(h, request.getUserHeaders(), this);
+        if (contentLength == 0) {
+            f.setFlag(HeadersFrame.END_STREAM);
+        }
+        return f;
+    }
+
+    private void setPseudoHeaderFields() {
+        HttpHeadersImpl hdrs = requestPseudoHeaders;
+        String method = request.method();
+        hdrs.setHeader(":method", method);
+        URI uri = request.uri();
+        hdrs.setHeader(":scheme", uri.getScheme());
+        // TODO: userinfo deprecated. Needs to be removed
+        hdrs.setHeader(":authority", uri.getAuthority());
+        // TODO: ensure header names beginning with : not in user headers
+        String query = uri.getQuery();
+        String path = uri.getPath();
+        if (path == null) {
+            if (method.equalsIgnoreCase("OPTIONS")) {
+                path = "*";
+            } else {
+                path = "/";
+            }
+        }
+        if (query != null) {
+            path += "?" + query;
+        }
+        hdrs.setHeader(":path", path);
+    }
+
+    HttpHeadersImpl getRequestPseudoHeaders() {
+        return requestPseudoHeaders;
     }
 
     @Override
     HttpResponseImpl getResponse() throws IOException {
-        return null;
+        try {
+            return getResponseAsync(null).join();
+        } catch (Throwable e) {
+            Throwable t = e.getCause();
+            if (t instanceof IOException) {
+                throw (IOException)t;
+            }
+            throw e;
+        }
     }
 
     @Override
     void sendRequest() throws IOException, InterruptedException {
+        sendHeadersOnly();
+        sendBody();
+    }
+
+    /**
+     * A simple general purpose blocking flow controller
+     */
+    class FlowController implements LongConsumer {
+        int permits;
+
+        FlowController() {
+            this.permits = 0;
+        }
+
+        @Override
+        public synchronized void accept(long n) {
+            if (n < 1) {
+                throw new InternalError("FlowController.accept called with " + n);
+            }
+            if (permits == 0) {
+                permits += n;
+                notifyAll();
+            } else {
+                permits += n;
+            }
+        }
+
+        public synchronized void take() throws InterruptedException {
+            take(1);
+        }
+
+        public synchronized void take(int amount) throws InterruptedException {
+            assert permits >= 0;
+            while (permits < amount) {
+                int n = Math.min(amount, permits);
+                permits -= n;
+                amount -= n;
+                if (amount > 0)
+                    wait();
+            }
+        }
     }
 
     @Override
     void sendHeadersOnly() throws IOException, InterruptedException {
+        if (Log.requests() && request != null) {
+            Log.logRequest(request.toString());
+        }
+        requestContentLen = requestProcessor.onRequestStart(request, userRequestFlowController);
+        OutgoingHeaders f = headerFrame(requestContentLen);
+        connection.sendFrame(f);
     }
 
     @Override
     void sendBody() throws IOException, InterruptedException {
+        sendBodyImpl();
     }
 
+    void registerStream(int id) {
+        this.streamid = id;
+        connection.putStream(this, streamid);
+    }
+
+    DataFrame getDataFrame() throws IOException, InterruptedException {
+        userRequestFlowController.take();
+        int maxpayloadLen = connection.getMaxSendFrameSize() - 9;
+        ByteBuffer buffer = connection.getBuffer();
+        buffer.limit(maxpayloadLen);
+        boolean complete = requestProcessor.onRequestBodyChunk(buffer);
+        buffer.flip();
+        int amount = buffer.remaining();
+        // wait for flow control if necessary. Following method will block
+        // until after headers frame is sent, so correct streamid is set.
+        remoteRequestFlowController.take(amount);
+        connection.obtainSendWindow(amount);
+
+        DataFrame df = new DataFrame();
+        df.streamid(streamid);
+        if (complete) {
+            df.setFlag(DataFrame.END_STREAM);
+        }
+        df.setData(buffer);
+        df.computeLength();
+        return df;
+    }
+
+
     @Override
     CompletableFuture<Void> sendHeadersAsync() {
-        return null;
+        try {
+            sendHeadersOnly();
+            return CompletableFuture.completedFuture(null);
+        } catch (IOException | InterruptedException ex) {
+            return CompletableFuture.failedFuture(ex);
+        }
     }
 
+    /**
+     * A List of responses relating to this stream. Normally there is only
+     * one response, but intermediate responses like 100 are allowed
+     * and must be passed up to higher level before continuing. Deals with races
+     * such as if responses are returned before the CFs get created by
+     * getResponseAsync()
+     */
+
+    final List<CompletableFuture<HttpResponseImpl>> response_cfs = new LinkedList<>();
+
     @Override
     CompletableFuture<HttpResponseImpl> getResponseAsync(Void v) {
-        return null;
+        CompletableFuture<HttpResponseImpl> cf;
+        synchronized (response_cfs) {
+            if (!response_cfs.isEmpty()) {
+                cf = response_cfs.remove(0);
+            } else {
+                cf = new CompletableFuture<>();
+                response_cfs.add(cf);
+            }
+        }
+        PushGroup<?> pg = request.pushGroup();
+        if (pg != null) {
+            // if an error occurs make sure it is recorded in the PushGroup
+            cf = cf.whenComplete((t,e) -> pg.pushError(e));
+        }
+        return cf;
+    }
+
+    /**
+     * Completes the first uncompleted CF on list, and removes it. If there is no
+     * uncompleted CF then creates one (completes it) and adds to list
+     */
+    void completeResponse(HttpResponse r) {
+        HttpResponseImpl resp = (HttpResponseImpl)r;
+        synchronized (response_cfs) {
+            for (CompletableFuture<HttpResponseImpl> cf : response_cfs) {
+                if (!cf.isDone()) {
+                    cf.complete(resp);
+                    response_cfs.remove(cf);
+                    //responseHeaders = new HttpHeadersImpl(); // for any following header blocks
+                    return;
+                } else
+                    System.err.println("Stream: " + this + " ALREADY DONE");
+            }
+            response_cfs.add(CompletableFuture.completedFuture(resp));
+            //responseHeaders = new HttpHeadersImpl(); // for any following header blocks
+        }
     }
 
-    @Override
-    CompletableFuture<Void> sendBodyAsync() {
-        return null;
+    // methods to update state and remove stream when finished
+
+    synchronized void requestSent() {
+        requestSent = true;
+        if (responseReceived)
+            connection.deleteStream(this);
+    }
+
+    synchronized void responseReceived() {
+        responseReceived = true;
+        if (requestSent)
+            connection.deleteStream(this);
+        PushGroup<?> pg = request.pushGroup();
+        if (pg != null)
+            pg.noMorePushes();
+    }
+
+    /**
+     * same as above but for errors
+     *
+     * @param t
+     */
+    void completeResponseExceptionally(Throwable t) {
+        synchronized (response_cfs) {
+            for (CompletableFuture<HttpResponseImpl> cf : response_cfs) {
+                if (!cf.isDone()) {
+                    cf.completeExceptionally(t);
+                    response_cfs.remove(cf);
+                    return;
+                }
+            }
+            response_cfs.add(CompletableFuture.failedFuture(t));
+        }
+    }
+
+    void sendBodyImpl() throws IOException, InterruptedException {
+        if (requestContentLen == 0) {
+            // no body
+            return;
+        }
+        DataFrame df;
+        do {
+            df = getDataFrame();
+            // TODO: check accumulated content length (if not checked below)
+            connection.sendFrame(df);
+        } while (!df.getFlag(DataFrame.END_STREAM));
+        requestSent();
     }
 
     @Override
     void cancel() {
+        cancelImpl(new Exception("Cancelled"));
     }
 
 
+    void cancelImpl(Throwable e) {
+        Log.logTrace("cancelling stream: {0}\n", e.toString());
+        inputQ.close();
+        try {
+            connection.resetStream(streamid, ResetFrame.CANCEL);
+        } catch (IOException | InterruptedException ex) {
+            Log.logError(ex);
+        }
+    }
+
     @Override
     CompletableFuture<Void> sendRequestAsync() {
-        return null;
+        CompletableFuture<Void> cf = new CompletableFuture<>();
+        executor.execute(() -> {
+           try {
+               sendRequest();
+               cf.complete(null);
+           } catch (IOException |InterruptedException e) {
+               cf.completeExceptionally(e);
+           }
+        }, null);
+        return cf;
     }
 
     @Override
     <T> T responseBody(HttpResponse.BodyProcessor<T> processor) throws IOException {
-        return null;
+        this.responseProcessor = processor;
+        T body = processor.onResponseBodyStart(
+                    responseContentLen, responseHeaders,
+                    responseFlowController); // TODO: filter headers
+        if (body == null) {
+            receiveData();
+            return processor.onResponseComplete();
+        } else
+            receiveDataAsync(processor);
+        responseReceived();
+        return body;
+    }
+
+    // called from Http2Connection reader thread
+    synchronized void updateOutgoingWindow(int update) {
+        remoteRequestFlowController.accept(update);
+    }
+
+    void close(String msg) {
+        cancel();
+    }
+
+    static class PushedStream extends Stream {
+        final PushGroup<?> pushGroup;
+        final private Stream parent;      // used by server push streams
+        // push streams need the response CF allocated up front as it is
+        // given directly to user via the multi handler callback function.
+        final CompletableFuture<HttpResponseImpl> pushCF;
+        final HttpRequestImpl pushReq;
+
+        PushedStream(PushGroup<?> pushGroup, HttpClientImpl client,
+                Http2Connection connection, Stream parent,
+                HttpRequestImpl pushReq) {
+            super(client, connection, pushReq);
+            this.pushGroup = pushGroup;
+            this.pushReq = pushReq;
+            this.pushCF = new CompletableFuture<>();
+            this.parent = parent;
+        }
+
+        // Following methods call the super class but in case of
+        // error record it in the PushGroup. The error method is called
+        // with a null value when no error occurred (is a no-op)
+        @Override
+        CompletableFuture<Void> sendBodyAsync() {
+            return super.sendBodyAsync()
+                        .whenComplete((v, t) -> pushGroup.pushError(t));
+        }
+
+        @Override
+        CompletableFuture<Void> sendHeadersAsync() {
+            return super.sendHeadersAsync()
+                        .whenComplete((v, t) -> pushGroup.pushError(t));
+        }
+
+        @Override
+        CompletableFuture<Void> sendRequestAsync() {
+            return super.sendRequestAsync()
+                        .whenComplete((v, t) -> pushGroup.pushError(t));
+        }
+
+        @Override
+        CompletableFuture<HttpResponseImpl> getResponseAsync(Void vo) {
+            return pushCF.whenComplete((v, t) -> pushGroup.pushError(t));
+        }
+
+        @Override
+        <T> CompletableFuture<T> responseBodyAsync(HttpResponse.BodyProcessor<T> processor) {
+            return super.responseBodyAsync(processor)
+                        .whenComplete((v, t) -> pushGroup.pushError(t));
+        }
+
+        @Override
+        void completeResponse(HttpResponse r) {
+            HttpResponseImpl resp = (HttpResponseImpl)r;
+            Utils.logResponse(resp);
+            pushCF.complete(resp);
+        }
+
+        @Override
+        void completeResponseExceptionally(Throwable t) {
+            pushCF.completeExceptionally(t);
+        }
+
+        @Override
+        synchronized void responseReceived() {
+            super.responseReceived();
+            pushGroup.pushCompleted();
+        }
+
+        // create and return the PushResponseImpl
+        @Override
+        protected void handleResponse() {
+            HttpConnection c = connection.connection; // TODO: improve
+            long statusCode = responseHeaders
+                .firstValueAsLong(":status")
+                .orElse(-1L);
+
+            if (statusCode == -1L)
+                completeResponseExceptionally(new IOException("No status code"));
+            ImmutableHeaders h = new ImmutableHeaders(responseHeaders, Utils.ALL_HEADERS);
+            this.response = new HttpResponseImpl((int)statusCode, pushReq, h, this,
+                c.sslParameters());
+            this.responseContentLen = responseHeaders
+                .firstValueAsLong("content-length")
+                .orElse(-1L);
+            // different implementations for normal streams and pushed streams
+            completeResponse(response);
+        }
+    }
+
+    /**
+     * One PushGroup object is associated with the parent Stream of
+     * the pushed Streams. This keeps track of all common state associated
+     * with the pushes.
+     */
+    static class PushGroup<T> {
+        // the overall completion object, completed when all pushes are done.
+        final CompletableFuture<T> resultCF;
+        Throwable error; // any exception that occured during pushes
+
+        // CF for main response
+        final CompletableFuture<HttpResponse> mainResponse;
+
+        // user's processor object
+        final HttpResponse.MultiProcessor<T> multiProcessor;
+
+        // per push handler function provided by processor
+        final private BiFunction<HttpRequest,
+                           CompletableFuture<HttpResponse>,
+                           Boolean> pushHandler;
+        int numberOfPushes;
+        int remainingPushes;
+        boolean noMorePushes = false;
+
+        PushGroup(HttpResponse.MultiProcessor<T> multiProcessor, HttpRequestImpl req) {
+            this.resultCF = new CompletableFuture<>();
+            this.mainResponse = new CompletableFuture<>();
+            this.multiProcessor = multiProcessor;
+            this.pushHandler = multiProcessor.onStart(req, mainResponse);
+        }
+
+        CompletableFuture<T> groupResult() {
+            return resultCF;
+        }
+
+        CompletableFuture<HttpResponse> mainResponse() {
+            return mainResponse;
+        }
+
+        private BiFunction<HttpRequest,
+            CompletableFuture<HttpResponse>, Boolean> pushHandler()
+        {
+                return pushHandler;
+        }
+
+        synchronized void addPush() {
+            numberOfPushes++;
+            remainingPushes++;
+        }
+
+        synchronized int numberOfPushes() {
+            return numberOfPushes;
+        }
+        // This is called when the main body response completes because it means
+        // no more PUSH_PROMISEs are possible
+        synchronized void noMorePushes() {
+            noMorePushes = true;
+            checkIfCompleted();
+        }
+
+        synchronized void pushCompleted() {
+            remainingPushes--;
+            checkIfCompleted();
+        }
+
+        synchronized void checkIfCompleted() {
+            if (remainingPushes == 0 && error == null && noMorePushes) {
+                T overallResult = multiProcessor.onComplete();
+                resultCF.complete(overallResult);
+            }
+        }
+
+        synchronized void pushError(Throwable t) {
+            if (t == null)
+                return;
+            this.error = t;
+            resultCF.completeExceptionally(t);
+        }
     }
 }
--- a/jdk/src/java.httpclient/share/classes/java/net/http/Utils.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/Utils.java	Thu Apr 28 23:08:16 2016 -0700
@@ -21,28 +21,37 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  */
-
 package java.net.http;
 
+import sun.net.NetProperties;
+
+import javax.net.ssl.SSLParameters;
 import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.IOException;
 import java.io.PrintStream;
 import java.io.UnsupportedEncodingException;
+import java.net.InetSocketAddress;
 import java.net.NetPermission;
 import java.net.URI;
 import java.net.URLPermission;
+import java.nio.Buffer;
 import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import javax.net.ssl.SSLParameters;
-import sun.net.NetProperties;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.LongBinaryOperator;
+import java.util.function.Predicate;
 
 /**
  * Miscellaneous utilities
  */
-class Utils {
+final class Utils {
 
     /**
      * Allocated buffer size. Must never be higher than 16K. But can be lower
@@ -51,7 +60,59 @@
      */
     public static final int BUFSIZE = 16 * 1024;
 
-    /** Validates a RFC7230 token */
+    private static final Set<String> DISALLOWED_HEADERS_SET = Set.of(
+            "authorization", "connection", "cookie", "content-length",
+            "date", "expect", "from", "host", "origin", "proxy-authorization",
+            "referer", "user-agent", "upgrade", "via", "warning");
+
+    static final Predicate<String>
+        ALLOWED_HEADERS = header -> !Utils.DISALLOWED_HEADERS_SET.contains(header);
+
+    static final Predicate<String>
+        ALL_HEADERS = header -> true;
+
+    static InetSocketAddress getAddress(HttpRequestImpl req) {
+        URI uri = req.uri();
+        if (uri == null) {
+            return req.authority();
+        }
+        int port = uri.getPort();
+        if (port == -1) {
+            if (uri.getScheme().equalsIgnoreCase("https")) {
+                port = 443;
+            } else {
+                port = 80;
+            }
+        }
+        String host = uri.getHost();
+        if (req.proxy() == null) {
+            return new InetSocketAddress(host, port);
+        } else {
+            return InetSocketAddress.createUnresolved(host, port);
+        }
+    }
+
+    /**
+     * Puts position to limit and limit to capacity so we can resume reading
+     * into this buffer, but if required > 0 then limit may be reduced so that
+     * no more than required bytes are read next time.
+     */
+    static void resumeChannelRead(ByteBuffer buf, int required) {
+        int limit = buf.limit();
+        buf.position(limit);
+        int capacity = buf.capacity() - limit;
+        if (required > 0 && required < capacity) {
+            buf.limit(limit + required);
+        } else {
+            buf.limit(buf.capacity());
+        }
+    }
+
+    private Utils() { }
+
+    /**
+     * Validates a RFC7230 token
+     */
     static void validateToken(String token, String errormsg) {
         int length = token.length();
         for (int i = 0; i < length; i++) {
@@ -69,7 +130,7 @@
     }
 
     /**
-     * Return sthe security permission required for the given details.
+     * Returns the security permission required for the given details.
      * If method is CONNECT, then uri must be of form "scheme://host:port"
      */
     static URLPermission getPermission(URI uri,
@@ -117,13 +178,13 @@
     }
 
     static int getIntegerNetProperty(String name, int defaultValue) {
-        return AccessController.doPrivileged((PrivilegedAction<Integer>)() ->
-            NetProperties.getInteger(name, defaultValue) );
+        return AccessController.doPrivileged((PrivilegedAction<Integer>) () ->
+                NetProperties.getInteger(name, defaultValue));
     }
 
     static String getNetProperty(String name) {
-        return AccessController.doPrivileged((PrivilegedAction<String>)() ->
-            NetProperties.get(name) );
+        return AccessController.doPrivileged((PrivilegedAction<String>) () ->
+                NetProperties.get(name));
     }
 
     static SSLParameters copySSLParameters(SSLParameters p) {
@@ -134,7 +195,9 @@
         p1.setEndpointIdentificationAlgorithm(p.getEndpointIdentificationAlgorithm());
         p1.setMaximumPacketSize(p.getMaximumPacketSize());
         p1.setNeedClientAuth(p.getNeedClientAuth());
-        p1.setProtocols(p.getProtocols().clone());
+        String[] protocols = p.getProtocols();
+        if (protocols != null)
+            p1.setProtocols(protocols.clone());
         p1.setSNIMatchers(p.getSNIMatchers());
         p1.setServerNames(p.getServerNames());
         p1.setUseCipherSuitesOrder(p.getUseCipherSuitesOrder());
@@ -142,33 +205,14 @@
         return p1;
     }
 
-
-    /** Resumes reading into the given buffer. */
-    static void unflip(ByteBuffer buf) {
-        buf.position(buf.limit());
-        buf.limit(buf.capacity());
-    }
-
     /**
      * Set limit to position, and position to mark.
-     *
-     *
-     * @param buffer
-     * @param mark
      */
     static void flipToMark(ByteBuffer buffer, int mark) {
         buffer.limit(buffer.position());
         buffer.position(mark);
     }
 
-    /** Compact and leave ready for reading. */
-    static void compact(List<ByteBuffer> buffers) {
-        for (ByteBuffer b : buffers) {
-            b.compact();
-            b.flip();
-        }
-    }
-
     static String stackTrace(Throwable t) {
         ByteArrayOutputStream bos = new ByteArrayOutputStream();
         String s = null;
@@ -182,8 +226,10 @@
         return s;
     }
 
-    /** Copies as much of src to dst as possible. */
-    static void copy (ByteBuffer src, ByteBuffer dst) {
+    /**
+     * Copies as much of src to dst as possible.
+     */
+    static void copy(ByteBuffer src, ByteBuffer dst) {
         int srcLen = src.remaining();
         int dstLen = dst.remaining();
         if (srcLen > dstLen) {
@@ -204,18 +250,101 @@
         return dst;
     }
 
-    static String combine(String[] s) {
+    //
+    // Helps to trim long names (packages, nested/inner types) in logs/toString
+    //
+    static String toStringSimple(Object o) {
+        return o.getClass().getSimpleName() + "@" +
+                Integer.toHexString(System.identityHashCode(o));
+    }
+
+    //
+    // 1. It adds a number of remaining bytes;
+    // 2. Standard Buffer-type toString for CharBuffer (since it adheres to the
+    // contract of java.lang.CharSequence.toString() which is both not too
+    // useful and not too private)
+    //
+    static String toString(Buffer b) {
+        return toStringSimple(b)
+                + "[pos=" + b.position()
+                + " lim=" + b.limit()
+                + " cap=" + b.capacity()
+                + " rem=" + b.remaining() + "]";
+    }
+
+    static String toString(CharSequence s) {
+        return s == null
+                ? "null"
+                : toStringSimple(s) + "[len=" + s.length() + "]";
+    }
+
+    static String dump(Object... objects) {
+        return Arrays.toString(objects);
+    }
+
+    static final System.Logger logger = System.getLogger("java.net.http.WebSocket");
+
+    static final ByteBuffer EMPTY_BYTE_BUFFER = ByteBuffer.allocate(0);
+
+    static String webSocketSpecViolation(String section, String detail) {
+        return "RFC 6455 " + section + " " + detail;
+    }
+
+    static void logResponse(HttpResponseImpl r) {
+        if (!Log.requests()) {
+            return;
+        }
         StringBuilder sb = new StringBuilder();
-        sb.append('[');
-        boolean first = true;
-        for (String s1 : s) {
-            if (!first) {
-                sb.append(", ");
-                first = false;
+        String method = r.request().method();
+        URI uri = r.uri();
+        String uristring = uri == null ? "" : uri.toString();
+        sb.append('(').append(method).append(" ").append(uristring).append(") ").append(Integer.toString(r.statusCode()));
+        Log.logResponse(sb.toString());
+    }
+
+    static int remaining(ByteBuffer[] bufs) {
+        int remain = 0;
+        for (ByteBuffer buf : bufs)
+            remain += buf.remaining();
+        return remain;
+    }
+
+    // assumes buffer was written into starting at position zero
+    static void unflip(ByteBuffer buf) {
+        buf.position(buf.limit());
+        buf.limit(buf.capacity());
+    }
+
+    static void close(Closeable... chans) {
+        for (Closeable chan : chans) {
+            System.err.println("Closing " + chan);
+            try {
+                chan.close();
+            } catch (IOException e) {
             }
-            sb.append(s1);
         }
-        sb.append(']');
-        return sb.toString();
+    }
+
+    static ByteBuffer[] reduce(ByteBuffer[] bufs, int start, int number) {
+        if (start == 0 && number == bufs.length)
+            return bufs;
+        ByteBuffer[] nbufs = new ByteBuffer[number];
+        int j = 0;
+        for (int i=start; i<start+number; i++)
+            nbufs[j++] = bufs[i];
+        return nbufs;
     }
+
+    static String asString(ByteBuffer buf) {
+        byte[] b = new byte[buf.remaining()];
+        buf.get(b);
+        return new String(b, StandardCharsets.US_ASCII);
+    }
+
+    // Put all these static 'empty' singletons here
+    @SuppressWarnings("rawtypes")
+    static CompletableFuture[] EMPTY_CFARRAY = new CompletableFuture[0];
+
+    static ByteBuffer EMPTY_BYTEBUFFER = ByteBuffer.allocate(0);
+    static ByteBuffer[] EMPTY_BB_ARRAY = new ByteBuffer[0];
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WindowUpdateFrame.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2015, 2016, 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
+ */
+
+package java.net.http;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+class WindowUpdateFrame extends Http2Frame {
+
+    int windowUpdate;
+
+    WindowUpdateFrame() {
+        type = TYPE;
+    }
+
+    public final static int TYPE = 0x8;
+
+    public void setUpdate(int windowUpdate) {
+        this.windowUpdate = windowUpdate;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(super.toString())
+          .append(" WindowUpdate: ")
+          .append(windowUpdate);
+        return sb.toString();
+    }
+
+    public int getUpdate() {
+        return this.windowUpdate;
+    }
+
+    /**
+     */
+    @Override
+    void readIncomingImpl(ByteBufferConsumer bc) throws IOException {
+        if (length != 4) {
+            throw new IOException("Invalid WindowUpdate frame");
+        }
+        windowUpdate = bc.getInt() & 0x7fffffff;
+    }
+
+    @Override
+    void computeLength() {
+        length = 4;
+    }
+
+    @Override
+    void writeOutgoing(ByteBufferGenerator bg) {
+        super.writeOutgoing(bg);
+        ByteBuffer buf = bg.getBuffer(4);
+        buf.putInt(windowUpdate);
+    }
+}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/package-info.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/package-info.java	Thu Apr 28 23:08:16 2016 -0700
@@ -24,11 +24,11 @@
  */
 
 /**
- * <h2>High level HTTP API</h2>
- * This provides a high-level client interface to HTTP (versions 1.1 and 2).
- * Synchronous and asynchronous (via
- * {@link java.util.concurrent.CompletableFuture}) modes are provided. The main
- * classes defined are:
+ * <h2>High level HTTP and WebSocket API</h2>
+ * This provides a high-level client interfaces to HTTP (versions 1.1 and 2)
+ * and WebSocket. Synchronous and asynchronous (via {@link
+ * java.util.concurrent.CompletableFuture}) modes are provided for HTTP.
+ * WebSocket works in asynchronous mode only. The main types defined are:
  * <ul>
  *    <li>{@link java.net.http.HttpClient}</li>
  *    <li>{@link java.net.http.HttpRequest}</li>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/BinaryRepresentationWriter.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+
+interface BinaryRepresentationWriter {
+
+    boolean write(HeaderTable table, ByteBuffer destination);
+
+    BinaryRepresentationWriter reset();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/BulkSizeUpdateWriter.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+import java.util.Iterator;
+
+import static java.util.Objects.requireNonNull;
+
+final class BulkSizeUpdateWriter implements BinaryRepresentationWriter {
+
+    private final SizeUpdateWriter writer = new SizeUpdateWriter();
+    private Iterator<Integer> maxSizes;
+    private boolean writing;
+    private boolean configured;
+
+    BulkSizeUpdateWriter maxHeaderTableSizes(Iterable<Integer> sizes) {
+        if (configured) {
+            throw new IllegalStateException("Already configured");
+        }
+        requireNonNull(sizes, "sizes");
+        maxSizes = sizes.iterator();
+        configured = true;
+        return this;
+    }
+
+    @Override
+    public boolean write(HeaderTable table, ByteBuffer destination) {
+        if (!configured) {
+            throw new IllegalStateException("Configure first");
+        }
+        while (true) {
+            if (writing) {
+                if (!writer.write(table, destination)) {
+                    return false;
+                }
+                writing = false;
+            } else if (maxSizes.hasNext()) {
+                writing = true;
+                writer.reset();
+                writer.maxHeaderTableSize(maxSizes.next());
+            } else {
+                configured = false;
+                return true;
+            }
+        }
+    }
+
+    @Override
+    public BulkSizeUpdateWriter reset() {
+        maxSizes = null;
+        writing = false;
+        configured = false;
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/Decoder.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,506 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.net.ProtocolException;
+import java.nio.ByteBuffer;
+
+import static java.lang.String.format;
+import static java.util.Objects.requireNonNull;
+
+/**
+ * Decodes headers from their binary representation.
+ *
+ * <p>Typical lifecycle looks like this:
+ *
+ * <p> {@link #Decoder(int) new Decoder}
+ * ({@link #setMaxCapacity(int) setMaxCapacity}?
+ * {@link #decode(ByteBuffer, boolean, DecodingCallback) decode})*
+ *
+ * @apiNote
+ *
+ * <p> The design intentions behind Decoder were to facilitate flexible and
+ * incremental style of processing.
+ *
+ * <p> {@code Decoder} does not require a complete header block in a single
+ * {@code ByteBuffer}. The header block can be spread across many buffers of any
+ * size and decoded one-by-one the way it makes most sense for the user. This
+ * way also allows not to limit the size of the header block.
+ *
+ * <p> Headers are delivered to the {@linkplain DecodingCallback callback} as
+ * soon as they become decoded. Using the callback also gives the user a freedom
+ * to decide how headers are processed. The callback does not limit the number
+ * of headers decoded during single decoding operation.
+ *
+ * @since 9
+ */
+public final class Decoder {
+
+    private static final State[] states = new State[256];
+
+    static {
+        // To be able to do a quick lookup, each of 256 possibilities are mapped
+        // to corresponding states.
+        //
+        // We can safely do this since patterns 1, 01, 001, 0001, 0000 are
+        // Huffman prefixes and therefore are inherently not ambiguous.
+        //
+        // I do it mainly for better debugging (to not go each time step by step
+        // through if...else tree). As for performance win for the decoding, I
+        // believe is negligible.
+        for (int i = 0; i < states.length; i++) {
+            if ((i & 0b1000_0000) == 0b1000_0000) {
+                states[i] = State.INDEXED;
+            } else if ((i & 0b1100_0000) == 0b0100_0000) {
+                states[i] = State.LITERAL_WITH_INDEXING;
+            } else if ((i & 0b1110_0000) == 0b0010_0000) {
+                states[i] = State.SIZE_UPDATE;
+            } else if ((i & 0b1111_0000) == 0b0001_0000) {
+                states[i] = State.LITERAL_NEVER_INDEXED;
+            } else if ((i & 0b1111_0000) == 0b0000_0000) {
+                states[i] = State.LITERAL;
+            } else {
+                throw new InternalError(String.valueOf(i));
+            }
+        }
+    }
+
+    private final HeaderTable table;
+
+    private State state = State.READY;
+    private final IntegerReader integerReader;
+    private final StringReader stringReader;
+    private final StringBuilder name;
+    private final StringBuilder value;
+    private int intValue;
+    private boolean firstValueRead;
+    private boolean firstValueIndex;
+    private boolean nameHuffmanEncoded;
+    private boolean valueHuffmanEncoded;
+    private int capacity;
+
+    /**
+     * Constructs a {@code Decoder} with the specified initial capacity of the
+     * header table.
+     *
+     * <p> The value has to be agreed between decoder and encoder out-of-band,
+     * e.g. by a protocol that uses HPACK (see <a
+     * href="https://tools.ietf.org/html/rfc7541#section-4.2">4.2. Maximum Table
+     * Size</a>).
+     *
+     * @param capacity
+     *         a non-negative integer
+     *
+     * @throws IllegalArgumentException
+     *         if capacity is negative
+     */
+    public Decoder(int capacity) {
+        setMaxCapacity(capacity);
+        table = new HeaderTable(capacity);
+        integerReader = new IntegerReader();
+        stringReader = new StringReader();
+        name = new StringBuilder(512);
+        value = new StringBuilder(1024);
+    }
+
+    /**
+     * Sets a maximum capacity of the header table.
+     *
+     * <p> The value has to be agreed between decoder and encoder out-of-band,
+     * e.g. by a protocol that uses HPACK (see <a
+     * href="https://tools.ietf.org/html/rfc7541#section-4.2">4.2. Maximum Table
+     * Size</a>).
+     *
+     * @param capacity
+     *         a non-negative integer
+     *
+     * @throws IllegalArgumentException
+     *         if capacity is negative
+     */
+    public void setMaxCapacity(int capacity) {
+        if (capacity < 0) {
+            throw new IllegalArgumentException("capacity >= 0: " + capacity);
+        }
+        // FIXME: await capacity update if less than what was prior to it
+        this.capacity = capacity;
+    }
+
+    /**
+     * Decodes a header block from the given buffer to the given callback.
+     *
+     * <p> Suppose a header block is represented by a sequence of {@code
+     * ByteBuffer}s in the form of {@code Iterator<ByteBuffer>}. And the
+     * consumer of decoded headers is represented by the callback. Then to
+     * decode the header block, the following approach might be used:
+     *
+     * <pre>{@code
+     * while (buffers.hasNext()) {
+     *     ByteBuffer input = buffers.next();
+     *     decoder.decode(input, callback, !buffers.hasNext());
+     * }
+     * }</pre>
+     *
+     * <p> The decoder reads as much as possible of the header block from the
+     * given buffer, starting at the buffer's position, and increments its
+     * position to reflect the bytes read. The buffer's mark and limit will not
+     * be modified.
+     *
+     * <p> Once the method is invoked with {@code endOfHeaderBlock == true}, the
+     * current header block is deemed ended, and inconsistencies, if any, are
+     * reported immediately by throwing an {@code UncheckedIOException}.
+     *
+     * <p> Each callback method is called only after the implementation has
+     * processed the corresponding bytes. If the bytes revealed a decoding
+     * error, the callback method is not called.
+     *
+     * <p> In addition to exceptions thrown directly by the method, any
+     * exceptions thrown from the {@code callback} will bubble up.
+     *
+     * @apiNote The method asks for {@code endOfHeaderBlock} flag instead of
+     * returning it for two reasons. The first one is that the user of the
+     * decoder always knows which chunk is the last. The second one is to throw
+     * the most detailed exception possible, which might be useful for
+     * diagnosing issues.
+     *
+     * @implNote This implementation is not atomic in respect to decoding
+     * errors. In other words, if the decoding operation has thrown a decoding
+     * error, the decoder is no longer usable.
+     *
+     * @param headerBlock
+     *         the chunk of the header block, may be empty
+     * @param endOfHeaderBlock
+     *         true if the chunk is the final (or the only one) in the sequence
+     *
+     * @param consumer
+     *         the callback
+     * @throws UncheckedIOException
+     *         in case of a decoding error
+     * @throws NullPointerException
+     *         if either headerBlock or consumer are null
+     */
+    public void decode(ByteBuffer headerBlock, boolean endOfHeaderBlock,
+                       DecodingCallback consumer) {
+        requireNonNull(headerBlock, "headerBlock");
+        requireNonNull(consumer, "consumer");
+        while (headerBlock.hasRemaining()) {
+            proceed(headerBlock, consumer);
+        }
+        if (endOfHeaderBlock && state != State.READY) {
+            throw new UncheckedIOException(
+                    new ProtocolException("Unexpected end of header block"));
+        }
+    }
+
+    private void proceed(ByteBuffer input, DecodingCallback action) {
+        switch (state) {
+            case READY:
+                resumeReady(input);
+                break;
+            case INDEXED:
+                resumeIndexed(input, action);
+                break;
+            case LITERAL:
+                resumeLiteral(input, action);
+                break;
+            case LITERAL_WITH_INDEXING:
+                resumeLiteralWithIndexing(input, action);
+                break;
+            case LITERAL_NEVER_INDEXED:
+                resumeLiteralNeverIndexed(input, action);
+                break;
+            case SIZE_UPDATE:
+                resumeSizeUpdate(input, action);
+                break;
+            default:
+                throw new InternalError(
+                        "Unexpected decoder state: " + String.valueOf(state));
+        }
+    }
+
+    private void resumeReady(ByteBuffer input) {
+        int b = input.get(input.position()) & 0xff; // absolute read
+        State s = states[b];
+        switch (s) {
+            case INDEXED:
+                integerReader.configure(7);
+                state = State.INDEXED;
+                firstValueIndex = true;
+                break;
+            case LITERAL:
+                state = State.LITERAL;
+                firstValueIndex = (b & 0b0000_1111) != 0;
+                if (firstValueIndex) {
+                    integerReader.configure(4);
+                }
+                break;
+            case LITERAL_WITH_INDEXING:
+                state = State.LITERAL_WITH_INDEXING;
+                firstValueIndex = (b & 0b0011_1111) != 0;
+                if (firstValueIndex) {
+                    integerReader.configure(6);
+                }
+                break;
+            case LITERAL_NEVER_INDEXED:
+                state = State.LITERAL_NEVER_INDEXED;
+                firstValueIndex = (b & 0b0000_1111) != 0;
+                if (firstValueIndex) {
+                    integerReader.configure(4);
+                }
+                break;
+            case SIZE_UPDATE:
+                integerReader.configure(5);
+                state = State.SIZE_UPDATE;
+                firstValueIndex = true;
+                break;
+            default:
+                throw new InternalError(String.valueOf(s));
+        }
+        if (!firstValueIndex) {
+            input.get(); // advance, next stop: "String Literal"
+        }
+    }
+
+    //              0   1   2   3   4   5   6   7
+    //            +---+---+---+---+---+---+---+---+
+    //            | 1 |        Index (7+)         |
+    //            +---+---------------------------+
+    //
+    private void resumeIndexed(ByteBuffer input, DecodingCallback action) {
+        if (!integerReader.read(input)) {
+            return;
+        }
+        intValue = integerReader.get();
+        integerReader.reset();
+        try {
+            HeaderTable.HeaderField f = table.get(intValue);
+            action.onIndexed(intValue, f.name, f.value);
+        } finally {
+            state = State.READY;
+        }
+    }
+
+    //              0   1   2   3   4   5   6   7
+    //            +---+---+---+---+---+---+---+---+
+    //            | 0 | 0 | 0 | 0 |  Index (4+)   |
+    //            +---+---+-----------------------+
+    //            | H |     Value Length (7+)     |
+    //            +---+---------------------------+
+    //            | Value String (Length octets)  |
+    //            +-------------------------------+
+    //
+    //              0   1   2   3   4   5   6   7
+    //            +---+---+---+---+---+---+---+---+
+    //            | 0 | 0 | 0 | 0 |       0       |
+    //            +---+---+-----------------------+
+    //            | H |     Name Length (7+)      |
+    //            +---+---------------------------+
+    //            |  Name String (Length octets)  |
+    //            +---+---------------------------+
+    //            | H |     Value Length (7+)     |
+    //            +---+---------------------------+
+    //            | Value String (Length octets)  |
+    //            +-------------------------------+
+    //
+    private void resumeLiteral(ByteBuffer input, DecodingCallback action) {
+        if (!completeReading(input)) {
+            return;
+        }
+        try {
+            if (firstValueIndex) {
+                HeaderTable.HeaderField f = table.get(intValue);
+                action.onLiteral(intValue, f.name, value, valueHuffmanEncoded);
+            } else {
+                action.onLiteral(name, nameHuffmanEncoded, value, valueHuffmanEncoded);
+            }
+        } finally {
+            cleanUpAfterReading();
+        }
+    }
+
+    //
+    //              0   1   2   3   4   5   6   7
+    //            +---+---+---+---+---+---+---+---+
+    //            | 0 | 1 |      Index (6+)       |
+    //            +---+---+-----------------------+
+    //            | H |     Value Length (7+)     |
+    //            +---+---------------------------+
+    //            | Value String (Length octets)  |
+    //            +-------------------------------+
+    //
+    //              0   1   2   3   4   5   6   7
+    //            +---+---+---+---+---+---+---+---+
+    //            | 0 | 1 |           0           |
+    //            +---+---+-----------------------+
+    //            | H |     Name Length (7+)      |
+    //            +---+---------------------------+
+    //            |  Name String (Length octets)  |
+    //            +---+---------------------------+
+    //            | H |     Value Length (7+)     |
+    //            +---+---------------------------+
+    //            | Value String (Length octets)  |
+    //            +-------------------------------+
+    //
+    private void resumeLiteralWithIndexing(ByteBuffer input, DecodingCallback action) {
+        if (!completeReading(input)) {
+            return;
+        }
+        try {
+            //
+            // 1. (name, value) will be stored in the table as strings
+            // 2. Most likely the callback will also create strings from them
+            // ------------------------------------------------------------------------
+            //    Let's create those string beforehand (and only once!) to benefit everyone
+            //
+            String n;
+            String v = value.toString();
+            if (firstValueIndex) {
+                HeaderTable.HeaderField f = table.get(intValue);
+                n = f.name;
+                action.onLiteralWithIndexing(intValue, n, v, valueHuffmanEncoded);
+            } else {
+                n = name.toString();
+                action.onLiteralWithIndexing(n, nameHuffmanEncoded, v, valueHuffmanEncoded);
+            }
+            table.put(n, v);
+        } catch (IllegalArgumentException | IllegalStateException e) {
+            throw new UncheckedIOException(
+                    (IOException) new ProtocolException().initCause(e));
+        } finally {
+            cleanUpAfterReading();
+        }
+    }
+
+    //              0   1   2   3   4   5   6   7
+    //            +---+---+---+---+---+---+---+---+
+    //            | 0 | 0 | 0 | 1 |  Index (4+)   |
+    //            +---+---+-----------------------+
+    //            | H |     Value Length (7+)     |
+    //            +---+---------------------------+
+    //            | Value String (Length octets)  |
+    //            +-------------------------------+
+    //
+    //              0   1   2   3   4   5   6   7
+    //            +---+---+---+---+---+---+---+---+
+    //            | 0 | 0 | 0 | 1 |       0       |
+    //            +---+---+-----------------------+
+    //            | H |     Name Length (7+)      |
+    //            +---+---------------------------+
+    //            |  Name String (Length octets)  |
+    //            +---+---------------------------+
+    //            | H |     Value Length (7+)     |
+    //            +---+---------------------------+
+    //            | Value String (Length octets)  |
+    //            +-------------------------------+
+    //
+    private void resumeLiteralNeverIndexed(ByteBuffer input, DecodingCallback action) {
+        if (!completeReading(input)) {
+            return;
+        }
+        try {
+            if (firstValueIndex) {
+                HeaderTable.HeaderField f = table.get(intValue);
+                action.onLiteralNeverIndexed(intValue, f.name, value, valueHuffmanEncoded);
+            } else {
+                action.onLiteralNeverIndexed(name, nameHuffmanEncoded, value, valueHuffmanEncoded);
+            }
+        } finally {
+            cleanUpAfterReading();
+        }
+    }
+
+    //              0   1   2   3   4   5   6   7
+    //            +---+---+---+---+---+---+---+---+
+    //            | 0 | 0 | 1 |   Max size (5+)   |
+    //            +---+---------------------------+
+    //
+    private void resumeSizeUpdate(ByteBuffer input, DecodingCallback action) {
+        if (!integerReader.read(input)) {
+            return;
+        }
+        intValue = integerReader.get();
+        assert intValue >= 0;
+        if (intValue > capacity) {
+            throw new UncheckedIOException(new ProtocolException(
+                    format("Received capacity exceeds expected: " +
+                            "capacity=%s, expected=%s", intValue, capacity)));
+        }
+        integerReader.reset();
+        try {
+            action.onSizeUpdate(intValue);
+            table.setMaxSize(intValue);
+        } finally {
+            state = State.READY;
+        }
+    }
+
+    private boolean completeReading(ByteBuffer input) {
+        if (!firstValueRead) {
+            if (firstValueIndex) {
+                if (!integerReader.read(input)) {
+                    return false;
+                }
+                intValue = integerReader.get();
+                integerReader.reset();
+            } else {
+                if (!stringReader.read(input, name)) {
+                    return false;
+                }
+                nameHuffmanEncoded = stringReader.isHuffmanEncoded();
+                stringReader.reset();
+            }
+            firstValueRead = true;
+            return false;
+        } else {
+            if (!stringReader.read(input, value)) {
+                return false;
+            }
+        }
+        valueHuffmanEncoded = stringReader.isHuffmanEncoded();
+        stringReader.reset();
+        return true;
+    }
+
+    private void cleanUpAfterReading() {
+        name.setLength(0);
+        value.setLength(0);
+        firstValueRead = false;
+        state = State.READY;
+    }
+
+    private enum State {
+        READY,
+        INDEXED,
+        LITERAL_NEVER_INDEXED,
+        LITERAL,
+        LITERAL_WITH_INDEXING,
+        SIZE_UPDATE
+    }
+
+    HeaderTable getTable() {
+        return table;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/DecodingCallback.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Delivers results of the {@link Decoder#decode(ByteBuffer, boolean,
+ * DecodingCallback) decoding operation}.
+ *
+ * <p> Methods of the callback are never called by a decoder with any of the
+ * arguments being {@code null}.
+ *
+ * @apiNote
+ *
+ * <p> The callback provides methods for all possible <a
+ * href="https://tools.ietf.org/html/rfc7541#section-6">binary
+ * representations</a>. This could be useful for implementing an intermediary,
+ * logging, debugging, etc.
+ *
+ * <p> The callback is an interface in order to interoperate with lambdas (in
+ * the most common use case):
+ * <pre>{@code
+ *     DecodingCallback callback = (name, value) -> System.out.println(name + ", " + value);
+ * }</pre>
+ *
+ * <p> Names and values are {@link CharSequence}s rather than {@link String}s in
+ * order to allow users to decide whether or not they need to create objects. A
+ * {@code CharSequence} might be used in-place, for example, to be appended to
+ * an {@link Appendable} (e.g. {@link StringBuilder}) and then discarded.
+ *
+ * <p> That said, if a passed {@code CharSequence} needs to outlast the method
+ * call, it needs to be copied.
+ *
+ * @since 9
+ */
+@FunctionalInterface
+public interface DecodingCallback {
+
+    /**
+     * A method the more specific methods of the callback forward their calls
+     * to.
+     *
+     * @param name
+     *         header name
+     * @param value
+     *         header value
+     */
+    void onDecoded(CharSequence name, CharSequence value);
+
+    /**
+     * A more finer-grained version of {@link #onDecoded(CharSequence,
+     * CharSequence)} that also reports on value sensitivity.
+     *
+     * <p> Value sensitivity must be considered, for example, when implementing
+     * an intermediary. A {@code value} is sensitive if it was represented as <a
+     * href="https://tools.ietf.org/html/rfc7541#section-6.2.3">Literal Header
+     * Field Never Indexed</a>.
+     *
+     * <p> It is required that intermediaries MUST use the {@linkplain
+     * Encoder#header(CharSequence, CharSequence, boolean) same representation}
+     * for encoding this header field in order to protect its value which is not
+     * to be put at risk by compressing it.
+     *
+     * @implSpec
+     *
+     * <p> The default implementation invokes {@code onDecoded(name, value)}.
+     *
+     * @param name
+     *         header name
+     * @param value
+     *         header value
+     * @param sensitive
+     *         whether or not the value is sensitive
+     *
+     * @see #onLiteralNeverIndexed(int, CharSequence, CharSequence, boolean)
+     * @see #onLiteralNeverIndexed(CharSequence, boolean, CharSequence, boolean)
+     */
+    default void onDecoded(CharSequence name, CharSequence value,
+                           boolean sensitive) {
+        onDecoded(name, value);
+    }
+
+    /**
+     * An <a href="https://tools.ietf.org/html/rfc7541#section-6.1">Indexed
+     * Header Field</a> decoded.
+     *
+     * @implSpec
+     *
+     * <p> The default implementation invokes
+     * {@code onDecoded(name, value, false)}.
+     *
+     * @param index
+     *         index of an entry in the table
+     * @param name
+     *         header name
+     * @param value
+     *         header value
+     */
+    default void onIndexed(int index, CharSequence name, CharSequence value) {
+        onDecoded(name, value, false);
+    }
+
+    /**
+     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.2.2">Literal
+     * Header Field without Indexing</a> decoded, where a {@code name} was
+     * referred by an {@code index}.
+     *
+     * @implSpec
+     *
+     * <p> The default implementation invokes
+     * {@code onDecoded(name, value, false)}.
+     *
+     * @param index
+     *         index of an entry in the table
+     * @param name
+     *         header name
+     * @param value
+     *         header value
+     * @param valueHuffman
+     *         if the {@code value} was Huffman encoded
+     */
+    default void onLiteral(int index, CharSequence name,
+                           CharSequence value, boolean valueHuffman) {
+        onDecoded(name, value, false);
+    }
+
+    /**
+     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.2.2">Literal
+     * Header Field without Indexing</a> decoded, where both a {@code name} and
+     * a {@code value} were literal.
+     *
+     * @implSpec
+     *
+     * <p> The default implementation invokes
+     * {@code onDecoded(name, value, false)}.
+     *
+     * @param name
+     *         header name
+     * @param nameHuffman
+     *         if the {@code name} was Huffman encoded
+     * @param value
+     *         header value
+     * @param valueHuffman
+     *         if the {@code value} was Huffman encoded
+     */
+    default void onLiteral(CharSequence name, boolean nameHuffman,
+                           CharSequence value, boolean valueHuffman) {
+        onDecoded(name, value, false);
+    }
+
+    /**
+     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.2.3">Literal
+     * Header Field Never Indexed</a> decoded, where a {@code name}
+     * was referred by an {@code index}.
+     *
+     * @implSpec
+     *
+     * <p> The default implementation invokes
+     * {@code onDecoded(name, value, true)}.
+     *
+     * @param index
+     *         index of an entry in the table
+     * @param name
+     *         header name
+     * @param value
+     *         header value
+     * @param valueHuffman
+     *         if the {@code value} was Huffman encoded
+     */
+    default void onLiteralNeverIndexed(int index, CharSequence name,
+                                       CharSequence value,
+                                       boolean valueHuffman) {
+        onDecoded(name, value, true);
+    }
+
+    /**
+     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.2.3">Literal
+     * Header Field Never Indexed</a> decoded, where both a {@code
+     * name} and a {@code value} were literal.
+     *
+     * @implSpec
+     *
+     * <p> The default implementation invokes
+     * {@code onDecoded(name, value, true)}.
+     *
+     * @param name
+     *         header name
+     * @param nameHuffman
+     *         if the {@code name} was Huffman encoded
+     * @param value
+     *         header value
+     * @param valueHuffman
+     *         if the {@code value} was Huffman encoded
+     */
+    default void onLiteralNeverIndexed(CharSequence name, boolean nameHuffman,
+                                       CharSequence value, boolean valueHuffman) {
+        onDecoded(name, value, true);
+    }
+
+    /**
+     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.2.1">Literal
+     * Header Field with Incremental Indexing</a> decoded, where a {@code name}
+     * was referred by an {@code index}.
+     *
+     * @implSpec
+     *
+     * <p> The default implementation invokes
+     * {@code onDecoded(name, value, false)}.
+     *
+     * @param index
+     *         index of an entry in the table
+     * @param name
+     *         header name
+     * @param value
+     *         header value
+     * @param valueHuffman
+     *         if the {@code value} was Huffman encoded
+     */
+    default void onLiteralWithIndexing(int index,
+                                       CharSequence name,
+                                       CharSequence value, boolean valueHuffman) {
+        onDecoded(name, value, false);
+    }
+
+    /**
+     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.2.1">Literal
+     * Header Field with Incremental Indexing</a> decoded, where both a {@code
+     * name} and a {@code value} were literal.
+     *
+     * @implSpec
+     *
+     * <p> The default implementation invokes
+     * {@code onDecoded(name, value, false)}.
+     *
+     * @param name
+     *         header name
+     * @param nameHuffman
+     *         if the {@code name} was Huffman encoded
+     * @param value
+     *         header value
+     * @param valueHuffman
+     *         if the {@code value} was Huffman encoded
+     */
+    default void onLiteralWithIndexing(CharSequence name, boolean nameHuffman,
+                                       CharSequence value, boolean valueHuffman) {
+        onDecoded(name, value, false);
+    }
+
+    /**
+     * A <a href="https://tools.ietf.org/html/rfc7541#section-6.3">Dynamic Table
+     * Size Update</a> decoded.
+     *
+     * @implSpec
+     *
+     * <p> The default implementation does nothing.
+     *
+     * @param capacity
+     *         new capacity of the header table
+     */
+    default void onSizeUpdate(int capacity) { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/Encoder.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+import java.nio.ReadOnlyBufferException;
+import java.util.LinkedList;
+import java.util.List;
+
+import static java.lang.String.format;
+import static java.util.Objects.requireNonNull;
+
+/**
+ * Encodes headers to their binary representation.
+ *
+ * <p>Typical lifecycle looks like this:
+ *
+ * <p> {@link #Encoder(int) new Encoder}
+ * ({@link #setMaxCapacity(int) setMaxCapacity}?
+ * {@link #encode(ByteBuffer) encode})*
+ *
+ * <p> Suppose headers are represented by {@code Map<String, List<String>>}. A
+ * supplier and a consumer of {@link ByteBuffer}s in forms of {@code
+ * Supplier<ByteBuffer>} and {@code Consumer<ByteBuffer>} respectively. Then to
+ * encode headers, the following approach might be used:
+ *
+ * <pre>{@code
+ *     for (Map.Entry<String, List<String>> h : headers.entrySet()) {
+ *         String name = h.getKey();
+ *         for (String value : h.getValue()) {
+ *             encoder.header(name, value);        // Set up header
+ *             boolean encoded;
+ *             do {
+ *                 ByteBuffer b = buffersSupplier.get();
+ *                 encoded = encoder.encode(b);    // Encode the header
+ *                 buffersConsumer.accept(b);
+ *             } while (!encoded);
+ *         }
+ *     }
+ * }</pre>
+ *
+ * <p> Though the specification <a
+ * href="https://tools.ietf.org/html/rfc7541#section-2"> does not define</a> how
+ * an encoder is to be implemented, a default implementation is provided by the
+ * method {@link #header(CharSequence, CharSequence, boolean)}.
+ *
+ * <p> To provide a custom encoding implementation, {@code Encoder} has to be
+ * extended. A subclass then can access methods for encoding using specific
+ * representations (e.g. {@link #literal(int, CharSequence, boolean) literal},
+ * {@link #indexed(int) indexed}, etc.)
+ *
+ * @apiNote
+ *
+ * <p> An Encoder provides an incremental way of encoding headers.
+ * {@link #encode(ByteBuffer)} takes a buffer a returns a boolean indicating
+ * whether, or not, the buffer was sufficiently sized to hold the
+ * remaining of the encoded representation.
+ *
+ * <p> This way, there's no need to provide a buffer of a specific size, or to
+ * resize (and copy) the buffer on demand, when the remaining encoded
+ * representation will not fit in the buffer's remaining space. Instead, an
+ * array of existing buffers can be used, prepended with a frame that encloses
+ * the resulting header block afterwards.
+ *
+ * <p> Splitting the encoding operation into header set up and header encoding,
+ * separates long lived arguments ({@code name}, {@code value}, {@code
+ * sensitivity}, etc.) from the short lived ones (e.g. {@code buffer}),
+ * simplifying each operation itself.
+ *
+ * @implNote
+ *
+ * <p> The default implementation does not use dynamic table. It reports to a
+ * coupled Decoder a size update with the value of {@code 0}, and never changes
+ * it afterwards.
+ *
+ * @since 9
+ */
+public class Encoder {
+
+    // TODO: enum: no huffman/smart huffman/always huffman
+    private static final boolean DEFAULT_HUFFMAN = true;
+
+    private final IndexedWriter indexedWriter = new IndexedWriter();
+    private final LiteralWriter literalWriter = new LiteralWriter();
+    private final LiteralNeverIndexedWriter literalNeverIndexedWriter
+            = new LiteralNeverIndexedWriter();
+    private final LiteralWithIndexingWriter literalWithIndexingWriter
+            = new LiteralWithIndexingWriter();
+    private final SizeUpdateWriter sizeUpdateWriter = new SizeUpdateWriter();
+    private final BulkSizeUpdateWriter bulkSizeUpdateWriter
+            = new BulkSizeUpdateWriter();
+
+    private BinaryRepresentationWriter writer;
+    private final HeaderTable headerTable;
+
+    private boolean encoding;
+
+    private int maxCapacity;
+    private int currCapacity;
+    private int lastCapacity;
+    private long minCapacity;
+    private boolean capacityUpdate;
+    private boolean configuredCapacityUpdate;
+
+    /**
+     * Constructs an {@code Encoder} with the specified maximum capacity of the
+     * header table.
+     *
+     * <p> The value has to be agreed between decoder and encoder out-of-band,
+     * e.g. by a protocol that uses HPACK (see <a
+     * href="https://tools.ietf.org/html/rfc7541#section-4.2">4.2. Maximum Table
+     * Size</a>).
+     *
+     * @param maxCapacity
+     *         a non-negative integer
+     *
+     * @throws IllegalArgumentException
+     *         if maxCapacity is negative
+     */
+    public Encoder(int maxCapacity) {
+        if (maxCapacity < 0) {
+            throw new IllegalArgumentException("maxCapacity >= 0: " + maxCapacity);
+        }
+        // Initial maximum capacity update mechanics
+        minCapacity = Long.MAX_VALUE;
+        currCapacity = -1;
+        setMaxCapacity(maxCapacity);
+        headerTable = new HeaderTable(lastCapacity);
+    }
+
+    /**
+     * Sets up the given header {@code (name, value)}.
+     *
+     * <p> Fixates {@code name} and {@code value} for the duration of encoding.
+     *
+     * @param name
+     *         the name
+     * @param value
+     *         the value
+     *
+     * @throws NullPointerException
+     *         if any of the arguments are {@code null}
+     * @throws IllegalStateException
+     *         if the encoder hasn't fully encoded the previous header, or
+     *         hasn't yet started to encode it
+     * @see #header(CharSequence, CharSequence, boolean)
+     */
+    public void header(CharSequence name, CharSequence value)
+            throws IllegalStateException {
+        header(name, value, false);
+    }
+
+    /**
+     * Sets up the given header {@code (name, value)} with possibly sensitive
+     * value.
+     *
+     * <p> Fixates {@code name} and {@code value} for the duration of encoding.
+     *
+     * @param name
+     *         the name
+     * @param value
+     *         the value
+     * @param sensitive
+     *         whether or not the value is sensitive
+     *
+     * @throws NullPointerException
+     *         if any of the arguments are {@code null}
+     * @throws IllegalStateException
+     *         if the encoder hasn't fully encoded the previous header, or
+     *         hasn't yet started to encode it
+     * @see #header(CharSequence, CharSequence)
+     * @see DecodingCallback#onDecoded(CharSequence, CharSequence, boolean)
+     */
+    public void header(CharSequence name, CharSequence value,
+                       boolean sensitive) throws IllegalStateException {
+        // Arguably a good balance between complexity of implementation and
+        // efficiency of encoding
+        requireNonNull(name, "name");
+        requireNonNull(value, "value");
+        HeaderTable t = getHeaderTable();
+        int index = t.indexOf(name, value);
+        if (index > 0) {
+            indexed(index);
+        } else if (index < 0) {
+            if (sensitive) {
+                literalNeverIndexed(-index, value, DEFAULT_HUFFMAN);
+            } else {
+                literal(-index, value, DEFAULT_HUFFMAN);
+            }
+        } else {
+            if (sensitive) {
+                literalNeverIndexed(name, DEFAULT_HUFFMAN, value, DEFAULT_HUFFMAN);
+            } else {
+                literal(name, DEFAULT_HUFFMAN, value, DEFAULT_HUFFMAN);
+            }
+        }
+    }
+
+    /**
+     * Sets a maximum capacity of the header table.
+     *
+     * <p> The value has to be agreed between decoder and encoder out-of-band,
+     * e.g. by a protocol that uses HPACK (see <a
+     * href="https://tools.ietf.org/html/rfc7541#section-4.2">4.2. Maximum Table
+     * Size</a>).
+     *
+     * <p> May be called any number of times after or before a complete header
+     * has been encoded.
+     *
+     * <p> If the encoder decides to change the actual capacity, an update will
+     * be encoded before a new encoding operation starts.
+     *
+     * @param capacity
+     *         a non-negative integer
+     *
+     * @throws IllegalArgumentException
+     *         if capacity is negative
+     * @throws IllegalStateException
+     *         if the encoder hasn't fully encoded the previous header, or
+     *         hasn't yet started to encode it
+     */
+    public void setMaxCapacity(int capacity) {
+        checkEncoding();
+        if (capacity < 0) {
+            throw new IllegalArgumentException("capacity >= 0: " + capacity);
+        }
+        int calculated = calculateCapacity(capacity);
+        if (calculated < 0 || calculated > capacity) {
+            throw new IllegalArgumentException(
+                    format("0 <= calculated <= capacity: calculated=%s, capacity=%s",
+                            calculated, capacity));
+        }
+        capacityUpdate = true;
+        // maxCapacity needs to be updated unconditionally, so the encoder
+        // always has the newest one (in case it decides to update it later
+        // unsolicitedly)
+        // Suppose maxCapacity = 4096, and the encoder has decided to use only
+        // 2048. It later can choose anything else from the region [0, 4096].
+        maxCapacity = capacity;
+        lastCapacity = calculated;
+        minCapacity = Math.min(minCapacity, lastCapacity);
+    }
+
+    protected int calculateCapacity(int maxCapacity) {
+        // Default implementation of the Encoder won't add anything to the
+        // table, therefore no need for a table space
+        return 0;
+    }
+
+    /**
+     * Encodes the {@linkplain #header(CharSequence, CharSequence) set up}
+     * header into the given buffer.
+     *
+     * <p> The encoder writes as much as possible of the header's binary
+     * representation into the given buffer, starting at the buffer's position,
+     * and increments its position to reflect the bytes written. The buffer's
+     * mark and limit will not be modified.
+     *
+     * <p> Once the method has returned {@code true}, the current header is
+     * deemed encoded. A new header may be set up.
+     *
+     * @param headerBlock
+     *         the buffer to encode the header into, may be empty
+     *
+     * @return {@code true} if the current header has been fully encoded,
+     *         {@code false} otherwise
+     *
+     * @throws NullPointerException
+     *         if the buffer is {@code null}
+     * @throws ReadOnlyBufferException
+     *         if this buffer is read-only
+     * @throws IllegalStateException
+     *         if there is no set up header
+     */
+    public final boolean encode(ByteBuffer headerBlock) {
+        if (!encoding) {
+            throw new IllegalStateException("A header hasn't been set up");
+        }
+        if (!prependWithCapacityUpdate(headerBlock)) {
+            return false;
+        }
+        boolean done = writer.write(headerTable, headerBlock);
+        if (done) {
+            writer.reset(); // FIXME: WHY?
+            encoding = false;
+        }
+        return done;
+    }
+
+    private boolean prependWithCapacityUpdate(ByteBuffer headerBlock) {
+        if (capacityUpdate) {
+            if (!configuredCapacityUpdate) {
+                List<Integer> sizes = new LinkedList<>();
+                if (minCapacity < currCapacity) {
+                    sizes.add((int) minCapacity);
+                    if (minCapacity != lastCapacity) {
+                        sizes.add(lastCapacity);
+                    }
+                } else if (lastCapacity != currCapacity) {
+                    sizes.add(lastCapacity);
+                }
+                bulkSizeUpdateWriter.maxHeaderTableSizes(sizes);
+                configuredCapacityUpdate = true;
+            }
+            boolean done = bulkSizeUpdateWriter.write(headerTable, headerBlock);
+            if (done) {
+                minCapacity = lastCapacity;
+                currCapacity = lastCapacity;
+                bulkSizeUpdateWriter.reset();
+                capacityUpdate = false;
+                configuredCapacityUpdate = false;
+            }
+            return done;
+        }
+        return true;
+    }
+
+    protected final void indexed(int index) throws IndexOutOfBoundsException {
+        checkEncoding();
+        encoding = true;
+        writer = indexedWriter.index(index);
+    }
+
+    protected final void literal(int index, CharSequence value,
+                                 boolean useHuffman)
+            throws IndexOutOfBoundsException {
+        checkEncoding();
+        encoding = true;
+        writer = literalWriter
+                .index(index).value(value, useHuffman);
+    }
+
+    protected final void literal(CharSequence name, boolean nameHuffman,
+                                 CharSequence value, boolean valueHuffman) {
+        checkEncoding();
+        encoding = true;
+        writer = literalWriter
+                .name(name, nameHuffman).value(value, valueHuffman);
+    }
+
+    protected final void literalNeverIndexed(int index,
+                                             CharSequence value,
+                                             boolean valueHuffman)
+            throws IndexOutOfBoundsException {
+        checkEncoding();
+        encoding = true;
+        writer = literalNeverIndexedWriter
+                .index(index).value(value, valueHuffman);
+    }
+
+    protected final void literalNeverIndexed(CharSequence name,
+                                             boolean nameHuffman,
+                                             CharSequence value,
+                                             boolean valueHuffman) {
+        checkEncoding();
+        encoding = true;
+        writer = literalNeverIndexedWriter
+                .name(name, nameHuffman).value(value, valueHuffman);
+    }
+
+    protected final void literalWithIndexing(int index,
+                                             CharSequence value,
+                                             boolean valueHuffman)
+            throws IndexOutOfBoundsException {
+        checkEncoding();
+        encoding = true;
+        writer = literalWithIndexingWriter
+                .index(index).value(value, valueHuffman);
+    }
+
+    protected final void literalWithIndexing(CharSequence name,
+                                             boolean nameHuffman,
+                                             CharSequence value,
+                                             boolean valueHuffman) {
+        checkEncoding();
+        encoding = true;
+        writer = literalWithIndexingWriter
+                .name(name, nameHuffman).value(value, valueHuffman);
+    }
+
+    protected final void sizeUpdate(int capacity)
+            throws IllegalArgumentException {
+        checkEncoding();
+        // Ensure subclass follows the contract
+        if (capacity > this.maxCapacity) {
+            throw new IllegalArgumentException(
+                    format("capacity <= maxCapacity: capacity=%s, maxCapacity=%s",
+                            capacity, maxCapacity));
+        }
+        writer = sizeUpdateWriter.maxHeaderTableSize(capacity);
+    }
+
+    protected final int getMaxCapacity() {
+        return maxCapacity;
+    }
+
+    protected final HeaderTable getHeaderTable() {
+        return headerTable;
+    }
+
+    protected final void checkEncoding() {
+        if (encoding) {
+            throw new IllegalStateException(
+                    "Previous encoding operation hasn't finished yet");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/HeaderTable.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,511 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import static java.lang.String.format;
+
+//
+// Header Table combined from two tables: static and dynamic.
+//
+// There is a single address space for index values. Index-aware methods
+// correspond to the table as a whole. Size-aware methods only to the dynamic
+// part of it.
+//
+final class HeaderTable {
+
+    private static final HeaderField[] staticTable = {
+            null, // To make index 1-based, instead of 0-based
+            new HeaderField(":authority"),
+            new HeaderField(":method", "GET"),
+            new HeaderField(":method", "POST"),
+            new HeaderField(":path", "/"),
+            new HeaderField(":path", "/index.html"),
+            new HeaderField(":scheme", "http"),
+            new HeaderField(":scheme", "https"),
+            new HeaderField(":status", "200"),
+            new HeaderField(":status", "204"),
+            new HeaderField(":status", "206"),
+            new HeaderField(":status", "304"),
+            new HeaderField(":status", "400"),
+            new HeaderField(":status", "404"),
+            new HeaderField(":status", "500"),
+            new HeaderField("accept-charset"),
+            new HeaderField("accept-encoding", "gzip, deflate"),
+            new HeaderField("accept-language"),
+            new HeaderField("accept-ranges"),
+            new HeaderField("accept"),
+            new HeaderField("access-control-allow-origin"),
+            new HeaderField("age"),
+            new HeaderField("allow"),
+            new HeaderField("authorization"),
+            new HeaderField("cache-control"),
+            new HeaderField("content-disposition"),
+            new HeaderField("content-encoding"),
+            new HeaderField("content-language"),
+            new HeaderField("content-length"),
+            new HeaderField("content-location"),
+            new HeaderField("content-range"),
+            new HeaderField("content-type"),
+            new HeaderField("cookie"),
+            new HeaderField("date"),
+            new HeaderField("etag"),
+            new HeaderField("expect"),
+            new HeaderField("expires"),
+            new HeaderField("from"),
+            new HeaderField("host"),
+            new HeaderField("if-match"),
+            new HeaderField("if-modified-since"),
+            new HeaderField("if-none-match"),
+            new HeaderField("if-range"),
+            new HeaderField("if-unmodified-since"),
+            new HeaderField("last-modified"),
+            new HeaderField("link"),
+            new HeaderField("location"),
+            new HeaderField("max-forwards"),
+            new HeaderField("proxy-authenticate"),
+            new HeaderField("proxy-authorization"),
+            new HeaderField("range"),
+            new HeaderField("referer"),
+            new HeaderField("refresh"),
+            new HeaderField("retry-after"),
+            new HeaderField("server"),
+            new HeaderField("set-cookie"),
+            new HeaderField("strict-transport-security"),
+            new HeaderField("transfer-encoding"),
+            new HeaderField("user-agent"),
+            new HeaderField("vary"),
+            new HeaderField("via"),
+            new HeaderField("www-authenticate")
+    };
+
+    private static final int STATIC_TABLE_LENGTH = staticTable.length - 1;
+    private static final int ENTRY_SIZE = 32;
+    private static final Map<String, LinkedHashMap<String, Integer>> staticIndexes;
+
+    static {
+        staticIndexes = new HashMap<>(STATIC_TABLE_LENGTH);
+        for (int i = 1; i <= STATIC_TABLE_LENGTH; i++) {
+            HeaderField f = staticTable[i];
+            Map<String, Integer> values = staticIndexes
+                    .computeIfAbsent(f.name, k -> new LinkedHashMap<>());
+            values.put(f.value, i);
+        }
+    }
+
+    private final Table dynamicTable = new Table(0);
+    private int maxSize;
+    private int size;
+
+    public HeaderTable(int maxSize) {
+        setMaxSize(maxSize);
+    }
+
+    //
+    // The method returns:
+    //
+    // * a positive integer i where i (i = [1..Integer.MAX_VALUE]) is an
+    // index of an entry with a header (n, v), where n.equals(name) &&
+    // v.equals(value)
+    //
+    // * a negative integer j where j (j = [-Integer.MAX_VALUE..-1]) is an
+    // index of an entry with a header (n, v), where n.equals(name)
+    //
+    // * 0 if there's no entry e such that e.getName().equals(name)
+    //
+    // The rationale behind this design is to allow to pack more useful data
+    // into a single invocation, facilitating a single pass where possible
+    // (the idea is the same as in java.util.Arrays.binarySearch(int[], int)).
+    //
+    public int indexOf(CharSequence name, CharSequence value) {
+        // Invoking toString() will possibly allocate Strings for the sake of
+        // the search, which doesn't feel right.
+        String n = name.toString();
+        String v = value.toString();
+
+        // 1. Try exact match in the static region
+        Map<String, Integer> values = staticIndexes.get(n);
+        if (values != null) {
+            Integer idx = values.get(v);
+            if (idx != null) {
+                return idx;
+            }
+        }
+        // 2. Try exact match in the dynamic region
+        int didx = dynamicTable.indexOf(n, v);
+        if (didx > 0) {
+            return STATIC_TABLE_LENGTH + didx;
+        } else if (didx < 0) {
+            if (values != null) {
+                // 3. Return name match from the static region
+                return -values.values().iterator().next(); // Iterator allocation
+            } else {
+                // 4. Return name match from the dynamic region
+                return -STATIC_TABLE_LENGTH + didx;
+            }
+        } else {
+            if (values != null) {
+                // 3. Return name match from the static region
+                return -values.values().iterator().next(); // Iterator allocation
+            } else {
+                return 0;
+            }
+        }
+    }
+
+    public int size() {
+        return size;
+    }
+
+    public int maxSize() {
+        return maxSize;
+    }
+
+    public int length() {
+        return STATIC_TABLE_LENGTH + dynamicTable.size();
+    }
+
+    HeaderField get(int index) {
+        checkIndex(index);
+        if (index <= STATIC_TABLE_LENGTH) {
+            return staticTable[index];
+        } else {
+            return dynamicTable.get(index - STATIC_TABLE_LENGTH);
+        }
+    }
+
+    void put(CharSequence name, CharSequence value) {
+        // Invoking toString() will possibly allocate Strings. But that's
+        // unavoidable at this stage. If a CharSequence is going to be stored in
+        // the table, it must not be mutable (e.g. for the sake of hashing).
+        put(new HeaderField(name.toString(), value.toString()));
+    }
+
+    private void put(HeaderField h) {
+        int entrySize = sizeOf(h);
+        while (entrySize > maxSize - size && size != 0) {
+            evictEntry();
+        }
+        if (entrySize > maxSize - size) {
+            return;
+        }
+        size += entrySize;
+        dynamicTable.add(h);
+    }
+
+    void setMaxSize(int maxSize) {
+        if (maxSize < 0) {
+            throw new IllegalArgumentException
+                    ("maxSize >= 0: maxSize=" + maxSize);
+        }
+        while (maxSize < size && size != 0) {
+            evictEntry();
+        }
+        this.maxSize = maxSize;
+        int upperBound = (maxSize / ENTRY_SIZE) + 1;
+        this.dynamicTable.setCapacity(upperBound);
+    }
+
+    HeaderField evictEntry() {
+        HeaderField f = dynamicTable.remove();
+        size -= sizeOf(f);
+        return f;
+    }
+
+    @Override
+    public String toString() {
+        double used = maxSize == 0 ? 0 : 100 * (((double) size) / maxSize);
+        return format("entries: %d; used %s/%s (%.1f%%)", dynamicTable.size(),
+                size, maxSize, used);
+    }
+
+    int checkIndex(int index) {
+        if (index < 1 || index > STATIC_TABLE_LENGTH + dynamicTable.size()) {
+            throw new IllegalArgumentException(
+                    format("1 <= index <= length(): index=%s, length()=%s",
+                            index, length()));
+        }
+        return index;
+    }
+
+    int sizeOf(HeaderField f) {
+        return f.name.length() + f.value.length() + ENTRY_SIZE;
+    }
+
+    //
+    // Diagnostic information in the form used in the RFC 7541
+    //
+    String getStateString() {
+        if (size == 0) {
+            return "empty.";
+        }
+
+        StringBuilder b = new StringBuilder();
+        for (int i = 1, size = dynamicTable.size(); i <= size; i++) {
+            HeaderField e = dynamicTable.get(i);
+            b.append(format("[%3d] (s = %3d) %s: %s\n", i,
+                    sizeOf(e), e.name, e.value));
+        }
+        b.append(format("      Table size:%4s", this.size));
+        return b.toString();
+    }
+
+    // Convert to a Value Object (JDK-8046159)?
+    static final class HeaderField {
+
+        final String name;
+        final String value;
+
+        public HeaderField(String name) {
+            this(name, "");
+        }
+
+        public HeaderField(String name, String value) {
+            this.name = name;
+            this.value = value;
+        }
+
+        @Override
+        public String toString() {
+            return value.isEmpty() ? name : name + ": " + value;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (o == null || getClass() != o.getClass()) {
+                return false;
+            }
+            HeaderField that = (HeaderField) o;
+            return name.equals(that.name) && value.equals(that.value);
+        }
+
+        @Override
+        public int hashCode() {
+            return 31 * (name.hashCode()) + value.hashCode();
+        }
+    }
+
+    //
+    // In order to be able to find an index of an entry with the given contents
+    // in the dynamic table an effective inverse mapping is needed. Here's a
+    // simple idea behind such a mapping.
+    //
+    // # The problem:
+    //
+    // We have a queue with an O(1) lookup by index:
+    //
+    //     get: index -> x
+    //
+    // What we also want is an O(1) reverse lookup:
+    //
+    //     indexOf: x -> index
+    //
+    // # Solution:
+    //
+    // Let's store an inverse mapping as a Map<X, Integer>. This have a problem
+    // that when a new element is added to the queue all indexes in the map
+    // becomes invalid. Namely, each i becomes shifted by 1 to the right:
+    //
+    //     i -> i + 1
+    //
+    // And the new element is assigned with an index of 1. This would seem to
+    // require a pass through the map incrementing all indexes (map values) by
+    // 1, which is O(n).
+    //
+    // The good news is we can do much better then this!
+    //
+    // Let's create a single field of type long, called 'counter'. Then each
+    // time a new element 'x' is added to the queue, a value of this field gets
+    // incremented. Then the resulting value of the 'counter_x' is then put as a
+    // value under key 'x' to the map:
+    //
+    //    map.put(x, counter_x)
+    //
+    // It gives us a map that maps an element to a value the counter had at the
+    // time the element had been added.
+    //
+    // In order to retrieve an index of any element 'x' in the queue (at any
+    // given time) we simply need to subtract the value (the snapshot of the
+    // counter at the time when the 'x' was added) from the current value of the
+    // counter. This operation basically answers the question:
+    //
+    //     How many elements ago 'x' was the tail of the queue?
+    //
+    // Which is the same as its index in the queue now. Given, of course, it's
+    // still in the queue.
+    //
+    // I'm pretty sure in a real life long overflow will never happen, so it's
+    // not too practical to add recalibrating code, but a pedantic person might
+    // want to do so:
+    //
+    //     if (counter == Long.MAX_VALUE) {
+    //         recalibrate();
+    //     }
+    //
+    // Where 'recalibrate()' goes through the table doing this:
+    //
+    //  value -= counter
+    //
+    // That's given, of course, the size of the table itself is less than
+    // Long.MAX_VALUE :-)
+    //
+    private static final class Table {
+
+        private final Map<String, Map<String, Long>> map;
+        private final CircularBuffer<HeaderField> buffer;
+        private long counter = 1;
+
+        Table(int capacity) {
+            buffer = new CircularBuffer<>(capacity);
+            map = new HashMap<>(capacity);
+        }
+
+        void add(HeaderField f) {
+            buffer.add(f);
+            Map<String, Long> values = map.computeIfAbsent(f.name, k -> new HashMap<>());
+            values.put(f.value, counter++);
+        }
+
+        HeaderField get(int index) {
+            return buffer.get(index - 1);
+        }
+
+        int indexOf(String name, String value) {
+            Map<String, Long> values = map.get(name);
+            if (values == null) {
+                return 0;
+            }
+            Long index = values.get(value);
+            if (index != null) {
+                return (int) (counter - index);
+            } else {
+                assert !values.isEmpty();
+                Long any = values.values().iterator().next(); // Iterator allocation
+                return -(int) (counter - any);
+            }
+        }
+
+        HeaderField remove() {
+            HeaderField f = buffer.remove();
+            Map<String, Long> values = map.get(f.name);
+            Long index = values.remove(f.value);
+            assert index != null;
+            if (values.isEmpty()) {
+                map.remove(f.name);
+            }
+            return f;
+        }
+
+        int size() {
+            return buffer.size;
+        }
+
+        public void setCapacity(int capacity) {
+            buffer.resize(capacity);
+        }
+    }
+
+    //                    head
+    //                    v
+    // [ ][ ][A][B][C][D][ ][ ][ ]
+    //        ^
+    //        tail
+    //
+    //       |<- size ->| (4)
+    // |<------ capacity ------->| (9)
+    //
+    static final class CircularBuffer<E> {
+
+        int tail, head, size, capacity;
+        Object[] elements;
+
+        CircularBuffer(int capacity) {
+            this.capacity = capacity;
+            elements = new Object[capacity];
+        }
+
+        void add(E elem) {
+            if (size == capacity) {
+                throw new IllegalStateException(
+                        format("No room for '%s': capacity=%s", elem, capacity));
+            }
+            elements[head] = elem;
+            head = (head + 1) % capacity;
+            size++;
+        }
+
+        @SuppressWarnings("unchecked")
+        E remove() {
+            if (size == 0) {
+                throw new NoSuchElementException("Empty");
+            }
+            E elem = (E) elements[tail];
+            elements[tail] = null;
+            tail = (tail + 1) % capacity;
+            size--;
+            return elem;
+        }
+
+        @SuppressWarnings("unchecked")
+        E get(int index) {
+            if (index < 0 || index >= size) {
+                throw new IndexOutOfBoundsException(
+                        format("0 <= index <= capacity: index=%s, capacity=%s",
+                                index, capacity));
+            }
+            int idx = (tail + (size - index - 1)) % capacity;
+            return (E) elements[idx];
+        }
+
+        public void resize(int newCapacity) {
+            if (newCapacity < size) {
+                throw new IllegalStateException(
+                        format("newCapacity >= size: newCapacity=%s, size=%s",
+                                newCapacity, size));
+            }
+
+            Object[] newElements = new Object[newCapacity];
+
+            if (tail < head || size == 0) {
+                System.arraycopy(elements, tail, newElements, 0, size);
+            } else {
+                System.arraycopy(elements, tail, newElements, 0, elements.length - tail);
+                System.arraycopy(elements, 0, newElements, elements.length - tail, head);
+            }
+
+            elements = newElements;
+            tail = 0;
+            head = size;
+            this.capacity = newCapacity;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/Huffman.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,676 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.ByteBuffer;
+
+import static java.lang.String.format;
+
+/**
+ * Huffman coding table.
+ *
+ * <p> Instances of this class are safe for use by multiple threads.
+ *
+ * @since 9
+ */
+public final class Huffman {
+
+    // TODO: check if reset is done in both reader and writer
+
+    static final class Reader {
+
+        private Node curr; // position in the trie
+        private int len;   // length of the path from the root to 'curr'
+        private int p;     // byte probe
+
+        {
+            reset();
+        }
+
+        public void read(ByteBuffer source, Appendable destination,
+                         boolean isLast) {
+            read(source, destination, true, isLast);
+        }
+
+        // Takes 'isLast' rather than returns whether the reading is done or
+        // not, for more informative exceptions.
+        void read(ByteBuffer source, Appendable destination, boolean reportEOS,
+                  boolean isLast) {
+
+            Node c = curr;
+            int l = len;
+            /*
+               Since ByteBuffer is itself stateful, its position is
+               remembered here NOT as a part of Reader's state,
+               but to set it back in the case of a failure
+             */
+            int pos = source.position();
+
+            while (source.hasRemaining()) {
+                int d = source.get();
+                for (; p != 0; p >>= 1) {
+                    c = c.getChild(p & d);
+                    l++;
+                    if (c.isLeaf()) {
+                        if (reportEOS && c.isEOSPath) {
+                            throw new IllegalArgumentException("Encountered EOS");
+                        }
+                        try {
+                            destination.append(c.getChar());
+                        } catch (RuntimeException | Error e) {
+                            source.position(pos);
+                            throw e;
+                        } catch (IOException e) {
+                            source.position(pos);
+                            throw new UncheckedIOException(e);
+                        }
+                        c = INSTANCE.root;
+                        l = 0;
+                    }
+                    curr = c;
+                    len = l;
+                }
+                resetProbe();
+                pos++;
+            }
+            if (!isLast) {
+                return; // it's too early to jump to any conclusions, let's wait
+            }
+            if (c.isLeaf()) {
+                return; // it's perfectly ok, no extra padding bits
+            }
+            if (c.isEOSPath && len <= 7) {
+                return; // it's ok, some extra padding bits
+            }
+            if (c.isEOSPath) {
+                throw new IllegalArgumentException(
+                        "Padding is too long (len=" + len + ") " +
+                                "or unexpected end of data");
+            }
+            throw new IllegalArgumentException(
+                    "Not a EOS prefix padding or unexpected end of data");
+        }
+
+        public void reset() {
+            curr = INSTANCE.root;
+            len = 0;
+            resetProbe();
+        }
+
+        private void resetProbe() {
+            p = 0x80;
+        }
+    }
+
+    static final class Writer {
+
+        private int pos;       // position in 'source'
+        private int avail = 8; // number of least significant bits available in 'curr'
+        private int curr;      // next byte to put to the destination
+        private int rem;       // number of least significant bits in 'code' yet to be processed
+        private int code;      // current code being written
+
+        private CharSequence source;
+        private int end;
+
+        public Writer from(CharSequence input, int start, int end) {
+            if (start < 0 || end < 0 || end > input.length() || start > end) {
+                throw new IndexOutOfBoundsException(
+                        String.format("input.length()=%s, start=%s, end=%s",
+                                input.length(), start, end));
+            }
+            pos = start;
+            this.end = end;
+            this.source = input;
+            return this;
+        }
+
+        public boolean write(ByteBuffer destination) {
+            for (; pos < end; pos++) {
+                if (rem == 0) {
+                    Code desc = INSTANCE.codeOf(source.charAt(pos));
+                    rem = desc.length;
+                    code = desc.code;
+                }
+                while (rem > 0) {
+                    if (rem < avail) {
+                        curr |= (code << (avail - rem));
+                        avail -= rem;
+                        rem = 0;
+                    } else {
+                        int c = (curr | (code >>> (rem - avail)));
+                        if (destination.hasRemaining()) {
+                            destination.put((byte) c);
+                        } else {
+                            return false;
+                        }
+                        curr = c;
+                        code <<= (32 - rem + avail);  // throw written bits off the cliff (is this Sparta?)
+                        code >>>= (32 - rem + avail); // return to the position
+                        rem -= avail;
+                        curr = 0;
+                        avail = 8;
+                    }
+                }
+            }
+
+            if (avail < 8) { // have to pad
+                if (destination.hasRemaining()) {
+                    destination.put((byte) (curr | (INSTANCE.EOS.code >>> (INSTANCE.EOS.length - avail))));
+                    avail = 8;
+                } else {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        public Writer reset() {
+            source = null;
+            end = -1;
+            pos = -1;
+            avail = 8;
+            curr = 0;
+            code = 0;
+            return this;
+        }
+    }
+
+    /**
+     * Shared instance.
+     */
+    public static final Huffman INSTANCE = new Huffman();
+
+    private final Code EOS = new Code(0x3fffffff, 30);
+    private final Code[] codes = new Code[257];
+    private final Node root = new Node() {
+        @Override
+        public String toString() { return "root"; }
+    };
+
+    // TODO: consider builder and immutable trie
+    private Huffman() {
+        // @formatter:off
+        addChar(0,   0x1ff8,     13);
+        addChar(1,   0x7fffd8,   23);
+        addChar(2,   0xfffffe2,  28);
+        addChar(3,   0xfffffe3,  28);
+        addChar(4,   0xfffffe4,  28);
+        addChar(5,   0xfffffe5,  28);
+        addChar(6,   0xfffffe6,  28);
+        addChar(7,   0xfffffe7,  28);
+        addChar(8,   0xfffffe8,  28);
+        addChar(9,   0xffffea,   24);
+        addChar(10,  0x3ffffffc, 30);
+        addChar(11,  0xfffffe9,  28);
+        addChar(12,  0xfffffea,  28);
+        addChar(13,  0x3ffffffd, 30);
+        addChar(14,  0xfffffeb,  28);
+        addChar(15,  0xfffffec,  28);
+        addChar(16,  0xfffffed,  28);
+        addChar(17,  0xfffffee,  28);
+        addChar(18,  0xfffffef,  28);
+        addChar(19,  0xffffff0,  28);
+        addChar(20,  0xffffff1,  28);
+        addChar(21,  0xffffff2,  28);
+        addChar(22,  0x3ffffffe, 30);
+        addChar(23,  0xffffff3,  28);
+        addChar(24,  0xffffff4,  28);
+        addChar(25,  0xffffff5,  28);
+        addChar(26,  0xffffff6,  28);
+        addChar(27,  0xffffff7,  28);
+        addChar(28,  0xffffff8,  28);
+        addChar(29,  0xffffff9,  28);
+        addChar(30,  0xffffffa,  28);
+        addChar(31,  0xffffffb,  28);
+        addChar(32,  0x14,        6);
+        addChar(33,  0x3f8,      10);
+        addChar(34,  0x3f9,      10);
+        addChar(35,  0xffa,      12);
+        addChar(36,  0x1ff9,     13);
+        addChar(37,  0x15,        6);
+        addChar(38,  0xf8,        8);
+        addChar(39,  0x7fa,      11);
+        addChar(40,  0x3fa,      10);
+        addChar(41,  0x3fb,      10);
+        addChar(42,  0xf9,        8);
+        addChar(43,  0x7fb,      11);
+        addChar(44,  0xfa,        8);
+        addChar(45,  0x16,        6);
+        addChar(46,  0x17,        6);
+        addChar(47,  0x18,        6);
+        addChar(48,  0x0,         5);
+        addChar(49,  0x1,         5);
+        addChar(50,  0x2,         5);
+        addChar(51,  0x19,        6);
+        addChar(52,  0x1a,        6);
+        addChar(53,  0x1b,        6);
+        addChar(54,  0x1c,        6);
+        addChar(55,  0x1d,        6);
+        addChar(56,  0x1e,        6);
+        addChar(57,  0x1f,        6);
+        addChar(58,  0x5c,        7);
+        addChar(59,  0xfb,        8);
+        addChar(60,  0x7ffc,     15);
+        addChar(61,  0x20,        6);
+        addChar(62,  0xffb,      12);
+        addChar(63,  0x3fc,      10);
+        addChar(64,  0x1ffa,     13);
+        addChar(65,  0x21,        6);
+        addChar(66,  0x5d,        7);
+        addChar(67,  0x5e,        7);
+        addChar(68,  0x5f,        7);
+        addChar(69,  0x60,        7);
+        addChar(70,  0x61,        7);
+        addChar(71,  0x62,        7);
+        addChar(72,  0x63,        7);
+        addChar(73,  0x64,        7);
+        addChar(74,  0x65,        7);
+        addChar(75,  0x66,        7);
+        addChar(76,  0x67,        7);
+        addChar(77,  0x68,        7);
+        addChar(78,  0x69,        7);
+        addChar(79,  0x6a,        7);
+        addChar(80,  0x6b,        7);
+        addChar(81,  0x6c,        7);
+        addChar(82,  0x6d,        7);
+        addChar(83,  0x6e,        7);
+        addChar(84,  0x6f,        7);
+        addChar(85,  0x70,        7);
+        addChar(86,  0x71,        7);
+        addChar(87,  0x72,        7);
+        addChar(88,  0xfc,        8);
+        addChar(89,  0x73,        7);
+        addChar(90,  0xfd,        8);
+        addChar(91,  0x1ffb,     13);
+        addChar(92,  0x7fff0,    19);
+        addChar(93,  0x1ffc,     13);
+        addChar(94,  0x3ffc,     14);
+        addChar(95,  0x22,        6);
+        addChar(96,  0x7ffd,     15);
+        addChar(97,  0x3,         5);
+        addChar(98,  0x23,        6);
+        addChar(99,  0x4,         5);
+        addChar(100, 0x24,        6);
+        addChar(101, 0x5,         5);
+        addChar(102, 0x25,        6);
+        addChar(103, 0x26,        6);
+        addChar(104, 0x27,        6);
+        addChar(105, 0x6,         5);
+        addChar(106, 0x74,        7);
+        addChar(107, 0x75,        7);
+        addChar(108, 0x28,        6);
+        addChar(109, 0x29,        6);
+        addChar(110, 0x2a,        6);
+        addChar(111, 0x7,         5);
+        addChar(112, 0x2b,        6);
+        addChar(113, 0x76,        7);
+        addChar(114, 0x2c,        6);
+        addChar(115, 0x8,         5);
+        addChar(116, 0x9,         5);
+        addChar(117, 0x2d,        6);
+        addChar(118, 0x77,        7);
+        addChar(119, 0x78,        7);
+        addChar(120, 0x79,        7);
+        addChar(121, 0x7a,        7);
+        addChar(122, 0x7b,        7);
+        addChar(123, 0x7ffe,     15);
+        addChar(124, 0x7fc,      11);
+        addChar(125, 0x3ffd,     14);
+        addChar(126, 0x1ffd,     13);
+        addChar(127, 0xffffffc,  28);
+        addChar(128, 0xfffe6,    20);
+        addChar(129, 0x3fffd2,   22);
+        addChar(130, 0xfffe7,    20);
+        addChar(131, 0xfffe8,    20);
+        addChar(132, 0x3fffd3,   22);
+        addChar(133, 0x3fffd4,   22);
+        addChar(134, 0x3fffd5,   22);
+        addChar(135, 0x7fffd9,   23);
+        addChar(136, 0x3fffd6,   22);
+        addChar(137, 0x7fffda,   23);
+        addChar(138, 0x7fffdb,   23);
+        addChar(139, 0x7fffdc,   23);
+        addChar(140, 0x7fffdd,   23);
+        addChar(141, 0x7fffde,   23);
+        addChar(142, 0xffffeb,   24);
+        addChar(143, 0x7fffdf,   23);
+        addChar(144, 0xffffec,   24);
+        addChar(145, 0xffffed,   24);
+        addChar(146, 0x3fffd7,   22);
+        addChar(147, 0x7fffe0,   23);
+        addChar(148, 0xffffee,   24);
+        addChar(149, 0x7fffe1,   23);
+        addChar(150, 0x7fffe2,   23);
+        addChar(151, 0x7fffe3,   23);
+        addChar(152, 0x7fffe4,   23);
+        addChar(153, 0x1fffdc,   21);
+        addChar(154, 0x3fffd8,   22);
+        addChar(155, 0x7fffe5,   23);
+        addChar(156, 0x3fffd9,   22);
+        addChar(157, 0x7fffe6,   23);
+        addChar(158, 0x7fffe7,   23);
+        addChar(159, 0xffffef,   24);
+        addChar(160, 0x3fffda,   22);
+        addChar(161, 0x1fffdd,   21);
+        addChar(162, 0xfffe9,    20);
+        addChar(163, 0x3fffdb,   22);
+        addChar(164, 0x3fffdc,   22);
+        addChar(165, 0x7fffe8,   23);
+        addChar(166, 0x7fffe9,   23);
+        addChar(167, 0x1fffde,   21);
+        addChar(168, 0x7fffea,   23);
+        addChar(169, 0x3fffdd,   22);
+        addChar(170, 0x3fffde,   22);
+        addChar(171, 0xfffff0,   24);
+        addChar(172, 0x1fffdf,   21);
+        addChar(173, 0x3fffdf,   22);
+        addChar(174, 0x7fffeb,   23);
+        addChar(175, 0x7fffec,   23);
+        addChar(176, 0x1fffe0,   21);
+        addChar(177, 0x1fffe1,   21);
+        addChar(178, 0x3fffe0,   22);
+        addChar(179, 0x1fffe2,   21);
+        addChar(180, 0x7fffed,   23);
+        addChar(181, 0x3fffe1,   22);
+        addChar(182, 0x7fffee,   23);
+        addChar(183, 0x7fffef,   23);
+        addChar(184, 0xfffea,    20);
+        addChar(185, 0x3fffe2,   22);
+        addChar(186, 0x3fffe3,   22);
+        addChar(187, 0x3fffe4,   22);
+        addChar(188, 0x7ffff0,   23);
+        addChar(189, 0x3fffe5,   22);
+        addChar(190, 0x3fffe6,   22);
+        addChar(191, 0x7ffff1,   23);
+        addChar(192, 0x3ffffe0,  26);
+        addChar(193, 0x3ffffe1,  26);
+        addChar(194, 0xfffeb,    20);
+        addChar(195, 0x7fff1,    19);
+        addChar(196, 0x3fffe7,   22);
+        addChar(197, 0x7ffff2,   23);
+        addChar(198, 0x3fffe8,   22);
+        addChar(199, 0x1ffffec,  25);
+        addChar(200, 0x3ffffe2,  26);
+        addChar(201, 0x3ffffe3,  26);
+        addChar(202, 0x3ffffe4,  26);
+        addChar(203, 0x7ffffde,  27);
+        addChar(204, 0x7ffffdf,  27);
+        addChar(205, 0x3ffffe5,  26);
+        addChar(206, 0xfffff1,   24);
+        addChar(207, 0x1ffffed,  25);
+        addChar(208, 0x7fff2,    19);
+        addChar(209, 0x1fffe3,   21);
+        addChar(210, 0x3ffffe6,  26);
+        addChar(211, 0x7ffffe0,  27);
+        addChar(212, 0x7ffffe1,  27);
+        addChar(213, 0x3ffffe7,  26);
+        addChar(214, 0x7ffffe2,  27);
+        addChar(215, 0xfffff2,   24);
+        addChar(216, 0x1fffe4,   21);
+        addChar(217, 0x1fffe5,   21);
+        addChar(218, 0x3ffffe8,  26);
+        addChar(219, 0x3ffffe9,  26);
+        addChar(220, 0xffffffd,  28);
+        addChar(221, 0x7ffffe3,  27);
+        addChar(222, 0x7ffffe4,  27);
+        addChar(223, 0x7ffffe5,  27);
+        addChar(224, 0xfffec,    20);
+        addChar(225, 0xfffff3,   24);
+        addChar(226, 0xfffed,    20);
+        addChar(227, 0x1fffe6,   21);
+        addChar(228, 0x3fffe9,   22);
+        addChar(229, 0x1fffe7,   21);
+        addChar(230, 0x1fffe8,   21);
+        addChar(231, 0x7ffff3,   23);
+        addChar(232, 0x3fffea,   22);
+        addChar(233, 0x3fffeb,   22);
+        addChar(234, 0x1ffffee,  25);
+        addChar(235, 0x1ffffef,  25);
+        addChar(236, 0xfffff4,   24);
+        addChar(237, 0xfffff5,   24);
+        addChar(238, 0x3ffffea,  26);
+        addChar(239, 0x7ffff4,   23);
+        addChar(240, 0x3ffffeb,  26);
+        addChar(241, 0x7ffffe6,  27);
+        addChar(242, 0x3ffffec,  26);
+        addChar(243, 0x3ffffed,  26);
+        addChar(244, 0x7ffffe7,  27);
+        addChar(245, 0x7ffffe8,  27);
+        addChar(246, 0x7ffffe9,  27);
+        addChar(247, 0x7ffffea,  27);
+        addChar(248, 0x7ffffeb,  27);
+        addChar(249, 0xffffffe,  28);
+        addChar(250, 0x7ffffec,  27);
+        addChar(251, 0x7ffffed,  27);
+        addChar(252, 0x7ffffee,  27);
+        addChar(253, 0x7ffffef,  27);
+        addChar(254, 0x7fffff0,  27);
+        addChar(255, 0x3ffffee,  26);
+        addEOS (256, EOS.code,   EOS.length);
+        // @formatter:on
+    }
+
+
+    /**
+     * Calculates the number of bytes required to represent the given {@code
+     * CharSequence} with the Huffman coding.
+     *
+     * @param value
+     *         characters
+     *
+     * @return number of bytes
+     *
+     * @throws NullPointerException
+     *         if the value is null
+     */
+    public int lengthOf(CharSequence value) {
+        return lengthOf(value, 0, value.length());
+    }
+
+    /**
+     * Calculates the number of bytes required to represent a subsequence of the
+     * given {@code CharSequence} with the Huffman coding.
+     *
+     * @param value
+     *         characters
+     * @param start
+     *         the start index, inclusive
+     * @param end
+     *         the end index, exclusive
+     *
+     * @return number of bytes
+     *
+     * @throws NullPointerException
+     *         if the value is null
+     * @throws IndexOutOfBoundsException
+     *         if any invocation of {@code value.charAt(i)}, where {@code start
+     *         <= i < end} would throw an IndexOutOfBoundsException
+     */
+    public int lengthOf(CharSequence value, int start, int end) {
+        int len = 0;
+        for (int i = start; i < end; i++) {
+            char c = value.charAt(i);
+            len += INSTANCE.codeOf(c).length;
+        }
+        // Integer division with ceiling, assumption:
+        assert (len / 8 + (len % 8 != 0 ? 1 : 0)) == (len + 7) / 8 : len;
+        return (len + 7) / 8;
+    }
+
+    private void addChar(int c, int code, int bitLength) {
+        addLeaf(c, code, bitLength, false);
+        codes[c] = new Code(code, bitLength);
+    }
+
+    private void addEOS(int c, int code, int bitLength) {
+        addLeaf(c, code, bitLength, true);
+        codes[c] = new Code(code, bitLength);
+    }
+
+    private void addLeaf(int c, int code, int bitLength, boolean isEOS) {
+        if (bitLength < 1) {
+            throw new IllegalArgumentException("bitLength < 1");
+        }
+        Node curr = root;
+        for (int p = 1 << bitLength - 1; p != 0 && !curr.isLeaf(); p = p >> 1) {
+            curr.isEOSPath |= isEOS; // If it's already true, it can't become false
+            curr = curr.addChildIfAbsent(p & code);
+        }
+        curr.isEOSPath |= isEOS; // The last one needs to have this property as well
+        if (curr.isLeaf()) {
+            throw new IllegalStateException("Specified code is already taken");
+        }
+        curr.setChar((char) c);
+    }
+
+    private Code codeOf(char c) {
+        if (c > 255) {
+            throw new IllegalArgumentException("char=" + ((int) c));
+        }
+        return codes[c];
+    }
+
+    //
+    // For debugging/testing purposes
+    //
+    Node getRoot() {
+        return root;
+    }
+
+    //
+    // Guarantees:
+    //
+    //  if (isLeaf() == true) => getChar() is a legal call
+    //  if (isLeaf() == false) => getChild(i) is a legal call (though it can
+    //                                                           return null)
+    //
+    static class Node {
+
+        Node left;
+        Node right;
+        boolean isEOSPath;
+
+        boolean charIsSet;
+        char c;
+
+        Node getChild(int selector) {
+            if (isLeaf()) {
+                throw new IllegalStateException("This is a leaf node");
+            }
+            Node result = selector == 0 ? left : right;
+            if (result == null) {
+                throw new IllegalStateException(format(
+                        "Node doesn't have a child (selector=%s)", selector));
+            }
+            return result;
+        }
+
+        boolean isLeaf() {
+            return charIsSet;
+        }
+
+        char getChar() {
+            if (!isLeaf()) {
+                throw new IllegalStateException("This node is not a leaf node");
+            }
+            return c;
+        }
+
+        void setChar(char c) {
+            if (charIsSet) {
+                throw new IllegalStateException(
+                        "This node has been taken already");
+            }
+            if (left != null || right != null) {
+                throw new IllegalStateException("The node cannot be made "
+                        + "a leaf as it's already has a child");
+            }
+            this.c = c;
+            charIsSet = true;
+        }
+
+        Node addChildIfAbsent(int i) {
+            if (charIsSet) {
+                throw new IllegalStateException("The node cannot have a child "
+                        + "as it's already a leaf node");
+            }
+            Node child;
+            if (i == 0) {
+                if ((child = left) == null) {
+                    child = left = new Node();
+                }
+            } else {
+                if ((child = right) == null) {
+                    child = right = new Node();
+                }
+            }
+            return child;
+        }
+
+        @Override
+        public String toString() {
+            if (isLeaf()) {
+                if (isEOSPath) {
+                    return "EOS";
+                } else {
+                    return format("char: (%3s) '%s'", (int) c, c);
+                }
+            }
+            return "/\\";
+        }
+    }
+
+    // TODO: value-based class?
+    // FIXME: can we re-use Node instead of this class?
+    private static final class Code {
+
+        final int code;
+        final int length;
+
+        private Code(int code, int length) {
+            this.code = code;
+            this.length = length;
+        }
+
+        public int getCode() {
+            return code;
+        }
+
+        public int getLength() {
+            return length;
+        }
+
+        @Override
+        public String toString() {
+            long p = 1 << length;
+            return Long.toBinaryString(code + p).substring(1)
+                    + ", length=" + length;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/ISO_8859_1.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.ByteBuffer;
+
+//
+// Custom implementation of ISO/IEC 8859-1:1998
+//
+// The rationale behind this is not to deal with CharsetEncoder/CharsetDecoder,
+// basically because it would require wrapping every single CharSequence into a
+// CharBuffer and then copying it back.
+//
+// But why not to give a CharBuffer instead of Appendable? Because I can choose
+// an Appendable (e.g. StringBuilder) that adjusts its length when needed and
+// therefore not to deal with pre-sized CharBuffers or copying.
+//
+// The encoding is simple and well known: 1 byte <-> 1 char
+//
+final class ISO_8859_1 {
+
+    private ISO_8859_1() { }
+
+    public static final class Reader {
+
+        public void read(ByteBuffer source, Appendable destination) {
+            for (int i = 0, len = source.remaining(); i < len; i++) {
+                char c = (char) (source.get() & 0xff);
+                try {
+                    destination.append(c);
+                } catch (IOException e) {
+                    throw new UncheckedIOException
+                            ("Error appending to the destination", e);
+                }
+            }
+        }
+
+        public Reader reset() {
+            return this;
+        }
+    }
+
+    public static final class Writer {
+
+        private CharSequence source;
+        private int pos;
+        private int end;
+
+        public Writer configure(CharSequence source, int start, int end) {
+            this.source = source;
+            this.pos = start;
+            this.end = end;
+            return this;
+        }
+
+        public boolean write(ByteBuffer destination) {
+            for (; pos < end; pos++) {
+                char c = source.charAt(pos);
+                if (c > '\u00FF') {
+                    throw new IllegalArgumentException(
+                            "Illegal ISO-8859-1 char: " + (int) c);
+                }
+                if (destination.hasRemaining()) {
+                    destination.put((byte) c);
+                } else {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        public Writer reset() {
+            source = null;
+            pos = -1;
+            end = -1;
+            return this;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/IndexNameValueWriter.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+
+abstract class IndexNameValueWriter implements BinaryRepresentationWriter {
+
+    private final int pattern;
+    private final int prefix;
+    private final IntegerWriter intWriter = new IntegerWriter();
+    private final StringWriter nameWriter = new StringWriter();
+    private final StringWriter valueWriter = new StringWriter();
+
+    protected boolean indexedRepresentation;
+
+    private static final int NEW               = 0;
+    private static final int NAME_PART_WRITTEN = 1;
+    private static final int VALUE_WRITTEN     = 2;
+
+    private int state = NEW;
+
+    protected IndexNameValueWriter(int pattern, int prefix) {
+        this.pattern = pattern;
+        this.prefix = prefix;
+    }
+
+    IndexNameValueWriter index(int index) {
+        indexedRepresentation = true;
+        intWriter.configure(index, prefix, pattern);
+        return this;
+    }
+
+    IndexNameValueWriter name(CharSequence name, boolean useHuffman) {
+        indexedRepresentation = false;
+        intWriter.configure(0, prefix, pattern);
+        nameWriter.configure(name, useHuffman);
+        return this;
+    }
+
+    IndexNameValueWriter value(CharSequence value, boolean useHuffman) {
+        valueWriter.configure(value, useHuffman);
+        return this;
+    }
+
+    @Override
+    public boolean write(HeaderTable table, ByteBuffer destination) {
+        if (state < NAME_PART_WRITTEN) {
+            if (indexedRepresentation) {
+                if (!intWriter.write(destination)) {
+                    return false;
+                }
+            } else {
+                if (!intWriter.write(destination) || !nameWriter.write(destination)) {
+                    return false;
+                }
+            }
+            state = NAME_PART_WRITTEN;
+        }
+        if (state < VALUE_WRITTEN) {
+            if (!valueWriter.write(destination)) {
+                return false;
+            }
+            state = VALUE_WRITTEN;
+        }
+        return state == VALUE_WRITTEN;
+    }
+
+    @Override
+    public IndexNameValueWriter reset() {
+        intWriter.reset();
+        if (!indexedRepresentation) {
+            nameWriter.reset();
+        }
+        valueWriter.reset();
+        state = NEW;
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/IndexedWriter.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+
+final class IndexedWriter implements BinaryRepresentationWriter {
+
+    private final IntegerWriter intWriter = new IntegerWriter();
+
+    IndexedWriter() { }
+
+    IndexedWriter index(int index) {
+        intWriter.configure(index, 7, 0b1000_0000);
+        return this;
+    }
+
+    @Override
+    public boolean write(HeaderTable table, ByteBuffer destination) {
+        return intWriter.write(destination);
+    }
+
+    @Override
+    public BinaryRepresentationWriter reset() {
+        intWriter.reset();
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/IntegerReader.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+import static java.lang.String.format;
+
+final class IntegerReader {
+
+    private static final int NEW             = 0;
+    private static final int CONFIGURED      = 1;
+    private static final int FIRST_BYTE_READ = 2;
+    private static final int DONE            = 4;
+
+    private int state = NEW;
+
+    private int N;
+    private int maxValue;
+    private int value;
+    private long r;
+    private long b = 1;
+
+    public IntegerReader configure(int N) {
+        return configure(N, Integer.MAX_VALUE);
+    }
+
+    //
+    // Why is it important to configure 'maxValue' here. After all we can wait
+    // for the integer to be fully read and then check it. Can't we?
+    //
+    // Two reasons.
+    //
+    // 1. Value wraps around long won't be unnoticed.
+    // 2. It can spit out an exception as soon as it becomes clear there's
+    // an overflow. Therefore, no need to wait for the value to be fully read.
+    //
+    public IntegerReader configure(int N, int maxValue) {
+        if (state != NEW) {
+            throw new IllegalStateException("Already configured");
+        }
+        checkPrefix(N);
+        if (maxValue < 0) {
+            throw new IllegalArgumentException(
+                    "maxValue >= 0: maxValue=" + maxValue);
+        }
+        this.maxValue = maxValue;
+        this.N = N;
+        state = CONFIGURED;
+        return this;
+    }
+
+    public boolean read(ByteBuffer input) {
+        if (state == NEW) {
+            throw new IllegalStateException("Configure first");
+        }
+        if (state == DONE) {
+            return true;
+        }
+        if (!input.hasRemaining()) {
+            return false;
+        }
+        if (state == CONFIGURED) {
+            int max = (2 << (N - 1)) - 1;
+            int n = input.get() & max;
+            if (n != max) {
+                value = n;
+                state = DONE;
+                return true;
+            } else {
+                r = max;
+            }
+            state = FIRST_BYTE_READ;
+        }
+        if (state == FIRST_BYTE_READ) {
+            // variable-length quantity (VLQ)
+            byte i;
+            do {
+                if (!input.hasRemaining()) {
+                    return false;
+                }
+                i = input.get();
+                long increment = b * (i & 127);
+                if (r + increment > maxValue) {
+                    throw new IllegalArgumentException(format(
+                            "Integer overflow: maxValue=%,d, value=%,d",
+                            maxValue, r + increment));
+                }
+                r += increment;
+                b *= 128;
+            } while ((128 & i) == 128);
+
+            value = (int) r;
+            state = DONE;
+            return true;
+        }
+        throw new InternalError(Arrays.toString(
+                new Object[]{state, N, maxValue, value, r, b}));
+    }
+
+    public int get() throws IllegalStateException {
+        if (state != DONE) {
+            throw new IllegalStateException("Has not been fully read yet");
+        }
+        return value;
+    }
+
+    private static void checkPrefix(int N) {
+        if (N < 1 || N > 8) {
+            throw new IllegalArgumentException("1 <= N <= 8: N= " + N);
+        }
+    }
+
+    public IntegerReader reset() {
+        b = 1;
+        state = NEW;
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/IntegerWriter.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+final class IntegerWriter {
+
+    private static final int NEW                = 0;
+    private static final int CONFIGURED         = 1;
+    private static final int FIRST_BYTE_WRITTEN = 2;
+    private static final int DONE               = 4;
+
+    private int state = NEW;
+
+    private int payload;
+    private int N;
+    private int value;
+
+    //
+    //      0   1   2   3   4   5   6   7
+    //    +---+---+---+---+---+---+---+---+
+    //    |   |   |   |   |   |   |   |   |
+    //    +---+---+---+-------------------+
+    //    |<--------->|<----------------->|
+    //       payload           N=5
+    //
+    // payload is the contents of the left-hand side part of the octet;
+    //         it is truncated to fit into 8-N bits, where 1 <= N <= 8;
+    //
+    public IntegerWriter configure(int value, int N, int payload) {
+        if (state != NEW) {
+            throw new IllegalStateException("Already configured");
+        }
+        if (value < 0) {
+            throw new IllegalArgumentException("value >= 0: value=" + value);
+        }
+        checkPrefix(N);
+        this.value = value;
+        this.N = N;
+        this.payload = payload & 0xFF & (0xFFFFFFFF << N);
+        state = CONFIGURED;
+        return this;
+    }
+
+    public boolean write(ByteBuffer output) {
+        if (state == NEW) {
+            throw new IllegalStateException("Configure first");
+        }
+        if (state == DONE) {
+            return true;
+        }
+
+        if (!output.hasRemaining()) {
+            return false;
+        }
+        if (state == CONFIGURED) {
+            int max = (2 << (N - 1)) - 1;
+            if (value < max) {
+                output.put((byte) (payload | value));
+                state = DONE;
+                return true;
+            }
+            output.put((byte) (payload | max));
+            value -= max;
+            state = FIRST_BYTE_WRITTEN;
+        }
+        if (state == FIRST_BYTE_WRITTEN) {
+            while (value >= 128 && output.hasRemaining()) {
+                output.put((byte) (value % 128 + 128));
+                value /= 128;
+            }
+            if (!output.hasRemaining()) {
+                return false;
+            }
+            output.put((byte) value);
+            state = DONE;
+            return true;
+        }
+        throw new InternalError(Arrays.toString(
+                new Object[]{state, payload, N, value}));
+    }
+
+    private static void checkPrefix(int N) {
+        if (N < 1 || N > 8) {
+            throw new IllegalArgumentException("1 <= N <= 8: N= " + N);
+        }
+    }
+
+    public IntegerWriter reset() {
+        state = NEW;
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/LiteralNeverIndexedWriter.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+final class LiteralNeverIndexedWriter extends IndexNameValueWriter {
+
+    LiteralNeverIndexedWriter() {
+        super(0b0001_0000, 4);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/LiteralWithIndexingWriter.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+
+final class LiteralWithIndexingWriter extends IndexNameValueWriter {
+
+    private boolean tableUpdated;
+
+    private CharSequence name;
+    private CharSequence value;
+    private int index;
+
+    LiteralWithIndexingWriter() {
+        super(0b0100_0000, 6);
+    }
+
+    @Override
+    LiteralWithIndexingWriter index(int index) {
+        super.index(index);
+        this.index = index;
+        return this;
+    }
+
+    @Override
+    LiteralWithIndexingWriter name(CharSequence name, boolean useHuffman) {
+        super.name(name, useHuffman);
+        this.name = name;
+        return this;
+    }
+
+    @Override
+    LiteralWithIndexingWriter value(CharSequence value, boolean useHuffman) {
+        super.value(value, useHuffman);
+        this.value = value;
+        return this;
+    }
+
+    @Override
+    public boolean write(HeaderTable table, ByteBuffer destination) {
+        if (!tableUpdated) {
+            CharSequence n;
+            if (indexedRepresentation) {
+                n = table.get(index).name;
+            } else {
+                n = name;
+            }
+            table.put(n, value);
+            tableUpdated = true;
+        }
+        return super.write(table, destination);
+    }
+
+    @Override
+    public IndexNameValueWriter reset() {
+        tableUpdated = false;
+        name = null;
+        value = null;
+        index = -1;
+        return super.reset();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/LiteralWriter.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+final class LiteralWriter extends IndexNameValueWriter {
+
+    LiteralWriter() {
+        super(0b0000_0000, 4);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/SizeUpdateWriter.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+
+final class SizeUpdateWriter implements BinaryRepresentationWriter {
+
+    private final IntegerWriter intWriter = new IntegerWriter();
+    private int maxSize;
+    private boolean tableUpdated;
+
+    SizeUpdateWriter() { }
+
+    SizeUpdateWriter maxHeaderTableSize(int size) {
+        intWriter.configure(size, 5, 0b0010_0000);
+        this.maxSize = size;
+        return this;
+    }
+
+    @Override
+    public boolean write(HeaderTable table, ByteBuffer destination) {
+        if (!tableUpdated) {
+            table.setMaxSize(maxSize);
+            tableUpdated = true;
+        }
+        return intWriter.write(destination);
+    }
+
+    @Override
+    public BinaryRepresentationWriter reset() {
+        intWriter.reset();
+        maxSize = -1;
+        tableUpdated = false;
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/StringReader.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+//
+//          0   1   2   3   4   5   6   7
+//        +---+---+---+---+---+---+---+---+
+//        | H |    String Length (7+)     |
+//        +---+---------------------------+
+//        |  String Data (Length octets)  |
+//        +-------------------------------+
+//
+final class StringReader {
+
+    private static final int NEW             = 0;
+    private static final int FIRST_BYTE_READ = 1;
+    private static final int LENGTH_READ     = 2;
+    private static final int DONE            = 4;
+
+    private final IntegerReader intReader = new IntegerReader();
+    private final Huffman.Reader huffmanReader = new Huffman.Reader();
+    private final ISO_8859_1.Reader plainReader = new ISO_8859_1.Reader();
+
+    private int state = NEW;
+
+    private boolean huffman;
+    private int remainingLength;
+
+    boolean read(ByteBuffer input, Appendable output) {
+        if (state == DONE) {
+            return true;
+        }
+        if (!input.hasRemaining()) {
+            return false;
+        }
+        if (state == NEW) {
+            int p = input.position();
+            huffman = (input.get(p) & 0b10000000) != 0;
+            state = FIRST_BYTE_READ;
+            intReader.configure(7);
+        }
+        if (state == FIRST_BYTE_READ) {
+            boolean lengthRead = intReader.read(input);
+            if (!lengthRead) {
+                return false;
+            }
+            remainingLength = intReader.get();
+            state = LENGTH_READ;
+        }
+        if (state == LENGTH_READ) {
+            boolean isLast = input.remaining() >= remainingLength;
+            int oldLimit = input.limit();
+            if (isLast) {
+                input.limit(input.position() + remainingLength);
+            }
+            if (huffman) {
+                huffmanReader.read(input, output, isLast);
+            } else {
+                plainReader.read(input, output);
+            }
+            if (isLast) {
+                input.limit(oldLimit);
+            }
+            return isLast;
+        }
+        throw new InternalError(Arrays.toString(
+                new Object[]{state, huffman, remainingLength}));
+    }
+
+    boolean isHuffmanEncoded() {
+        if (state < FIRST_BYTE_READ) {
+            throw new IllegalStateException("Has not been fully read yet");
+        }
+        return huffman;
+    }
+
+    void reset() {
+        if (huffman) {
+            huffmanReader.reset();
+        } else {
+            plainReader.reset();
+        }
+        intReader.reset();
+        state = NEW;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/StringWriter.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+//
+//          0   1   2   3   4   5   6   7
+//        +---+---+---+---+---+---+---+---+
+//        | H |    String Length (7+)     |
+//        +---+---------------------------+
+//        |  String Data (Length octets)  |
+//        +-------------------------------+
+//
+// StringWriter does not require a notion of endOfInput (isLast) in 'write'
+// methods due to the nature of string representation in HPACK. Namely, the
+// length of the string is put before string's contents. Therefore the length is
+// always known beforehand.
+//
+// Expected use:
+//
+//     configure write* (reset configure write*)*
+//
+final class StringWriter {
+
+    private static final int NEW            = 0;
+    private static final int CONFIGURED     = 1;
+    private static final int LENGTH_WRITTEN = 2;
+    private static final int DONE           = 4;
+
+    private final IntegerWriter intWriter = new IntegerWriter();
+    private final Huffman.Writer huffmanWriter = new Huffman.Writer();
+    private final ISO_8859_1.Writer plainWriter = new ISO_8859_1.Writer();
+
+    private int state = NEW;
+    private boolean huffman;
+
+    StringWriter configure(CharSequence input, boolean huffman) {
+        return configure(input, 0, input.length(), huffman);
+    }
+
+    StringWriter configure(CharSequence input, int start, int end,
+                           boolean huffman) {
+        if (start < 0 || end < 0 || end > input.length() || start > end) {
+            throw new IndexOutOfBoundsException(
+                    String.format("input.length()=%s, start=%s, end=%s",
+                            input.length(), start, end));
+        }
+        if (!huffman) {
+            plainWriter.configure(input, start, end);
+            intWriter.configure(end - start, 7, 0b0000_0000);
+        } else {
+            huffmanWriter.from(input, start, end);
+            intWriter.configure(Huffman.INSTANCE.lengthOf(input, start, end),
+                    7, 0b1000_0000);
+        }
+
+        this.huffman = huffman;
+        state = CONFIGURED;
+        return this;
+    }
+
+    boolean write(ByteBuffer output) {
+        if (state == DONE) {
+            return true;
+        }
+        if (state == NEW) {
+            throw new IllegalStateException("Configure first");
+        }
+        if (!output.hasRemaining()) {
+            return false;
+        }
+        if (state == CONFIGURED) {
+            if (intWriter.write(output)) {
+                state = LENGTH_WRITTEN;
+            } else {
+                return false;
+            }
+        }
+        if (state == LENGTH_WRITTEN) {
+            boolean written = huffman
+                    ? huffmanWriter.write(output)
+                    : plainWriter.write(output);
+            if (written) {
+                state = DONE;
+                return true;
+            } else {
+                return false;
+            }
+        }
+        throw new InternalError(Arrays.toString(new Object[]{state, huffman}));
+    }
+
+    void reset() {
+        intWriter.reset();
+        if (huffman) {
+            huffmanWriter.reset();
+        } else {
+            plainWriter.reset();
+        }
+        state = NEW;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/sun/net/httpclient/hpack/package-info.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2015, 2016, 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.
+ */
+/**
+ * HPACK (Header Compression for HTTP/2) implementation conforming to
+ * <a href="https://tools.ietf.org/html/rfc7541">RFC&nbsp;7541</a>.
+ *
+ * <p> Headers can be decoded and encoded by {@link sun.net.httpclient.hpack.Decoder}
+ * and {@link sun.net.httpclient.hpack.Encoder} respectively.
+ *
+ * <p> Instances of these classes are not safe for use by multiple threads.
+ */
+package sun.net.httpclient.hpack;
--- a/jdk/src/java.logging/share/classes/java/util/logging/LogManager.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.logging/share/classes/java/util/logging/LogManager.java	Thu Apr 28 23:08:16 2016 -0700
@@ -42,8 +42,9 @@
 import java.util.stream.Stream;
 import jdk.internal.misc.JavaAWTAccess;
 import jdk.internal.misc.SharedSecrets;
-import sun.misc.ManagedLocalsThread;
 import sun.util.logging.internal.LoggingProviderImpl;
+import java.lang.reflect.Module;
+import static jdk.internal.logger.DefaultLoggerFinder.isSystem;
 
 /**
  * There is a single global LogManager object that is used to
@@ -254,9 +255,10 @@
 
     // This private class is used as a shutdown hook.
     // It does a "reset" to close all open handlers.
-    private class Cleaner extends ManagedLocalsThread {
+    private class Cleaner extends Thread {
 
         private Cleaner() {
+            super(null, null, "Logging-Cleaner", 0, false);
             /* Set context class loader to null in order to avoid
              * keeping a strong reference to an application classloader.
              */
@@ -503,10 +505,16 @@
     // as a LogManager subclass may override the addLogger, getLogger,
     // readConfiguration, and other methods.
     Logger demandLogger(String name, String resourceBundleName, Class<?> caller) {
+        final Module module = caller == null ? null : caller.getModule();
+        return demandLogger(name, resourceBundleName, module);
+    }
+
+    Logger demandLogger(String name, String resourceBundleName, Module module) {
         Logger result = getLogger(name);
         if (result == null) {
             // only allocate the new logger once
-            Logger newLogger = new Logger(name, resourceBundleName, caller, this, false);
+            Logger newLogger = new Logger(name, resourceBundleName,
+                    module == null ? null : module, this, false);
             do {
                 if (addLogger(newLogger)) {
                     // We successfully added the new Logger that we
@@ -532,9 +540,14 @@
     }
 
     Logger demandSystemLogger(String name, String resourceBundleName, Class<?> caller) {
+        final Module module = caller == null ? null : caller.getModule();
+        return demandSystemLogger(name, resourceBundleName, module);
+    }
+
+    Logger demandSystemLogger(String name, String resourceBundleName, Module module) {
         // Add a system logger in the system context's namespace
         final Logger sysLogger = getSystemContext()
-                .demandLogger(name, resourceBundleName, caller);
+                .demandLogger(name, resourceBundleName, module);
 
         // Add the system logger to the LogManager's namespace if not exist
         // so that there is only one single logger of the given name.
@@ -619,11 +632,11 @@
             return global;
         }
 
-        Logger demandLogger(String name, String resourceBundleName, Class<?> caller) {
+        Logger demandLogger(String name, String resourceBundleName, Module module) {
             // a LogManager subclass may have its own implementation to add and
             // get a Logger.  So delegate to the LogManager to do the work.
             final LogManager owner = getOwner();
-            return owner.demandLogger(name, resourceBundleName, caller);
+            return owner.demandLogger(name, resourceBundleName, module);
         }
 
 
@@ -907,11 +920,13 @@
         // one single logger of the given name.  System loggers are visible
         // to applications unless a logger of the same name has been added.
         @Override
-        Logger demandLogger(String name, String resourceBundleName, Class<?> caller) {
+        Logger demandLogger(String name, String resourceBundleName,
+                            Module module) {
             Logger result = findLogger(name);
             if (result == null) {
                 // only allocate the new system logger once
-                Logger newLogger = new Logger(name, resourceBundleName, caller, getOwner(), true);
+                Logger newLogger = new Logger(name, resourceBundleName,
+                                              module, getOwner(), true);
                 do {
                     if (addLocalLogger(newLogger)) {
                         // We successfully added the new Logger that we
@@ -2622,18 +2637,18 @@
         }
 
         /**
-         * Demands a logger on behalf of the given {@code caller}.
+         * Demands a logger on behalf of the given {@code module}.
          * <p>
-         * If a named logger suitable for the given caller is found
+         * If a named logger suitable for the given module is found
          * returns it.
-         * Otherwise, creates a new logger suitable for the given caller.
+         * Otherwise, creates a new logger suitable for the given module.
          *
          * @param name   The logger name.
-         * @param caller The caller on which behalf the logger is created/retrieved.
-         * @return A logger for the given {@code caller}.
+         * @param module The module on which behalf the logger is created/retrieved.
+         * @return A logger for the given {@code module}.
          *
          * @throws NullPointerException if {@code name} is {@code null}
-         *         or {@code caller} is {@code null}.
+         *         or {@code module} is {@code null}.
          * @throws IllegalArgumentException if {@code manager} is not the default
          *         LogManager.
          * @throws SecurityException if a security manager is present and the
@@ -2641,7 +2656,7 @@
          *        {@link LoggingPermission LoggingPermission("demandLogger", null)}.
          */
         @Override
-        public Logger demandLoggerFor(LogManager manager, String name, /* Module */ Class<?> caller) {
+        public Logger demandLoggerFor(LogManager manager, String name, Module module) {
             if (manager != getLogManager()) {
                 // having LogManager as parameter just ensures that the
                 // caller will have initialized the LogManager before reaching
@@ -2649,15 +2664,16 @@
                 throw new IllegalArgumentException("manager");
             }
             Objects.requireNonNull(name);
+            Objects.requireNonNull(module);
             SecurityManager sm = System.getSecurityManager();
             if (sm != null) {
                 sm.checkPermission(controlPermission);
             }
-            if (caller.getClassLoader() == null) {
+            if (isSystem(module)) {
                 return manager.demandSystemLogger(name,
-                    Logger.SYSTEM_LOGGER_RB_NAME, caller);
+                    Logger.SYSTEM_LOGGER_RB_NAME, module);
             } else {
-                return manager.demandLogger(name, null, caller);
+                return manager.demandLogger(name, null, module);
             }
         }
 
--- a/jdk/src/java.logging/share/classes/java/util/logging/Logger.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.logging/share/classes/java/util/logging/Logger.java	Thu Apr 28 23:08:16 2016 -0700
@@ -40,6 +40,7 @@
 import java.util.function.Supplier;
 import jdk.internal.reflect.CallerSensitive;
 import jdk.internal.reflect.Reflection;
+import static jdk.internal.logger.DefaultLoggerFinder.isSystem;
 
 /**
  * A Logger object is used to log messages for a specific
@@ -379,7 +380,8 @@
         this(name, resourceBundleName, null, LogManager.getLogManager(), false);
     }
 
-    Logger(String name, String resourceBundleName, Class<?> caller, LogManager manager, boolean isSystemLogger) {
+    Logger(String name, String resourceBundleName, Module caller,
+           LogManager manager, boolean isSystemLogger) {
         this.manager = manager;
         this.isSystemLogger = isSystemLogger;
         setupResourceInfo(resourceBundleName, caller);
@@ -387,10 +389,7 @@
         levelValue = Level.INFO.intValue();
     }
 
-    private void setCallerModuleRef(Class<?> caller) {
-        Module callerModule = ((caller != null)
-                                        ? caller.getModule()
-                                        : null);
+    private void setCallerModuleRef(Module callerModule) {
         if (callerModule != null) {
             this.callerModuleRef = new WeakReference<>(callerModule);
         }
@@ -618,7 +617,7 @@
         // all loggers in the system context will default to
         // the system logger's resource bundle - therefore the caller won't
         // be needed and can be null.
-        Logger result = manager.demandSystemLogger(name, SYSTEM_LOGGER_RB_NAME, null);
+        Logger result = manager.demandSystemLogger(name, SYSTEM_LOGGER_RB_NAME, (Module)null);
         return result;
     }
 
@@ -681,8 +680,10 @@
         LogManager manager = LogManager.getLogManager();
         // cleanup some Loggers that have been GC'ed
         manager.drainLoggerRefQueueBounded();
+        final Class<?> callerClass = Reflection.getCallerClass();
+        final Module module = callerClass.getModule();
         Logger result = new Logger(null, resourceBundleName,
-                                   Reflection.getCallerClass(), manager, false);
+                                   module, manager, false);
         result.anonymous = true;
         Logger root = manager.getLogger("");
         result.doSetParent(root);
@@ -2046,6 +2047,11 @@
         }
     }
 
+    private void setupResourceInfo(String name, Class<?> caller) {
+        final Module module = caller == null ? null : caller.getModule();
+        setupResourceInfo(name, module);
+    }
+
     // Private utility method to initialize our one entry
     // resource bundle name cache and the callers Module
     // Note: for consistency reasons, we are careful to check
@@ -2053,7 +2059,7 @@
     // resourceBundleName field.
     // Synchronized to prevent races in setting the fields.
     private synchronized void setupResourceInfo(String name,
-                                                Class<?> callerClass) {
+                                                Module callerModule) {
         final LoggerBundle lb = loggerBundle;
         if (lb.resourceBundleName != null) {
             // this Logger already has a ResourceBundle
@@ -2072,8 +2078,9 @@
             return;
         }
 
-        setCallerModuleRef(callerClass);
-        if (isSystemLogger && (callerClass != null && callerClass.getClassLoader() != null)) {
+        setCallerModuleRef(callerModule);
+
+        if (isSystemLogger && (callerModule != null && !isSystem(callerModule))) {
             checkPermission();
         }
 
--- a/jdk/src/java.logging/share/classes/module-info.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.logging/share/classes/module-info.java	Thu Apr 28 23:08:16 2016 -0700
@@ -24,8 +24,6 @@
  */
 
 module java.logging {
-    // 8153158
-    requires jdk.unsupported;
     exports java.util.logging;
     provides jdk.internal.logger.DefaultLoggerFinder with
         sun.util.logging.internal.LoggingProviderImpl;
--- a/jdk/src/java.logging/share/classes/sun/util/logging/internal/LoggingProviderImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.logging/share/classes/sun/util/logging/internal/LoggingProviderImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -32,6 +32,7 @@
 import java.util.function.Supplier;
 import java.lang.System.LoggerFinder;
 import java.lang.System.Logger;
+import java.lang.reflect.Module;
 import java.util.Objects;
 import java.util.logging.LogManager;
 import jdk.internal.logger.DefaultLoggerFinder;
@@ -398,21 +399,20 @@
     }
 
     /**
-     * Creates a java.util.logging.Logger for the given caller.
+     * Creates a java.util.logging.Logger for the given module.
      * @param name the logger name.
-     * @param caller the caller for which the logger should be created.
-     * @return a Logger suitable for use in the given caller.
+     * @param module the module for which the logger should be created.
+     * @return a Logger suitable for use in the given module.
      */
     private static java.util.logging.Logger demandJULLoggerFor(final String name,
-                                                            /* Module */
-                                                            final Class<?> caller) {
+                                                               Module module) {
         final LogManager manager = LogManager.getLogManager();
         final SecurityManager sm = System.getSecurityManager();
         if (sm == null) {
-            return logManagerAccess.demandLoggerFor(manager, name, caller);
+            return logManagerAccess.demandLoggerFor(manager, name, module);
         } else {
             final PrivilegedAction<java.util.logging.Logger> pa =
-                    () -> logManagerAccess.demandLoggerFor(manager, name, caller);
+                    () -> logManagerAccess.demandLoggerFor(manager, name, module);
             return AccessController.doPrivileged(pa, null, LOGGING_CONTROL_PERMISSION);
         }
     }
@@ -429,17 +429,17 @@
      * {@code RuntimePermission("loggerFinder")}.
      */
     @Override
-    protected Logger demandLoggerFor(String name, /* Module */ Class<?> caller) {
+    protected Logger demandLoggerFor(String name, Module module) {
         final SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
             sm.checkPermission(LOGGERFINDER_PERMISSION);
         }
-        return JULWrapper.of(demandJULLoggerFor(name,caller));
+        return JULWrapper.of(demandJULLoggerFor(name,module));
     }
 
     public static interface LogManagerAccess {
         java.util.logging.Logger demandLoggerFor(LogManager manager,
-                String name, /* Module */ Class<?> caller);
+                String name, Module module);
     }
 
     // Hook for tests
--- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ClientCommunicatorAdmin.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ClientCommunicatorAdmin.java	Thu Apr 28 23:08:16 2016 -0700
@@ -30,7 +30,6 @@
 
 import com.sun.jmx.remote.util.ClassLogger;
 import com.sun.jmx.remote.util.EnvHelp;
-import sun.misc.ManagedLocalsThread;
 
 public abstract class ClientCommunicatorAdmin {
     private static volatile long threadNo = 1;
@@ -41,10 +40,11 @@
         if (period > 0) {
             checker = new Checker();
 
-            Thread t = new ManagedLocalsThread(
-                checker,
-                "JMX client heartbeat " +  (++threadNo)
-            );
+            Thread t = new Thread(null,
+                                  checker,
+                                  "JMX client heartbeat " +  (++threadNo),
+                                  0,
+                                  false);
 
             t.setDaemon(true);
             t.start();
--- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java	Thu Apr 28 23:08:16 2016 -0700
@@ -52,7 +52,6 @@
 import com.sun.jmx.remote.util.ClassLogger;
 import com.sun.jmx.remote.util.EnvHelp;
 import java.rmi.UnmarshalException;
-import sun.misc.ManagedLocalsThread;
 
 
 public abstract class ClientNotifForwarder {
@@ -91,7 +90,8 @@
                 throw new IllegalArgumentException("More than one command");
             this.command = command;
             if (thread == null) {
-                thread = new ManagedLocalsThread(
+                thread = new Thread(
+                    null,
                     ()-> {
                         while (true) {
                             Runnable r;
@@ -107,7 +107,9 @@
                             r.run();
                         }
                     },
-                    "ClientNotifForwarder-" + ++threadId
+                    "ClientNotifForwarder-" + ++threadId,
+                    0,
+                    false
                 );
                 thread.setDaemon(true);
                 thread.start();
--- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ServerCommunicatorAdmin.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ServerCommunicatorAdmin.java	Thu Apr 28 23:08:16 2016 -0700
@@ -27,7 +27,6 @@
 
 
 import com.sun.jmx.remote.util.ClassLogger;
-import sun.misc.ManagedLocalsThread;
 
 public abstract class ServerCommunicatorAdmin {
     public ServerCommunicatorAdmin(long timeout) {
@@ -42,7 +41,11 @@
         timestamp = 0;
         if (timeout < Long.MAX_VALUE) {
             Runnable timeoutTask = new Timeout();
-            final Thread t = new ManagedLocalsThread(timeoutTask);
+            final Thread t = new Thread(null,
+                                        timeoutTask,
+                                        "JMX-Server-Admin-Timeout",
+                                        0,
+                                        false);
             t.setName("JMX server connection timeout " + t.getId());
             // If you change this name you will need to change a unit test
             // (NoServerTimeoutTest)
--- a/jdk/src/java.management/share/classes/javax/management/monitor/Monitor.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.management/share/classes/javax/management/monitor/Monitor.java	Thu Apr 28 23:08:16 2016 -0700
@@ -61,7 +61,6 @@
 import javax.management.ObjectName;
 import javax.management.ReflectionException;
 import static javax.management.monitor.MonitorNotification.*;
-import sun.misc.ManagedLocalsThread;
 
 /**
  * Defines the part common to all monitor MBeans.
@@ -1637,10 +1636,12 @@
         }
 
         public Thread newThread(Runnable r) {
-            Thread t = new ManagedLocalsThread(
+            Thread t = new Thread(
                 group,
                 r,
-                namePrefix + threadNumber.getAndIncrement() + nameSuffix
+                namePrefix + threadNumber.getAndIncrement() + nameSuffix,
+                0,
+                false
             );
 
             t.setDaemon(true);
--- a/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIConnectorServer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIConnectorServer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, 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
@@ -45,6 +45,7 @@
 
 import javax.management.InstanceNotFoundException;
 import javax.management.MBeanServer;
+import javax.management.remote.JMXAuthenticator;
 
 import javax.management.remote.JMXConnectionNotification;
 import javax.management.remote.JMXConnector;
@@ -100,6 +101,21 @@
         "jmx.remote.rmi.server.socket.factory";
 
     /**
+    * Name of the attribute that specifies a list of class names acceptable
+    * as parameters to the {@link RMIServer#newClient(java.lang.Object) RMIServer.newClient()}
+    * remote method call.
+    * <p>
+    * This list of classes should correspond to the transitive closure of the
+    * credentials class (or classes) used by the installed {@linkplain JMXAuthenticator}
+    * associated with the {@linkplain RMIServer} implementation.
+    * <p>
+    * If the attribute is not set, or is null, then any class is
+    * deemed acceptable.
+    */
+    public static final String CREDENTIAL_TYPES =
+            "jmx.remote.rmi.server.credential.types";
+
+    /**
      * <p>Makes an <code>RMIConnectorServer</code>.
      * This is equivalent to calling {@link #RMIConnectorServer(
      * JMXServiceURL,Map,RMIServerImpl,MBeanServer)
--- a/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIJRMPServerImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIJRMPServerImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,6 +39,13 @@
 
 import com.sun.jmx.remote.internal.RMIExporter;
 import com.sun.jmx.remote.util.EnvHelp;
+import java.io.ObjectStreamClass;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import sun.reflect.misc.ReflectUtil;
+import sun.rmi.server.DeserializationChecker;
 import sun.rmi.server.UnicastServerRef;
 import sun.rmi.server.UnicastServerRef2;
 
@@ -52,6 +59,9 @@
  * @since 1.5
  */
 public class RMIJRMPServerImpl extends RMIServerImpl {
+
+    private final ExportedWrapper exportedWrapper;
+
     /**
      * <p>Creates a new {@link RMIServer} object that will be exported
      * on the given port using the given socket factories.</p>
@@ -89,10 +99,31 @@
         this.csf = csf;
         this.ssf = ssf;
         this.env = (env == null) ? Collections.<String, Object>emptyMap() : env;
+
+        String[] credentialsTypes
+                = (String[]) this.env.get(RMIConnectorServer.CREDENTIAL_TYPES);
+        List<String> types = null;
+        if (credentialsTypes != null) {
+            types = new ArrayList<>();
+            for (String type : credentialsTypes) {
+                if (type == null) {
+                    throw new IllegalArgumentException("A credential type is null.");
+                }
+                ReflectUtil.checkPackageAccess(type);
+                types.add(type);
+            }
+        }
+        exportedWrapper = types != null ?
+                new ExportedWrapper(this, types) :
+                null;
     }
 
     protected void export() throws IOException {
-        export(this);
+        if (exportedWrapper != null) {
+            export(exportedWrapper);
+        } else {
+            export(this);
+        }
     }
 
     private void export(Remote obj) throws RemoteException {
@@ -142,7 +173,11 @@
      *            RMIJRMPServerImpl has not been exported yet.
      */
     public Remote toStub() throws IOException {
-        return RemoteObject.toStub(this);
+        if (exportedWrapper != null) {
+            return RemoteObject.toStub(exportedWrapper);
+        } else {
+            return RemoteObject.toStub(this);
+        }
     }
 
     /**
@@ -189,11 +224,56 @@
      * server failed.
      */
     protected void closeServer() throws IOException {
-        unexport(this, true);
+        if (exportedWrapper != null) {
+            unexport(exportedWrapper, true);
+        } else {
+            unexport(this, true);
+        }
     }
 
     private final int port;
     private final RMIClientSocketFactory csf;
     private final RMIServerSocketFactory ssf;
     private final Map<String, ?> env;
+
+    private static class ExportedWrapper implements RMIServer, DeserializationChecker {
+        private final RMIServer impl;
+        private final List<String> allowedTypes;
+
+        private ExportedWrapper(RMIServer impl, List<String> credentialsTypes) {
+            this.impl = impl;
+            allowedTypes = credentialsTypes;
+        }
+
+        @Override
+        public String getVersion() throws RemoteException {
+            return impl.getVersion();
+        }
+
+        @Override
+        public RMIConnection newClient(Object credentials) throws IOException {
+            return impl.newClient(credentials);
+        }
+
+        @Override
+        public void check(Method method, ObjectStreamClass descriptor,
+                int paramIndex, int callID) {
+            String type = descriptor.getName();
+            if (!allowedTypes.contains(type)) {
+                throw new ClassCastException("Unsupported type: " + type);
+            }
+        }
+
+        @Override
+        public void checkProxyClass(Method method, String[] ifaces,
+                int paramIndex, int callID) {
+            if (ifaces != null && ifaces.length > 0) {
+                for (String iface : ifaces) {
+                    if (!allowedTypes.contains(iface)) {
+                        throw new ClassCastException("Unsupported type: " + iface);
+                    }
+                }
+            }
+        }
+    }
 }
--- a/jdk/src/java.management/share/classes/module-info.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.management/share/classes/module-info.java	Thu Apr 28 23:08:16 2016 -0700
@@ -27,8 +27,6 @@
     requires public java.rmi;
     requires java.logging;
     requires java.naming;
-    // 8147553
-    requires jdk.unsupported;
 
     exports java.lang.management;
     exports javax.management;
--- a/jdk/src/java.management/share/classes/sun/management/jdp/JdpController.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.management/share/classes/sun/management/jdp/JdpController.java	Thu Apr 28 23:08:16 2016 -0700
@@ -34,7 +34,6 @@
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import sun.management.VMManagement;
-import sun.misc.ManagedLocalsThread;
 
 /**
  * JdpController is responsible to create and manage a broadcast loop.
@@ -219,7 +218,7 @@
 
         controller = new JDPControllerRunner(bcast, packet, pause);
 
-        Thread t = new ManagedLocalsThread(controller, "JDP broadcaster");
+        Thread t = new Thread(null, controller, "JDP broadcaster", 0, false);
         t.setDaemon(true);
         t.start();
     }
--- a/jdk/src/java.management/share/classes/sun/management/jmxremote/ConnectorBootstrap.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.management/share/classes/sun/management/jmxremote/ConnectorBootstrap.java	Thu Apr 28 23:08:16 2016 -0700
@@ -510,6 +510,9 @@
         // This RMI server should not keep the VM alive
         Map<String, Object> env = new HashMap<>();
         env.put(RMIExporter.EXPORTER_ATTRIBUTE, new PermanentExporter());
+        env.put(RMIConnectorServer.CREDENTIAL_TYPES, new String[]{
+            String[].class.getName(), String.class.getName()
+        });
 
         // The local connector server need only be available via the
         // loopback connection.
@@ -740,6 +743,9 @@
         PermanentExporter exporter = new PermanentExporter();
 
         env.put(RMIExporter.EXPORTER_ATTRIBUTE, exporter);
+        env.put(RMIConnectorServer.CREDENTIAL_TYPES, new String[]{
+            String[].class.getName(), String.class.getName()
+        });
 
         boolean useSocketFactory = bindAddress != null && !useSsl;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.rmi/share/classes/sun/rmi/server/DeserializationChecker.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.rmi.server;
+
+import java.io.ObjectStreamClass;
+import java.lang.reflect.Method;
+
+/**
+ * Implementing this interface to have a deserialization control when RMI
+ * dispatches a remote request. If an exported object implements this interface,
+ * RMI dispatching mechanism will call the method {@code check} every time
+ * deserialising a remote object for invoking a method of the exported object.
+ *
+ * @author sjiang
+ */
+public interface DeserializationChecker {
+    /**
+     * Will be called to check a descriptor.
+     * This method may be called 2 times, the first time is when a descriptor is read
+     * from the stream, the second is just before creating an object described
+     * by this descriptor.
+     *
+     * @param method the method invoked from a remote request.
+     * @param descriptor The descriptor of the class of any object deserialised
+     *  while deserialising the parameter. The first descriptor will be that of
+     *  the top level object (the concrete class of the parameter itself);
+     *  Subsequent calls with the same {@code method}, {@code paramIndex} and
+     *  {@code callID} will correspond to objects contained in the parameter.
+     * @param paramIndex an index indicates the position of a parameter in the
+     * method. This index will be reused for deserialising all
+     * objects contained in the parameter object. For example, the parameter
+     * being deserialised is a {@code List}, all deserialisation calls for its
+     * elements will have same index.
+     * @param callID a unique ID identifying one
+     * time method invocation, the same ID is used for deserialization call of
+     * all parameters within the method.
+     */
+    public void check(Method method,
+            ObjectStreamClass descriptor,
+            int paramIndex,
+            int callID);
+
+    /**
+     * Will be called to validate a Proxy interfaces from a remote user before loading it.
+     * @param method the method invoked from a remote request.
+     * @param ifaces a string table of all interfaces implemented by the proxy to be checked.
+     * @param paramIndex an index indicates the position of a parameter in the
+     * method. This index will be reused for deserialising all
+     * objects contained in the parameter object. For example, the parameter
+     * being deserialised is a {@code List}, all deserialisation calls for its
+     * elements will have same index.
+     * @param callID a unique ID identifying one
+     * time method invocation, the same ID is used for deserialization call of
+     * all parameters within the method.
+     */
+    public void checkProxyClass(Method method,
+            String[] ifaces,
+            int paramIndex,
+            int callID);
+
+    /**
+     * Inform of the completion of parameter deserialisation for a method invocation.
+     * This is useful if the last parameter is a complex  object, like a {@code List}
+     * which elements are complex object too.
+     *
+     * The default implementation does nothing.
+     * @param callID the ID identifying a method invocation.
+     */
+    public default void end(int callID) {}
+}
--- a/jdk/src/java.rmi/share/classes/sun/rmi/server/MarshalInputStream.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.rmi/share/classes/sun/rmi/server/MarshalInputStream.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, 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,13 +30,13 @@
 import java.io.ObjectInputStream;
 import java.io.ObjectStreamClass;
 import java.io.StreamCorruptedException;
-import java.net.URL;
 import java.util.*;
 import java.security.AccessControlException;
 import java.security.Permission;
-
 import java.rmi.server.RMIClassLoader;
 import java.security.PrivilegedAction;
+import jdk.internal.misc.ObjectStreamClassValidator;
+import jdk.internal.misc.SharedSecrets;
 
 /**
  * MarshalInputStream is an extension of ObjectInputStream.  When resolving
@@ -54,6 +54,11 @@
  * @author      Peter Jones
  */
 public class MarshalInputStream extends ObjectInputStream {
+    interface StreamChecker extends ObjectStreamClassValidator {
+        void checkProxyInterfaceNames(String[] ifaces);
+    }
+
+    private volatile StreamChecker streamChecker = null;
 
     /**
      * Value of "java.rmi.server.useCodebaseOnly" property,
@@ -123,7 +128,7 @@
         throws IOException, StreamCorruptedException
     {
         super(in);
-    }
+                    }
 
     /**
      * Returns a callback previously registered via the setDoneCallback
@@ -240,6 +245,11 @@
     protected Class<?> resolveProxyClass(String[] interfaces)
         throws IOException, ClassNotFoundException
     {
+        StreamChecker checker = streamChecker;
+        if (checker != null) {
+            checker.checkProxyInterfaceNames(interfaces);
+        }
+
         /*
          * Always read annotation written by MarshalOutputStream.
          */
@@ -319,4 +329,28 @@
     void useCodebaseOnly() {
         useCodebaseOnly = true;
     }
+
+    synchronized void setStreamChecker(StreamChecker checker) {
+        streamChecker = checker;
+        SharedSecrets.getJavaObjectInputStreamAccess().setValidator(this, checker);
+    }
+    @Override
+    protected ObjectStreamClass readClassDescriptor() throws IOException,
+            ClassNotFoundException {
+        ObjectStreamClass descriptor = super.readClassDescriptor();
+
+        validateDesc(descriptor);
+
+        return descriptor;
+    }
+
+    private void validateDesc(ObjectStreamClass descriptor) {
+        StreamChecker checker;
+        synchronized (this) {
+            checker = streamChecker;
+        }
+        if (checker != null) {
+            checker.validateDescriptor(descriptor);
+        }
+    }
 }
--- a/jdk/src/java.rmi/share/classes/sun/rmi/server/UnicastServerRef.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.rmi/share/classes/sun/rmi/server/UnicastServerRef.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,7 @@
 import java.io.IOException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
-import java.io.PrintStream;
+import java.io.ObjectStreamClass;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.rmi.MarshalException;
@@ -52,6 +52,7 @@
 import java.util.HashMap;
 import java.util.Map;
 import java.util.WeakHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
 import sun.rmi.runtime.Log;
 import sun.rmi.transport.LiveRef;
 import sun.rmi.transport.Target;
@@ -116,6 +117,8 @@
     private static final Map<Class<?>,?> withoutSkeletons =
         Collections.synchronizedMap(new WeakHashMap<Class<?>,Void>());
 
+    private final AtomicInteger methodCallIDCount = new AtomicInteger(0);
+
     /**
      * Create a new (empty) Unicast server remote reference.
      */
@@ -297,14 +300,11 @@
             logCall(obj, method);
 
             // unmarshal parameters
-            Class<?>[] types = method.getParameterTypes();
-            Object[] params = new Object[types.length];
+            Object[] params = null;
 
             try {
                 unmarshalCustomCallData(in);
-                for (int i = 0; i < types.length; i++) {
-                    params[i] = unmarshalValue(types[i], in);
-                }
+                params = unmarshalParameters(obj, method, marshalStream);
             } catch (java.io.IOException e) {
                 throw new UnmarshalException(
                     "error unmarshalling arguments", e);
@@ -565,4 +565,85 @@
             return map;
         }
     }
+
+    /**
+     * Unmarshal parameters for the given method of the given instance over
+     * the given marshalinputstream. Perform any necessary checks.
+     */
+    private Object[] unmarshalParameters(Object obj, Method method, MarshalInputStream in)
+    throws IOException, ClassNotFoundException {
+        return (obj instanceof DeserializationChecker) ?
+            unmarshalParametersChecked((DeserializationChecker)obj, method, in) :
+            unmarshalParametersUnchecked(method, in);
+    }
+
+    /**
+     * Unmarshal parameters for the given method of the given instance over
+     * the given marshalinputstream. Do not perform any additional checks.
+     */
+    private Object[] unmarshalParametersUnchecked(Method method, ObjectInput in)
+    throws IOException, ClassNotFoundException {
+        Class<?>[] types = method.getParameterTypes();
+        Object[] params = new Object[types.length];
+        for (int i = 0; i < types.length; i++) {
+            params[i] = unmarshalValue(types[i], in);
+        }
+        return params;
+    }
+
+    /**
+     * Unmarshal parameters for the given method of the given instance over
+     * the given marshalinputstream. Do perform all additional checks.
+     */
+    private Object[] unmarshalParametersChecked(
+        DeserializationChecker checker,
+        Method method, MarshalInputStream in)
+    throws IOException, ClassNotFoundException {
+        int callID = methodCallIDCount.getAndIncrement();
+        MyChecker myChecker = new MyChecker(checker, method, callID);
+        in.setStreamChecker(myChecker);
+        try {
+            Class<?>[] types = method.getParameterTypes();
+            Object[] values = new Object[types.length];
+            for (int i = 0; i < types.length; i++) {
+                myChecker.setIndex(i);
+                values[i] = unmarshalValue(types[i], in);
+            }
+            myChecker.end(callID);
+            return values;
+        } finally {
+            in.setStreamChecker(null);
+        }
+    }
+
+    private static class MyChecker implements MarshalInputStream.StreamChecker {
+        private final DeserializationChecker descriptorCheck;
+        private final Method method;
+        private final int callID;
+        private int parameterIndex;
+
+        MyChecker(DeserializationChecker descriptorCheck, Method method, int callID) {
+            this.descriptorCheck = descriptorCheck;
+            this.method = method;
+            this.callID = callID;
+        }
+
+        @Override
+        public void validateDescriptor(ObjectStreamClass descriptor) {
+            descriptorCheck.check(method, descriptor, parameterIndex, callID);
+        }
+
+        @Override
+        public void checkProxyInterfaceNames(String[] ifaces) {
+            descriptorCheck.checkProxyClass(method, ifaces, parameterIndex, callID);
+        }
+
+        void setIndex(int parameterIndex) {
+            this.parameterIndex = parameterIndex;
+        }
+
+        void end(int callId) {
+            descriptorCheck.end(callId);
+        }
+    }
 }
--- a/jdk/src/java.security.jgss/share/classes/sun/security/jgss/SunProvider.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/SunProvider.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -97,8 +97,6 @@
         }
     }
 
-    public static final SunProvider INSTANCE = new SunProvider();
-
     public SunProvider() {
         /* We are the Sun JGSS provider */
         super("SunJGSS", 9.0d, INFO);
--- a/jdk/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSNameElement.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSNameElement.java	Thu Apr 28 23:08:16 2016 -0700
@@ -159,7 +159,9 @@
             int atPos = krbName.lastIndexOf('@');
             if (atPos != -1) {
                 String atRealm = krbName.substring(atPos);
-                if (nameType.equals(GSSUtil.NT_GSS_KRB5_PRINCIPAL)
+                // getNativeNameType() can modify NT_GSS_KRB5_PRINCIPAL to null
+                if ((nameType == null
+                            || nameType.equals(GSSUtil.NT_GSS_KRB5_PRINCIPAL))
                         && new String(nameBytes).endsWith(atRealm)) {
                     // Created from Kerberos name with realm, no need to check
                 } else {
--- a/jdk/src/java.security.jgss/windows/classes/sun/security/krb5/internal/tools/Klist.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.security.jgss/windows/classes/sun/security/krb5/internal/tools/Klist.java	Thu Apr 28 23:08:16 2016 -0700
@@ -134,7 +134,7 @@
         Character arg;
         for (int i = 0; i < args.length; i++) {
             if ((args[i].length() >= 2) && (args[i].startsWith("-"))) {
-                arg = new Character(args[i].charAt(1));
+                arg = Character.valueOf(args[i].charAt(1));
                 switch (arg.charValue()) {
                 case 'c':
                     action = 'c';
--- a/jdk/src/java.sql.rowset/share/classes/com/sun/rowset/CachedRowSetImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/java.sql.rowset/share/classes/com/sun/rowset/CachedRowSetImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1963,7 +1963,7 @@
             return (float)0;
         }
         try {
-            return ((new Float(value.toString())).floatValue());
+            return Float.parseFloat(value.toString());
         } catch (NumberFormatException ex) {
             throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.floatfail").toString(),
                   new Object[] {value.toString().trim(), columnIndex}));
@@ -2007,7 +2007,7 @@
             return (double)0;
         }
         try {
-            return ((new Double(value.toString().trim())).doubleValue());
+            return Double.parseDouble(value.toString().trim());
         } catch (NumberFormatException ex) {
             throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.doublefail").toString(),
                   new Object[] {value.toString().trim(), columnIndex}));
@@ -4017,9 +4017,9 @@
                     return new BigDecimal(srcObj.toString().trim());
                 case java.sql.Types.REAL:
                 case java.sql.Types.FLOAT:
-                    return new Float(srcObj.toString().trim());
+                    return Float.valueOf(srcObj.toString().trim());
                 case java.sql.Types.DOUBLE:
-                    return new Double(srcObj.toString().trim());
+                    return Double.valueOf(srcObj.toString().trim());
                 case java.sql.Types.CHAR:
                 case java.sql.Types.VARCHAR:
                 case java.sql.Types.LONGVARCHAR:
--- a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/Translator.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/Translator.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, 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,13 +26,11 @@
 
 package com.sun.java.accessibility.util;
 
-import java.lang.*;
+import com.sun.java.accessibility.util.internal.*;
 import java.beans.*;
 import java.util.*;
 import java.awt.*;
 import java.awt.event.*;
-import java.awt.image.*;
-import java.security.AccessControlException;
 // Do not import Swing classes.  This module is intended to work
 // with both Swing and AWT.
 // import javax.swing.*;
@@ -77,12 +75,26 @@
         if (c == null) {
             return null;
         }
-        try {
-            t = Class.forName("com.sun.java.accessibility.util.internal."
-                              + c.getSimpleName()
-                              + "Translator");
+        switch (c.getSimpleName()) {
+            case "Button":
+                t = ButtonTranslator.class;
+                break;
+            case "Checkbox":
+                t = CheckboxTranslator.class;
+                break;
+            case "Label":
+                t = LabelTranslator.class;
+                break;
+            case "List":
+                t = ListTranslator.class;
+                break;
+            case "TextComponent":
+                t = TextComponentTranslator.class;
+                break;
+        }
+        if (t != null) {
             return t;
-        } catch (Exception e) {
+        } else {
             return getTranslatorClass(c.getSuperclass());
         }
     }
@@ -106,10 +118,6 @@
         if (o instanceof Accessible) {
             a = (Accessible)o;
         } else {
-            // About to "newInstance" an object of a class of a restricted package
-            // so ensure the caller is allowed access to that package.
-            String pkg = "com.sun.java.accessibility.util.internal";
-            System.getSecurityManager().checkPackageAccess(pkg);
             Class<?> translatorClass = getTranslatorClass(o.getClass());
             if (translatorClass != null) {
                 try {
--- a/jdk/src/jdk.accessibility/windows/native/jaccesswalker/jaccesswalker.cpp	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/jdk.accessibility/windows/native/jaccesswalker/jaccesswalker.cpp	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -543,7 +543,7 @@
     } else {
         char s[LINE_BUFSIZE];
         sprintf( s,
-            "ERROR calling GetAccessibleContextInfo; vmID = %X, context = %X",
+            "ERROR calling GetAccessibleContextInfo; vmID = %X, context = %p",
             vmID, context );
 
         TVITEM tvi;
--- a/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/WinAccessBridge.cpp	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/jdk.accessibility/windows/native/libwindowsaccessbridge/WinAccessBridge.cpp	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -1125,7 +1125,7 @@
 
     PrintDebugString("WinAccessBridge::getAccessibleContextWithFocus(%p, %X, )", window, vmID);
     // find vmID, etc. from HWND; ask that VM for the AC w/Focus
-        HWND pkgVMID = (HWND)ABLongToHandle( pkg->rVMID ) ;
+    HWND pkgVMID;
     if (getAccessibleContextFromHWND(window, (long *)&(pkgVMID), &(pkg->rAccessibleContext)) == TRUE) {
         HWND destABWindow = javaVMs->findAccessBridgeWindow((long)pkgVMID);     // ineffecient [[[FIXME]]]
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
--- a/jdk/src/jdk.crypto.pkcs11/share/classes/module-info.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/jdk.crypto.pkcs11/share/classes/module-info.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, 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,6 @@
 module jdk.crypto.pkcs11 {
     // Depends on SunEC provider for EC related functionality
     requires jdk.crypto.ec;
-    // 8153371
-    requires jdk.unsupported;
     provides java.security.Provider with sun.security.pkcs11.SunPKCS11;
 }
 
--- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/SunPKCS11.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/SunPKCS11.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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,7 +42,6 @@
 import javax.security.auth.callback.PasswordCallback;
 import javax.security.auth.callback.TextOutputCallback;
 
-import sun.misc.ManagedLocalsThread;
 import sun.security.util.Debug;
 import sun.security.util.ResourcesMgr;
 
@@ -816,7 +815,7 @@
             return;
         }
         final TokenPoller poller = new TokenPoller(this);
-        Thread t = new ManagedLocalsThread(poller, "Poller " + getName());
+        Thread t = new Thread(null, poller, "Poller " + getName(), 0, false);
         t.setDaemon(true);
         t.setPriority(Thread.MIN_PRIORITY);
         t.start();
--- a/jdk/src/jdk.httpserver/share/classes/module-info.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/jdk.httpserver/share/classes/module-info.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,8 +25,7 @@
 
 module jdk.httpserver {
     requires java.logging;
-    // 8153372
-    requires jdk.unsupported;
+
     exports com.sun.net.httpserver;
     exports com.sun.net.httpserver.spi;
     uses com.sun.net.httpserver.spi.HttpServerProvider;
--- a/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -36,7 +36,6 @@
 import com.sun.net.httpserver.*;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-import sun.misc.ManagedLocalsThread;
 import sun.net.httpserver.HttpConnection.State;
 
 /**
@@ -143,7 +142,7 @@
         if (executor == null) {
             executor = new DefaultExecutor();
         }
-        dispatcherThread = new ManagedLocalsThread(dispatcher);
+        dispatcherThread = new Thread(null, dispatcher, "HTTP-Dispatcher", 0, false);
         started = true;
         dispatcherThread.start();
     }
--- a/jdk/src/jdk.jcmd/share/classes/sun/tools/jstat/ExpressionExecuter.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/jdk.jcmd/share/classes/sun/tools/jstat/ExpressionExecuter.java	Thu Apr 28 23:08:16 2016 -0700
@@ -83,14 +83,14 @@
         if (op == null) {
             return evaluate(l);
         } else {
-            Double lval = new Double(((Number)evaluate(l)).doubleValue());
-            Double rval = new Double(((Number)evaluate(r)).doubleValue());
-            double result = op.eval(lval.doubleValue(), rval.doubleValue());
+            double lval = ((Number)evaluate(l)).doubleValue();
+            double rval = ((Number)evaluate(r)).doubleValue();
+            double result = op.eval(lval, rval);
             if (debug) {
                 System.out.println("Performed Operation: " + lval + op + rval
                                    + " = " + result);
             }
-            return new Double(result);
+            return Double.valueOf(result);
         }
     }
 }
--- a/jdk/src/jdk.jcmd/share/classes/sun/tools/jstat/ExpressionResolver.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/jdk.jcmd/share/classes/sun/tools/jstat/ExpressionResolver.java	Thu Apr 28 23:08:16 2016 -0700
@@ -71,7 +71,7 @@
             if (m == null) {
                 System.err.println("Warning: Unresolved Symbol: "
                                    + id.getName() + " substituted NaN");
-                return new Literal(new Double(Double.NaN));
+                return new Literal(Double.valueOf(Double.NaN));
             }
             if (m.getVariability() == Variability.CONSTANT) {
                 if (debug) {
@@ -105,7 +105,7 @@
                 Literal rl = (Literal)r;
                 boolean warn = false;
 
-                Double nan = new Double(Double.NaN);
+                Double nan = Double.valueOf(Double.NaN);
                 if (ll.getValue() instanceof String) {
                     warn = true; ll.setValue(nan);
                 }
@@ -129,7 +129,7 @@
                                        + " (right = " + rn.doubleValue() + ")"
                                        + " to literal value " + result);
                 }
-                return new Literal(new Double(result));
+                return new Literal(Double.valueOf(result));
             }
         }
 
--- a/jdk/src/jdk.jcmd/share/classes/sun/tools/jstat/Parser.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/jdk.jcmd/share/classes/sun/tools/jstat/Parser.java	Thu Apr 28 23:08:16 2016 -0700
@@ -324,7 +324,7 @@
         case StreamTokenizer.TT_NUMBER:
             double literal = lookahead.nval;
             matchNumber();
-            e = new Literal(new Double(literal));
+            e = new Literal(Double.valueOf(literal));
             log(pdebug, "Parsed: number -> " + literal);
             break;
         default:
@@ -360,7 +360,7 @@
             e1.setOperator(op);
             e1.setRight(e);
             log(pdebug, "Parsed: unary -> " + e1);
-            e1.setLeft(new Literal(new Double(0)));
+            e1.setLeft(new Literal(Double.valueOf(0)));
             e = e1;
         }
     }
--- a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/VirtualMachineManager.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/VirtualMachineManager.java	Thu Apr 28 23:08:16 2016 -0700
@@ -257,11 +257,11 @@
  * delegate to the {@link com.sun.jdi.connect.spi.TransportService#description()
  * description()} method of the underlying transport service. Both
  * the AttachingConnector and the ListeningConnector will have two
- * Connector {@link com.sun.jdi.connect.Connector$Argument Arguments}.
- * A {@link com.sun.jdi.connect.Connector$StringArgument StringArgument}
+ * Connector {@link com.sun.jdi.connect.Connector.Argument Arguments}.
+ * A {@link com.sun.jdi.connect.Connector.StringArgument StringArgument}
  * named {@code address} is the connector argument to specify the
  * address to attach too, or to listen on. A
- * {@link com.sun.jdi.connect.Connector$IntegerArgument IntegerArgument}
+ * {@link com.sun.jdi.connect.Connector.IntegerArgument IntegerArgument}
  * named {@code timeout} is the connector argument to specify the
  * timeout when attaching, or accepting. The timeout connector may be
  * ignored depending on if the transport service supports an attach
--- a/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/Commands.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/Commands.java	Thu Apr 28 23:08:16 2016 -0700
@@ -478,7 +478,7 @@
             ThreadGroupReference tg = it.nextThreadGroup();
             ++cnt;
             MessageOutput.println("thread group number description name",
-                                  new Object [] { new Integer (cnt),
+                                  new Object [] { Integer.valueOf(cnt),
                                                   Env.description(tg),
                                                   tg.name()});
         }
@@ -1014,7 +1014,7 @@
         return MessageOutput.format("locationString",
                                     new Object [] {loc.declaringType().name(),
                                                    loc.method().name(),
-                                                   new Integer (loc.lineNumber()),
+                                                   Integer.valueOf(loc.lineNumber()),
                                                    Long.valueOf(loc.codeIndex())});
     }
 
@@ -1467,7 +1467,7 @@
                 MessageOutput.println("Line number information not available for");
             } else if (Env.sourceLine(loc, lineno) == null) {
                 MessageOutput.println("is an invalid line number for",
-                                      new Object [] {new Integer (lineno),
+                                      new Object [] {Integer.valueOf(lineno),
                                                      refType.name()});
             } else {
                 for (int i = startLine; i <= endLine; i++) {
@@ -1477,11 +1477,11 @@
                     }
                     if (i == lineno) {
                         MessageOutput.println("source line number current line and line",
-                                              new Object [] {new Integer (i),
+                                              new Object [] {Integer.valueOf(i),
                                                              sourceLine});
                     } else {
                         MessageOutput.println("source line number and line",
-                                              new Object [] {new Integer (i),
+                                              new Object [] {Integer.valueOf(i),
                                                              sourceLine});
                     }
                 }
@@ -1725,7 +1725,7 @@
                 } else {
                     MessageOutput.println("Owned by:",
                                           new Object [] {owner.name(),
-                                                         new Integer (object.entryCount())});
+                                                         Integer.valueOf(object.entryCount())});
                 }
                 List<ThreadReference> waiters = object.waitingThreads();
                 if (waiters.size() == 0) {
--- a/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/MessageOutput.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/MessageOutput.java	Thu Apr 28 23:08:16 2016 -0700
@@ -198,7 +198,7 @@
                 (MessageOutput.format("jdb prompt thread name and current stack frame",
                                       new Object [] {
                                           threadInfo.getThread().name(),
-                                          new Integer (threadInfo.getCurrentFrameIndex() + 1)}));
+                                          Integer.valueOf(threadInfo.getCurrentFrameIndex() + 1)}));
         }
         System.out.flush();
     }
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/ExtractedImage.java	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2015, 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 jdk.tools.jimage;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.function.Consumer;
-import jdk.tools.jlink.internal.ImageFileCreator;
-import jdk.tools.jlink.internal.Archive;
-import jdk.tools.jlink.internal.ImagePluginStack;
-import jdk.tools.jlink.internal.DirArchive;
-/**
- *
- * Support for extracted image.
- */
-public final class ExtractedImage {
-
-    private Set<Archive> archives = new HashSet<>();
-    private final ImagePluginStack plugins;
-
-    ExtractedImage(Path dirPath, ImagePluginStack plugins, PrintWriter log,
-            boolean verbose) throws IOException {
-        if (!Files.isDirectory(dirPath)) {
-            throw new IOException("Not a directory");
-        }
-        Consumer<String> cons = (String t) -> {
-            if (verbose) {
-                log.println(t);
-            }
-        };
-        this.plugins = plugins;
-        Files.walk(dirPath, 1).forEach((p) -> {
-            if (!dirPath.equals(p)) {
-                if (Files.isDirectory(p)) {
-                    Archive a = new DirArchive(p, cons);
-                    archives.add(a);
-                }
-            }
-        });
-        archives = Collections.unmodifiableSet(archives);
-    }
-
-    void recreateJImage(Path path) throws IOException {
-        ImageFileCreator.recreateJimage(path, archives, plugins);
-    }
-
-    private static String getPathName(Path path) {
-        return path.toString().replace(File.separatorChar, '/');
-    }
-}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/JImageTask.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/JImageTask.java	Thu Apr 28 23:08:16 2016 -0700
@@ -32,7 +32,6 @@
 import java.nio.ByteOrder;
 import java.nio.channels.FileChannel;
 import java.nio.file.Files;
-import java.nio.file.Path;
 import static java.nio.file.StandardOpenOption.READ;
 import static java.nio.file.StandardOpenOption.WRITE;
 import java.util.LinkedList;
@@ -44,8 +43,6 @@
 import static jdk.internal.jimage.ImageHeader.MINOR_VERSION;
 import jdk.internal.jimage.ImageLocation;
 import jdk.tools.jlink.internal.ImageResourcesTree;
-import jdk.tools.jlink.internal.ImagePluginConfiguration;
-import jdk.tools.jlink.internal.ImagePluginStack;
 import jdk.tools.jlink.internal.TaskHelper;
 import jdk.tools.jlink.internal.TaskHelper.BadArgs;
 import static jdk.tools.jlink.internal.TaskHelper.JIMAGE_BUNDLE;
@@ -97,7 +94,6 @@
         EXTRACT,
         INFO,
         LIST,
-        RECREATE,
         SET,
         VERIFY
     };
@@ -152,21 +148,28 @@
             setLog(new PrintWriter(System.out));
         }
 
+        if (args.length == 0) {
+            log.println(taskHelper.getMessage("main.usage.summary", PROGNAME));
+            return EXIT_ABNORMAL;
+        }
+
         try {
             List<String> unhandled = optionsHelper.handleOptions(this, args);
             if(!unhandled.isEmpty()) {
-                options.task = Enum.valueOf(Task.class, unhandled.get(0).toUpperCase());
+                try {
+                    options.task = Enum.valueOf(Task.class, unhandled.get(0).toUpperCase());
+                } catch (IllegalArgumentException ex) {
+                    throw taskHelper.newBadArgs("err.not.a.task", unhandled.get(0));
+                }
                 for(int i = 1; i < unhandled.size(); i++) {
                     options.jimages.add(new File(unhandled.get(i)));
                 }
+            } else {
+                throw taskHelper.newBadArgs("err.not.a.task", "<unspecified>");
             }
             if (options.help) {
                 optionsHelper.showHelp(PROGNAME);
             }
-            if(optionsHelper.listPlugins()) {
-                optionsHelper.listPlugins(true);
-                return EXIT_OK;
-            }
             if (options.version || options.fullVersion) {
                 taskHelper.showVersion(options.fullVersion);
             }
@@ -186,49 +189,19 @@
         }
     }
 
-    private void recreate() throws Exception, BadArgs {
-        File directory = new File(options.directory);
-        if (!directory.isDirectory()) {
-            throw taskHelper.newBadArgs("err.not.a.dir", directory.getAbsolutePath());
-        }
-        Path dirPath = directory.toPath();
-        if (options.jimages.isEmpty()) {
-            throw taskHelper.newBadArgs("err.jimage.not.specified");
-        } else if (options.jimages.size() != 1) {
-            throw taskHelper.newBadArgs("err.only.one.jimage");
-        }
-
-        Path jimage = options.jimages.get(0).toPath();
-
-        if (jimage.toFile().createNewFile()) {
-            ImagePluginStack pc = ImagePluginConfiguration.parseConfiguration(taskHelper.
-                    getPluginsConfig(null, false));
-            ExtractedImage img = new ExtractedImage(dirPath, pc, log, options.verbose);
-            img.recreateJImage(jimage);
-        } else {
-            throw taskHelper.newBadArgs("err.jimage.already.exists", jimage.getFileName());
-        }
-    }
-
-    private void title(File file, BasicImageReader reader) {
-        log.println("jimage: " + file.getName());
-    }
-
     private void listTitle(File file, BasicImageReader reader) {
-        title(file, reader);
-
-        if (options.verbose) {
-            log.print(pad("Offset", OFFSET_WIDTH + 1));
-            log.print(pad("Size", SIZE_WIDTH + 1));
-            log.print(pad("Compressed", COMPRESSEDSIZE_WIDTH + 1));
-            log.println(" Entry");
-        }
+        log.println("jimage: " + file);
     }
 
     private interface JImageAction {
         public void apply(File file, BasicImageReader reader) throws IOException, BadArgs;
     }
 
+    private interface ModuleAction {
+         public void apply(BasicImageReader reader,
+                 String oldModule, String newModule) throws IOException, BadArgs;
+    }
+
     private interface ResourceAction {
         public void apply(BasicImageReader reader, String name,
                 ImageLocation location) throws IOException, BadArgs;
@@ -254,23 +227,32 @@
         }
     }
 
-    private static final int NUMBER_WIDTH = 12;
-    private static final int OFFSET_WIDTH = NUMBER_WIDTH;
-    private static final int SIZE_WIDTH = NUMBER_WIDTH;
-    private static final int COMPRESSEDSIZE_WIDTH = NUMBER_WIDTH;
+    private static final int OFFSET_WIDTH = 12;
+    private static final int SIZE_WIDTH = 10;
+    private static final int COMPRESSEDSIZE_WIDTH = 10;
+
+    private String trimModule(String name) {
+        int offset = name.indexOf('/', 1);
 
-    private void print(String entry, ImageLocation location) {
+        if (offset != -1 && offset + 1 < name.length()) {
+            return name.substring(offset + 1);
+        }
+
+        return name;
+    }
+
+    private void print(String name, ImageLocation location) {
         log.print(pad(location.getContentOffset(), OFFSET_WIDTH) + " ");
         log.print(pad(location.getUncompressedSize(), SIZE_WIDTH) + " ");
         log.print(pad(location.getCompressedSize(), COMPRESSEDSIZE_WIDTH) + " ");
-        log.println(entry);
+        log.println(trimModule(name));
     }
 
-    private void print(BasicImageReader reader, String entry) {
+    private void print(BasicImageReader reader, String name) {
         if (options.verbose) {
-            print(entry, reader.findLocation(entry));
+            print(name, reader.findLocation(name));
         } else {
-            log.println(entry);
+            log.println("    " + trimModule(name));
         }
     }
 
@@ -289,6 +271,18 @@
         log.println(" Index Size:     " + header.getIndexSize());
     }
 
+    private void listModule(BasicImageReader reader, String oldModule, String newModule) {
+        log.println();
+        log.println("Module: " + newModule);
+
+        if (options.verbose) {
+            log.print(pad("Offset", OFFSET_WIDTH) + " ");
+            log.print(pad("Size", SIZE_WIDTH) + " ");
+            log.print(pad("Compressed", COMPRESSEDSIZE_WIDTH) + " ");
+            log.println("Entry");
+        }
+    }
+
     private void list(BasicImageReader reader, String name, ImageLocation location) {
         print(reader, name);
     }
@@ -338,7 +332,12 @@
     }
 
     private void iterate(JImageAction jimageAction,
+            ModuleAction moduleAction,
             ResourceAction resourceAction) throws IOException, BadArgs {
+        if (options.jimages.isEmpty()) {
+            throw taskHelper.newBadArgs("err.no.jimage");
+        }
+
         for (File file : options.jimages) {
             if (!file.exists() || !file.isFile()) {
                 throw taskHelper.newBadArgs("err.not.a.jimage", file.getName());
@@ -351,9 +350,23 @@
 
                 if (resourceAction != null) {
                     String[] entryNames = reader.getEntryNames();
+                    String oldModule = "";
 
                     for (String name : entryNames) {
                         if (!ImageResourcesTree.isTreeInfoResource(name)) {
+                            if (moduleAction != null) {
+                                int offset = name.indexOf('/', 1);
+
+                                String newModule = offset != -1 ?
+                                        name.substring(1, offset) :
+                                        "<unknown>";
+
+                                if (!oldModule.equals(newModule)) {
+                                    moduleAction.apply(reader, oldModule, newModule);
+                                    oldModule = newModule;
+                                }
+                            }
+
                             ImageLocation location = reader.findLocation(name);
                             resourceAction.apply(reader, name, location);
                         }
@@ -366,22 +379,19 @@
     private boolean run() throws Exception, BadArgs {
         switch (options.task) {
             case EXTRACT:
-                iterate(null, this::extract);
+                iterate(null, null, this::extract);
                 break;
             case INFO:
-                iterate(this::info, null);
+                iterate(this::info, null, null);
                 break;
             case LIST:
-                iterate(this::listTitle, this::list);
-                break;
-            case RECREATE:
-                recreate();
+                iterate(this::listTitle, this::listModule, this::list);
                 break;
             case SET:
-                iterate(this::set, null);
+                iterate(this::set, null, null);
                 break;
             case VERIFY:
-                iterate(this::title, this::verify);
+                iterate(this::listTitle, null, this::verify);
                 break;
             default:
                 throw taskHelper.newBadArgs("err.invalid.task", options.task.name()).showUsage(true);
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/resources/jimage.properties	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/resources/jimage.properties	Thu Apr 28 23:08:16 2016 -0700
@@ -1,30 +1,25 @@
 main.usage.summary=\
-Usage: {0} <extract|info|list|recreate|set|verify> <options> jimage...\n\
+Usage: {0} <extract|info|list|set|verify> <options> jimage...\n\
 use --help for a list of possible options
 
 main.usage=\
-Usage: {0} <extract|info|list|recreate|set|verify> <options> jimage...\n\
+Usage: {0} <extract|info|list|set|verify> <options> jimage...\n\
 \n\
 \  extract  - Extract all jimage entries into separate files into the directory\n\
 \             specified by --dir=<directory> (default='.')\n\
 \  info     - Prints information specified in the jimage header.\n\
 \  list     - Prints the names of all the entries in the jimage.  When used with\n\
 \             --verbose will also print entry attributes ex. size and offset.\n\
-\  recreate - Reconstructs a jimage from an extracted directory (--dir)\n\
 \  set      - sets the value of specific jimage header entries\n\
 \  verify   - Reports errors on any .class entries that don't verify as classes.\n\
 \n\
 Possible options include:
 
-main.extended.help=\
-jimage recreate is extensible by the main of plugins. Following plugins have been discovered \
-thanks to ServiceLoader and can be used when re-creating a jimage.
-
 error.prefix=Error:
 warn.prefix=Warning:
 
 main.opt.dir=\
-\  --dir                                Target directory for extract/recreate
+\  --dir                                Target directory for extract
 
 main.opt.flags=\
 \  --flags=value                        Set the jimage flags to value
@@ -38,14 +33,8 @@
 main.opt.version=\
 \  --version                            Version information
 
-main.opt.configuration=\
-\  --configuration <path>               Path to properties file containing defaults\
-\ options for recreate
-
 main.command.files=\
 \  @<filename>                          Read options from file
-
-err.cannot.create.dir=cannot create directory: {0}
 err.cannot.read.file=cannot read file: {0}
 err.cannot.update.file=cannot update file: {0}
 err.file.not.found=cannot find file: {0}
@@ -53,12 +42,11 @@
 err.flags.not.int=--flags value not integer: {0}
 err.internal.error=internal error: {0} {1} {2}
 err.invalid.arg.for.option=invalid argument for option: {0}
-err.invalid.task=task must be extract|recreate|info|list|verify: {0}
-err.jimage.already.exists=jimage already exists: {0}
-err.jimage.not.specified=no jimage specified
+err.invalid.task=task must be extract|info|list|verify: {0}
 err.missing.arg=no value given for {0}
 err.not.a.dir=not a directory: {0}
 err.not.a.jimage=not a jimage file: {0}
-err.only.one.jimage=only one jimage should be specified
+err.no.jimage=no jimage provided
+err.not.a.task=not a valid task: {0}
 err.option.unsupported={0} not supported: {1}
 err.unknown.option=unknown option: {0}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImageLocationWriter.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImageLocationWriter.java	Thu Apr 28 23:08:16 2016 -0700
@@ -61,24 +61,32 @@
         String baseName;
         String extensionName = "";
 
-        int offset = fullName.indexOf('/', 1);
-        if (fullName.length() >= 2 && fullName.charAt(0) == '/' && offset != -1) {
-            moduleName = fullName.substring(1, offset);
-            fullName = fullName.substring(offset + 1);
-        }
+        if (fullName.startsWith("/modules/")) {
+            moduleName = "modules";
+            baseName = fullName.substring("/modules/".length());
+        } else if ( fullName.startsWith("/packages/")) {
+            moduleName = "packages";
+            baseName = fullName.substring("/packages/".length());
+        } else {
+            int offset = fullName.indexOf('/', 1);
+            if (fullName.length() >= 2 && fullName.charAt(0) == '/' && offset != -1) {
+                moduleName = fullName.substring(1, offset);
+                fullName = fullName.substring(offset + 1);
+            }
 
-        offset = fullName.lastIndexOf('/');
-        if (1 < offset) {
-            parentName = fullName.substring(0, offset);
-            fullName = fullName.substring(offset + 1);
-        }
+            offset = fullName.lastIndexOf('/');
+            if (1 < offset) {
+                parentName = fullName.substring(0, offset);
+                fullName = fullName.substring(offset + 1);
+            }
 
-        offset = fullName.lastIndexOf('.');
-        if (offset != -1) {
-            baseName = fullName.substring(0, offset);
-            extensionName = fullName.substring(offset + 1);
-        } else {
-            baseName = fullName;
+            offset = fullName.lastIndexOf('.');
+            if (offset != -1) {
+                baseName = fullName.substring(0, offset);
+                extensionName = fullName.substring(offset + 1);
+            } else {
+                baseName = fullName;
+            }
         }
 
         return new ImageLocationWriter(strings)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/packager/AppRuntimeImageBuilder.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2016, 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 jdk.tools.jlink.internal.packager;
+
+
+import jdk.tools.jlink.Jlink;
+import jdk.tools.jlink.builder.ImageBuilder;
+import jdk.tools.jlink.plugin.Plugin;
+import jdk.tools.jlink.builder.*;
+import jdk.tools.jlink.plugin.Pool;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.ResourceBundle;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+
+/**
+ * AppRuntimeImageBuilder is a private API used only by the Java Packager to generate
+ * a Java runtime image using jlink. AppRuntimeImageBuilder encapsulates the
+ * arguments that jlink requires to generate this image. To create the image call the
+ * build() method.
+ */
+public final class AppRuntimeImageBuilder {
+    private Path outputDir = null;
+    private List<Path> modulePath = null;
+    private Set<String> addModules = null;
+    private Set<String> limitModules = null;
+    private String excludeFileList = null;
+    private Map<String, String> userArguments = null;
+    private Boolean stripNativeCommands = null;
+
+    public AppRuntimeImageBuilder() {}
+
+    public void setOutputDir(Path value) {
+        outputDir = value;
+    }
+
+    public void setModulePath(List<Path> value) {
+        modulePath = value;
+    }
+
+    public void setAddModules(Set<String> value) {
+        addModules = value;
+    }
+
+    public void setLimitModules(Set<String> value) {
+        limitModules = value;
+    }
+
+    public void setExcludeFileList(String value) {
+        excludeFileList = value;
+    }
+
+    public void setStripNativeCommands(boolean value) {
+        stripNativeCommands = value;
+    }
+
+    public void setUserArguments(Map<String, String> value) {
+        userArguments = value;
+    }
+
+    public void build() throws IOException {
+        // jlink main arguments
+        Jlink.JlinkConfiguration jlinkConfig = new Jlink.JlinkConfiguration(
+            new File("").toPath(), // Unused
+            modulePath, addModules, limitModules);
+
+        // plugin configuration
+        List<Plugin> plugins = new ArrayList<Plugin>();
+
+        if (stripNativeCommands) {
+            plugins.add(Jlink.newPlugin(
+                        "strip-native-commands",
+                        Collections.singletonMap("strip-native-commands", "on"),
+                        null));
+        }
+
+        if (excludeFileList != null && !excludeFileList.isEmpty()) {
+            plugins.add(Jlink.newPlugin(
+                        "exclude-files",
+                        Collections.singletonMap("exclude-files", excludeFileList),
+                        null));
+        }
+
+        // add user supplied jlink arguments
+        for (Map.Entry<String, String> entry : userArguments.entrySet()) {
+            String key = entry.getKey();
+            String value = entry.getValue();
+            plugins.add(Jlink.newPlugin(key,
+                                        Collections.singletonMap(key, value),
+                                        null));
+        }
+
+        plugins.add(Jlink.newPlugin("installed-modules", Collections.emptyMap(), null));
+
+        // build the image
+        Jlink.PluginsConfiguration pluginConfig = new Jlink.PluginsConfiguration(
+            plugins, new DefaultImageBuilder(true, outputDir), null);
+        Jlink jlink = new Jlink();
+        jlink.build(jlinkConfig, pluginConfig);
+    }
+}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Pool.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Pool.java	Thu Apr 28 23:08:16 2016 -0700
@@ -226,7 +226,7 @@
      * <li>For jimage content: /{module name}/{package1}/.../{packageN}/{file
      * name}</li>
      * <li>For other files (shared lib, launchers, config, ...):/{module name}/
-     * {@literal bin|conf|native}/{dir1}>/.../{dirN}/{file name}</li>
+     * {@literal bin|conf|native}/{dir1}/.../{dirN}/{file name}</li>
      * </ul>
      */
     public static class ModuleData {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jstatd/share/classes/module-info.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+module jdk.jstatd {
+    requires java.rmi;
+    requires jdk.jvmstat;
+
+    // RMI needs to serialize types in this package
+    exports sun.jvmstat.monitor.remote to java.rmi;
+
+    provides sun.jvmstat.monitor.MonitoredHostService with sun.jvmstat.perfdata.monitor.protocol.rmi.MonitoredHostRmiService;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jstatd/share/classes/sun/jvmstat/monitor/remote/RemoteHost.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.jvmstat.monitor.remote;
+
+import sun.jvmstat.monitor.*;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.io.IOException;
+
+/**
+ * Remote Interface for discovering and attaching to remote
+ * monitorable Java Virtual Machines.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public interface RemoteHost extends Remote {
+
+    /**
+     * Remote method to attach to a remote HotSpot Java Virtual Machine
+     * identified by <code>vmid</code>.
+     *
+     * @param vmid The identifier for the target virtual machine.
+     * @return RemoteVm - A remote object for accessing the remote Java
+     *                    Virtual Machine.
+     *
+     * @throws MonitorException Thrown when any other error is encountered
+     *                          while communicating with the target virtual
+     *                          machine.
+     * @throws RemoteException
+     *
+     */
+    RemoteVm attachVm(int vmid, String mode) throws RemoteException,
+                                                    MonitorException;
+
+    /**
+     * Remote method to detach from a remote HotSpot Java Virtual Machine
+     * identified by <code>vmid</code>.
+     *
+     * @param rvm The remote object for the target Java Virtual
+     *            Machine.
+     *
+     * @throws MonitorException Thrown when any other error is encountered
+     *                          while communicating with the target virtual
+     *                          machine.
+     * @throws RemoteException
+     */
+    void detachVm(RemoteVm rvm) throws RemoteException, MonitorException;
+
+    /**
+     * Get a list of Local Virtual Machine Identifiers for the active
+     * Java Virtual Machine the remote system. A Local Virtual Machine
+     * Identifier is also known as an <em>lvmid</em>.
+     *
+     * @return int[] - A array of <em>lvmid</em>s.
+     * @throws MonitorException Thrown when any other error is encountered
+     *                          while communicating with the target virtual
+     *                          machine.
+     * @throws RemoteException
+     */
+    int[] activeVms() throws RemoteException, MonitorException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jstatd/share/classes/sun/jvmstat/monitor/remote/RemoteVm.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.jvmstat.monitor.remote;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+/**
+ * Interface for accessing the instrumentation exported by a
+ * Java Virtual Machine running on a remote host.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public interface RemoteVm extends Remote {
+
+    /**
+     * Interface to get the bytes associated with the instrumentation
+     * for the remote Java Virtual Machine.
+     *
+     * @return byte[] - a byte array containing the current bytes
+     *                  for the instrumentation exported by the
+     *                  remote Java Virtual Machine.
+     * @throws RemoteException Thrown on any communication error
+     */
+    byte[] getBytes() throws RemoteException;
+
+    /**
+     * Interface to get the size of the instrumentation buffer
+     * for the target Java Virtual Machine.
+     *
+     * @return int - the size of the instrumentation buffer for the
+     *               remote Java Virtual Machine.
+     * @throws RemoteException Thrown on any communication error
+     */
+    int getCapacity() throws RemoteException;
+
+    /**
+     * Interface to return the Local Virtual Machine Identifier for
+     * the remote Java Virtual Machine. The Local Virtual Machine
+     * Identifier is also know as the <em>lvmid</em>.
+     *
+     * @throws RemoteException Thrown on any communication error
+     */
+    int getLocalVmId() throws RemoteException;
+
+    /**
+     * Interface to detach from the remote Java Virtual Machine.
+     *
+     * @throws RemoteException Thrown on any communication error
+     */
+    void detach() throws RemoteException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jstatd/share/classes/sun/jvmstat/monitor/remote/package.html	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,39 @@
+<!doctype html public "-//IETF//DTD HTML/EN">
+<html>
+<head>
+<!--
+ 
+
+ Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ This code is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License version 2 only, as
+ published by the Free Software Foundation.  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.
+
+
+-->
+</head>
+<body bgcolor="white">
+<p>
+Provides interfaces supporting remote monitoring for instrumented
+HotSpot Java Virtual Machines.
+</p>
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jstatd/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostProvider.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.jvmstat.perfdata.monitor.protocol.rmi;
+
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.event.*;
+import sun.jvmstat.monitor.remote.*;
+import sun.jvmstat.perfdata.monitor.*;
+import java.util.*;
+import java.net.*;
+import java.io.*;
+import java.rmi.*;
+import java.util.HashMap;
+
+/**
+ * Concrete implementation of the MonitoredHost interface for the
+ * <em>rmi</em> protocol of the HotSpot PerfData monitoring implementation.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class MonitoredHostProvider extends MonitoredHost {
+    private static final String serverName = "/JStatRemoteHost";
+    private static final int DEFAULT_POLLING_INTERVAL = 1000;
+
+    private ArrayList<HostListener> listeners;
+    private NotifierTask task;
+    private HashSet<Integer> activeVms;
+    private RemoteVmManager vmManager;
+    private RemoteHost remoteHost;
+    private Timer timer;
+
+    /**
+     * Create a MonitoredHostProvider instance using the given HostIdentifier.
+     *
+     * @param hostId the host identifier for this MonitoredHost
+     * @throws MonitorException Thrown on any error encountered while
+     *                          communicating with the remote host.
+     */
+    public MonitoredHostProvider(HostIdentifier hostId)
+           throws MonitorException {
+        this.hostId = hostId;
+        this.listeners = new ArrayList<HostListener>();
+        this.interval = DEFAULT_POLLING_INTERVAL;
+        this.activeVms = new HashSet<Integer>();
+
+        String rmiName;
+        String sn = serverName;
+        String path = hostId.getPath();
+
+        if ((path != null) && (path.length() > 0)) {
+            sn = path;
+        }
+
+        if (hostId.getPort() != -1) {
+            rmiName = "rmi://" + hostId.getHost() + ":" + hostId.getPort() + sn;
+        } else {
+            rmiName = "rmi://" + hostId.getHost() + sn;
+        }
+
+        try {
+            remoteHost = (RemoteHost)Naming.lookup(rmiName);
+
+        } catch (RemoteException e) {
+            /*
+             * rmi registry not available
+             *
+             * Access control exceptions, where the rmi server refuses a
+             * connection based on policy file configuration, come through
+             * here on the client side. Unfortunately, the RemoteException
+             * doesn't contain enough information to determine the true cause
+             * of the exception. So, we have to output a rather generic message.
+             */
+            String message = "RMI Registry not available at "
+                             + hostId.getHost();
+
+            if (hostId.getPort() == -1) {
+                message = message + ":"
+                          + java.rmi.registry.Registry.REGISTRY_PORT;
+            } else {
+                message = message + ":" + hostId.getPort();
+            }
+
+            if (e.getMessage() != null) {
+                throw new MonitorException(message + "\n" + e.getMessage(), e);
+            } else {
+                throw new MonitorException(message, e);
+            }
+
+        } catch (NotBoundException e) {
+            // no server with given name
+            String message = e.getMessage();
+            if (message == null) message = rmiName;
+            throw new MonitorException("RMI Server " + message
+                                       + " not available", e);
+        } catch (MalformedURLException e) {
+            // this is a programming problem
+            e.printStackTrace();
+            throw new IllegalArgumentException("Malformed URL: " + rmiName);
+        }
+        this.vmManager = new RemoteVmManager(remoteHost);
+        this.timer = new Timer(true);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public MonitoredVm getMonitoredVm(VmIdentifier vmid)
+                       throws MonitorException {
+        return getMonitoredVm(vmid, DEFAULT_POLLING_INTERVAL);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public MonitoredVm getMonitoredVm(VmIdentifier vmid, int interval)
+                       throws MonitorException {
+        VmIdentifier nvmid = null;
+        try {
+            nvmid = hostId.resolve(vmid);
+            RemoteVm rvm = remoteHost.attachVm(vmid.getLocalVmId(),
+                                               vmid.getMode());
+            RemoteMonitoredVm rmvm = new RemoteMonitoredVm(rvm, nvmid, timer,
+                                                           interval);
+            rmvm.attach();
+            return rmvm;
+
+        } catch (RemoteException e) {
+            throw new MonitorException("Remote Exception attaching to "
+                                       + nvmid.toString(), e);
+        } catch (URISyntaxException e) {
+            /*
+             * the VmIdentifier is expected to be a valid and should resolve
+             * easonably against the host identifier. A URISyntaxException
+             * here is most likely a programming error.
+             */
+            throw new IllegalArgumentException("Malformed URI: "
+                                               + vmid.toString(), e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void detach(MonitoredVm vm) throws MonitorException {
+        RemoteMonitoredVm rmvm = (RemoteMonitoredVm)vm;
+        rmvm.detach();
+        try {
+            remoteHost.detachVm(rmvm.getRemoteVm());
+
+        } catch (RemoteException e) {
+            throw new MonitorException("Remote Exception detaching from "
+                                       + vm.getVmIdentifier().toString(), e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void addHostListener(HostListener listener) {
+        synchronized(listeners) {
+            listeners.add(listener);
+            if (task == null) {
+                task = new NotifierTask();
+                timer.schedule(task, 0, interval);
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void removeHostListener(HostListener listener) {
+        /*
+         * XXX: if a disconnect method is added, make sure it calls
+         * this method to unregister this object from the watcher. otherwise,
+         * an unused MonitoredHostProvider instance may go uncollected.
+         */
+        synchronized(listeners) {
+            listeners.remove(listener);
+            if (listeners.isEmpty() && (task != null)) {
+                task.cancel();
+                task = null;
+            }
+        }
+    }
+
+    public void setInterval(int newInterval) {
+        synchronized(listeners) {
+            if (newInterval == interval) {
+                return;
+            }
+
+            int oldInterval = interval;
+            super.setInterval(newInterval);
+
+            if (task != null) {
+                task.cancel();
+                NotifierTask oldTask = task;
+                task = new NotifierTask();
+                CountedTimerTaskUtils.reschedule(timer, oldTask, task,
+                                                 oldInterval, newInterval);
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Set<Integer> activeVms() throws MonitorException {
+        return vmManager.activeVms();
+    }
+
+    /**
+     * Fire VmStatusChangeEvent events to HostListener objects
+     *
+     * @param active Set of Integer objects containing the local
+     *               Vm Identifiers of the active JVMs
+     * @param started Set of Integer objects containing the local
+     *                Vm Identifiers of new JVMs started since last
+     *                interval.
+     * @param terminated Set of Integer objects containing the local
+     *                   Vm Identifiers of terminated JVMs since last
+     *                   interval.
+     */
+    @SuppressWarnings("unchecked") // Cast of result of clone
+    private void fireVmStatusChangedEvents(Set<Integer> active, Set<Integer> started,
+                                           Set<Integer> terminated) {
+        ArrayList<HostListener> registered = null;
+        VmStatusChangeEvent ev = null;
+
+        synchronized(listeners) {
+            registered = (ArrayList)listeners.clone();
+        }
+
+        for (Iterator<HostListener> i = registered.iterator(); i.hasNext(); /* empty */) {
+            HostListener l = i.next();
+            if (ev == null) {
+                ev = new VmStatusChangeEvent(this, active, started, terminated);
+            }
+            l.vmStatusChanged(ev);
+        }
+    }
+
+    /**
+     * Fire hostDisconnectEvent events.
+     */
+    @SuppressWarnings("unchecked") // Cast of result of clone
+    void fireDisconnectedEvents() {
+        ArrayList<HostListener> registered = null;
+        HostEvent ev = null;
+
+        synchronized(listeners) {
+            registered = (ArrayList)listeners.clone();
+        }
+
+        for (Iterator<HostListener> i = registered.iterator(); i.hasNext(); /* empty */) {
+            HostListener l = i.next();
+            if (ev == null) {
+                ev = new HostEvent(this);
+            }
+            l.disconnected(ev);
+        }
+    }
+
+    /**
+     * class to poll the remote machine and generate local event notifications.
+     */
+    private class NotifierTask extends CountedTimerTask {
+        public void run() {
+            super.run();
+
+            // save the last set of active JVMs
+            Set<Integer> lastActiveVms = activeVms;
+
+            try {
+                // get the current set of active JVMs
+                activeVms = (HashSet<Integer>)vmManager.activeVms();
+
+            } catch (MonitorException e) {
+                // XXX: use logging api
+                System.err.println("MonitoredHostProvider: polling task "
+                                   + "caught MonitorException:");
+                e.printStackTrace();
+
+                // mark the HostManager as errored and notify listeners
+                setLastException(e);
+                fireDisconnectedEvents();
+            }
+
+            if (activeVms.isEmpty()) {
+                return;
+            }
+
+            Set<Integer> startedVms = new HashSet<>();
+            Set<Integer> terminatedVms = new HashSet<>();
+
+            for (Iterator<Integer> i = activeVms.iterator(); i.hasNext(); /* empty */ ) {
+                Integer vmid = i.next();
+                if (!lastActiveVms.contains(vmid)) {
+                    // a new file has been detected, add to set
+                    startedVms.add(vmid);
+                }
+            }
+
+            for (Iterator<Integer> i = lastActiveVms.iterator(); i.hasNext();
+                    /* empty */ ) {
+                Integer o = i.next();
+                if (!activeVms.contains(o)) {
+                    // JVM has terminated, remove it from the active list
+                    terminatedVms.add(o);
+                }
+            }
+
+            if (!startedVms.isEmpty() || !terminatedVms.isEmpty()) {
+                fireVmStatusChangedEvents(activeVms, startedVms, terminatedVms);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jstatd/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostRmiService.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.jvmstat.perfdata.monitor.protocol.rmi;
+
+import sun.jvmstat.monitor.HostIdentifier;
+import sun.jvmstat.monitor.MonitorException;
+import sun.jvmstat.monitor.MonitoredHost;
+import sun.jvmstat.monitor.MonitoredHostService;
+
+public final class MonitoredHostRmiService implements MonitoredHostService {
+
+    @Override
+    public MonitoredHost getMonitoredHost(HostIdentifier hostId) throws MonitorException {
+        return new MonitoredHostProvider(hostId);
+    }
+
+    @Override
+    public String getScheme() {
+        return "rmi";
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jstatd/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/PerfDataBuffer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.jvmstat.perfdata.monitor.protocol.rmi;
+
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.remote.*;
+import sun.jvmstat.perfdata.monitor.*;
+import java.io.*;
+import java.rmi.RemoteException;
+import java.nio.ByteBuffer;
+
+/**
+ * The concrete PerfDataBuffer implementation for the <em>rmi:</em>
+ * protocol for the HotSpot PerfData monitoring implementation.
+ * <p>
+ * This class is responsible for acquiring the instrumentation buffer
+ * data for a remote target HotSpot Java Virtual Machine.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class PerfDataBuffer extends AbstractPerfDataBuffer {
+
+    private RemoteVm rvm;
+
+    /**
+     * Create a PerfDataBuffer instance for accessing the specified
+     * instrumentation buffer.
+     *
+     * @param rvm the proxy to the remote MonitredVm object
+     * @param lvmid the local Java Virtual Machine Identifier of the
+     *              remote target.
+     *
+     * @throws MonitorException
+     */
+    public PerfDataBuffer(RemoteVm rvm, int lvmid) throws MonitorException {
+
+        this.rvm = rvm;
+        try {
+            ByteBuffer buffer = ByteBuffer.allocate(rvm.getCapacity());
+            sample(buffer);
+            createPerfDataBuffer(buffer, lvmid);
+
+        } catch (RemoteException e) {
+            throw new MonitorException("Could not read data for remote JVM "
+                                       + lvmid, e);
+        }
+    }
+
+    /**
+     * Get a copy of the remote instrumentation buffer.
+     *<p>
+     * The data in the remote instrumentation buffer is copied into
+     * the local byte buffer.
+     *
+     * @param buffer the buffer to receive the copy of the remote
+     *               instrumentation buffer.
+     * @throws RemoteException Thrown on any communications errors with
+     *                         the remote system.
+     */
+    public void sample(ByteBuffer buffer) throws RemoteException {
+        assert buffer != null;
+        assert rvm != null;
+        synchronized(buffer) {
+            buffer.clear();
+            buffer.put(rvm.getBytes());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jstatd/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteMonitoredVm.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.jvmstat.perfdata.monitor.protocol.rmi;
+
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.event.*;
+import sun.jvmstat.monitor.remote.*;
+import sun.jvmstat.perfdata.monitor.*;
+import java.lang.reflect.*;
+import java.util.*;
+import java.io.*;
+import java.nio.ByteBuffer;
+import java.rmi.*;
+
+/**
+ * Concrete implementation of the AbstractMonitoredVm class for the
+ * <em>rmi:</em> protocol for the HotSpot PerfData monitoring implementation.
+ * <p>
+ * This class provides the ability to acquire to the instrumentation buffer
+ * of a live, remote target Java Virtual Machine through an RMI server.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class RemoteMonitoredVm extends AbstractMonitoredVm {
+
+    private ArrayList<VmListener> listeners;
+    private NotifierTask notifierTask;
+    private SamplerTask samplerTask;
+    private Timer timer;
+
+    private RemoteVm rvm;
+    private ByteBuffer updateBuffer;
+
+    /**
+     * Create a RemoteMonitoredVm instance.
+     *
+     * @param rvm the proxy to the remote MonitoredVm instance.
+     * @param vmid the vm identifier specifying the remot target JVM
+     * @param timer the timer used to run polling tasks
+     * @param interval the sampling interval
+     */
+    public RemoteMonitoredVm(RemoteVm rvm, VmIdentifier vmid,
+                             Timer timer, int interval)
+           throws MonitorException {
+        super(vmid, interval);
+        this.rvm = rvm;
+        pdb = new PerfDataBuffer(rvm, vmid.getLocalVmId());
+        this.listeners = new ArrayList<VmListener>();
+        this.timer = timer;
+    }
+
+    /**
+     * Method to attach to the remote MonitoredVm.
+     */
+    public void attach() throws MonitorException {
+        updateBuffer = pdb.getByteBuffer().duplicate();
+
+        // if continuous sampling is requested, register with the sampler thread
+        if (interval > 0) {
+            samplerTask = new SamplerTask();
+            timer.schedule(samplerTask, 0, interval);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void detach() {
+        try {
+            if (interval > 0) {
+                if (samplerTask != null) {
+                    samplerTask.cancel();
+                    samplerTask = null;
+                }
+                if (notifierTask != null) {
+                    notifierTask.cancel();
+                    notifierTask = null;
+                }
+                sample();
+            }
+        } catch (RemoteException e) {
+            // XXX: - use logging api? throw an exception instead?
+            System.err.println("Could not read data for remote JVM " + vmid);
+            e.printStackTrace();
+
+        } finally {
+            super.detach();
+        }
+    }
+
+    /**
+     * Get a copy of the remote instrumentation buffer.
+     *<p>
+     * The data in the remote instrumentation buffer is copied into
+     * a local byte buffer.
+     *
+     * @throws RemoteException Thrown on any communications errors with
+     *                         the remote system.
+     */
+    public void sample() throws RemoteException {
+        assert updateBuffer != null;
+        ((PerfDataBuffer)pdb).sample(updateBuffer);
+    }
+
+    /**
+     * Get the proxy to the remote MonitoredVm.
+     *
+     * @return RemoteVm - the proxy to the remote MonitoredVm.
+     */
+    public RemoteVm getRemoteVm() {
+        return rvm;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void addVmListener(VmListener l) {
+        synchronized(listeners) {
+            listeners.add(l);
+            if (notifierTask == null) {
+                notifierTask = new NotifierTask();
+                timer.schedule(notifierTask, 0, interval);
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void removeVmListener(VmListener l) {
+        synchronized(listeners) {
+            listeners.remove(l);
+            if (listeners.isEmpty() && (notifierTask != null)) {
+                notifierTask.cancel();
+                notifierTask = null;
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setInterval(int newInterval) {
+        synchronized(listeners) {
+            if (newInterval == interval) {
+                return;
+            }
+
+            int oldInterval = interval;
+            super.setInterval(newInterval);
+
+            if (samplerTask != null) {
+                samplerTask.cancel();
+                SamplerTask oldSamplerTask = samplerTask;
+                samplerTask = new SamplerTask();
+                CountedTimerTaskUtils.reschedule(timer, oldSamplerTask,
+                                                 samplerTask, oldInterval,
+                                                 newInterval);
+            }
+            if (notifierTask != null) {
+                notifierTask.cancel();
+                NotifierTask oldNotifierTask = notifierTask;
+                notifierTask = new NotifierTask();
+                CountedTimerTaskUtils.reschedule(timer, oldNotifierTask,
+                                                 notifierTask, oldInterval,
+                                                 newInterval);
+            }
+        }
+    }
+
+    /**
+     * Fire MonitoredVmStructureChanged events.
+     *
+     * @param inserted List of Monitor objects inserted.
+     * @param removed List of Monitor objects removed.
+     */
+    @SuppressWarnings("unchecked") // Cast of result of clone
+    void fireMonitorStatusChangedEvents(List<Monitor> inserted, List<Monitor> removed) {
+        ArrayList<VmListener> registered = null;
+        MonitorStatusChangeEvent ev = null;
+
+        synchronized(listeners) {
+            registered = (ArrayList)listeners.clone();
+        }
+
+        for (Iterator<VmListener> i = registered.iterator(); i.hasNext(); /* empty */) {
+            VmListener l = i.next();
+            if (ev == null) {
+                ev = new MonitorStatusChangeEvent(this, inserted, removed);
+            }
+            l.monitorStatusChanged(ev);
+        }
+    }
+
+    /**
+     * Fire MonitoredVmStructureChanged events.
+     */
+    @SuppressWarnings("unchecked") // Cast of result of clone
+    void fireMonitorsUpdatedEvents() {
+        ArrayList<VmListener> registered = null;
+        VmEvent ev = null;
+
+        synchronized(listeners) {
+            registered = (ArrayList)listeners.clone();
+        }
+
+        for (Iterator<VmListener> i = registered.iterator(); i.hasNext(); /* empty */) {
+            VmListener l = i.next();
+            if (ev == null) {
+                ev = new VmEvent(this);
+            }
+            l.monitorsUpdated(ev);
+        }
+    }
+
+    /*
+     * Timer Tasks. There are two separate timer tasks here. The SamplerTask
+     * is active whenever we are attached to the remote JVM with a periodic
+     * sampling interval > 0. The NotifierTask is only active if a VmListener
+     * has registered with this RemoteMonitoredVm instance. Also, in the future
+     * we may want to run these tasks at different intervals. Currently,
+     * they run at the same interval and some significant work may
+     * need to be done to complete the separation of these two intervals.
+     */
+
+    /**
+     * Class to periodically check the state of the defined monitors
+     * for the remote MonitoredVm instance and to notify listeners of
+     * any detected changes.
+     */
+    private class NotifierTask extends CountedTimerTask {
+        public void run() {
+            super.run();
+            try {
+                MonitorStatus status = getMonitorStatus();
+
+                List<Monitor> inserted = status.getInserted();
+                List<Monitor> removed = status.getRemoved();
+
+                if (!inserted.isEmpty() || !removed.isEmpty()) {
+                    fireMonitorStatusChangedEvents(inserted, removed);
+                }
+            } catch (MonitorException e) {
+                // XXX: use logging api? fire disconnect events? mark errored?
+                // fireDisconnectedEvents();
+                System.err.println("Exception updating monitors for "
+                                   + getVmIdentifier());
+                e.printStackTrace();
+                // XXX: should we cancle the notifierTask here?
+                // this.cancel();
+            }
+        }
+    }
+
+    /**
+     * Class to periodically sample the remote instrumentation byte buffer
+     * and refresh the local copy. Registered listeners are notified of
+     * the completion of a sampling event.
+     */
+    private class SamplerTask extends CountedTimerTask {
+        public void run() {
+            super.run();
+            try {
+                sample();
+                fireMonitorsUpdatedEvents();
+
+            } catch (RemoteException e) {
+                // XXX: use logging api, mark vm as errored.
+                System.err.println("Exception taking sample for "
+                                   + getVmIdentifier());
+                e.printStackTrace();
+                this.cancel();
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jstatd/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteVmManager.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.jvmstat.perfdata.monitor.protocol.rmi;
+
+import java.util.*;
+import java.util.regex.*;
+import java.io.*;
+import java.rmi.RemoteException;
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.event.*;
+import sun.jvmstat.monitor.remote.*;
+
+/**
+ * Class for managing the RemoteMonitoredVm instances on a remote system.
+ * <p>
+ * This class is responsible for the mechanism that detects the active
+ * HotSpot Java Virtual Machines on the remote host and possibly for a
+ * specific user. The ability to detect all possible HotSpot Java Virtual
+ * Machines on the remote host may be limited by the permissions of the
+ * principal running the RMI server application on the remote host.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class RemoteVmManager {
+
+    private RemoteHost remoteHost;
+    private String user;
+
+    /**
+     * Creates a RemoteVmManager instance for the remote system.
+     * <p>
+     * Manages RemoteMonitordVm instances for which the principal
+     * running the remote server has appropriate permissions.
+     *
+     * @param remoteHost the remote proxy object to the RMI server on
+     *                   the remote system.
+     */
+    public RemoteVmManager(RemoteHost remoteHost) {
+        this(remoteHost, null);
+    }
+
+    /**
+     * Creates a RemoteVmManager instance for the given user.
+     * <p>
+     * Manages RemoteMonitoredVm instances for all remote Java Virtual
+     * machines owned by the specified user on the remote system. The
+     * RMI server on the remote system must have the appropriate permissions
+     * to access the named users Java Virtual Machines.
+     *
+     * @param remoteHost the remote proxy object to the RMI server on
+     *                   the remote system.
+     * @param user the name of the user
+     */
+    public RemoteVmManager(RemoteHost remoteHost, String user) {
+        this.user = user;
+        this.remoteHost = remoteHost;
+    }
+
+    /**
+     * Return the current set of monitorable Java Virtual Machines.
+     * <p>
+     * The set returned by this method depends on the user name passed
+     * to the constructor. If no user name was specified, then this
+     * method will return all candidate JVMs on the system. Otherwise,
+     * only the JVMs for the given user will be returned. This assumes
+     * that the RMI server process has the appropriate permissions to
+     * access the target set of JVMs.
+     *
+     * @return Set - the Set of monitorable Java Virtual Machines
+     */
+    public Set<Integer> activeVms() throws MonitorException {
+        int[] active = null;
+
+        try {
+            active = remoteHost.activeVms();
+
+        } catch (RemoteException e) {
+            throw new MonitorException("Error communicating with remote host: "
+                                       + e.getMessage(), e);
+        }
+
+        Set<Integer> activeSet = new HashSet<Integer>(active.length);
+
+        for (int i = 0; i < active.length; i++) {
+            activeSet.add(active[i]);
+        }
+
+        return activeSet;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jstatd/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/package.html	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,47 @@
+<!doctype html public "-//IETF//DTD HTML/EN">
+<html>
+<head>
+<!--
+ 
+
+ Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ This code is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License version 2 only, as
+ published by the Free Software Foundation.  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.
+
+-->
+</head>
+<body bgcolor="white">
+<p>
+Provides the implementation classes for the <em>rmi:</em> protocol for
+the HotSpot PerfData instrumentation buffer monitoring implementation.
+</p>
+<p>
+The <em>rmi:</em> protocol is the default protocol for the PerfData
+implementation when a hostname is specified as part of a HostIdentifier
+or VMIdentifier. It communicates with an RMI server on the remote machine
+that provides functions to get a list of available Java Virtual Machines
+and to acquire a copy of a Java Virtual Machine's instrumentation buffer.
+The RMI server may or may not use the PerfData implementation on the
+remote host to acquire this information. The <em>jstatd</em> server
+provides a PerfData implementation of the RMI server.
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jstatd/share/classes/sun/tools/jstatd/Jstatd.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.tools.jstatd;
+
+import java.rmi.*;
+import java.rmi.server.*;
+import java.rmi.registry.Registry;
+import java.rmi.registry.LocateRegistry;
+import java.net.MalformedURLException;
+import sun.jvmstat.monitor.remote.*;
+
+/**
+ * Application providing remote access to the jvmstat instrumentation
+ * exported by local Java Virtual Machine processes. Remote access is
+ * provided through an RMI interface.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class Jstatd {
+
+    private static Registry registry;
+    private static int port = -1;
+    private static boolean startRegistry = true;
+
+    private static void printUsage() {
+        System.err.println("usage: jstatd [-nr] [-p port] [-n rminame]");
+    }
+
+    static void bind(String name, RemoteHostImpl remoteHost)
+                throws RemoteException, MalformedURLException, Exception {
+
+        try {
+            Naming.rebind(name, remoteHost);
+        } catch (java.rmi.ConnectException e) {
+            /*
+             * either the registry is not running or we cannot contact it.
+             * start an internal registry if requested.
+             */
+            if (startRegistry && registry == null) {
+                int localport = (port < 0) ? Registry.REGISTRY_PORT : port;
+                registry = LocateRegistry.createRegistry(localport);
+                bind(name, remoteHost);
+            } else {
+                throw e;
+            }
+        }
+    }
+
+    @SuppressWarnings("deprecation") // Use of RMISecurityManager
+    public static void main(String[] args) {
+        String rminame = null;
+        int argc = 0;
+
+        for ( ; (argc < args.length) && (args[argc].startsWith("-")); argc++) {
+            String arg = args[argc];
+
+            if (arg.compareTo("-nr") == 0) {
+                startRegistry = false;
+            } else if (arg.startsWith("-p")) {
+                if (arg.compareTo("-p") != 0) {
+                    port = Integer.parseInt(arg.substring(2));
+                } else {
+                  argc++;
+                  if (argc >= args.length) {
+                      printUsage();
+                      System.exit(1);
+                  }
+                  port = Integer.parseInt(args[argc]);
+                }
+            } else if (arg.startsWith("-n")) {
+                if (arg.compareTo("-n") != 0) {
+                    rminame = arg.substring(2);
+                } else {
+                    argc++;
+                    if (argc >= args.length) {
+                        printUsage();
+                        System.exit(1);
+                    }
+                    rminame = args[argc];
+                }
+            } else {
+                printUsage();
+                System.exit(1);
+            }
+        }
+
+        if (argc < args.length) {
+            printUsage();
+            System.exit(1);
+        }
+
+        if (System.getSecurityManager() == null) {
+            System.setSecurityManager(new RMISecurityManager());
+        }
+
+        StringBuilder name = new StringBuilder();
+
+        if (port >= 0) {
+            name.append("//:").append(port);
+        }
+
+        if (rminame == null) {
+            rminame = "JStatRemoteHost";
+        }
+
+        name.append("/").append(rminame);
+
+        try {
+            // use 1.5.0 dynamically generated subs.
+            System.setProperty("java.rmi.server.ignoreSubClasses", "true");
+            RemoteHostImpl remoteHost = new RemoteHostImpl();
+            RemoteHost stub = (RemoteHost) UnicastRemoteObject.exportObject(
+                    remoteHost, 0);
+            bind(name.toString(), remoteHost);
+            System.out.println("jstatd started (bound to " + name.toString() + ")");
+            System.out.flush();
+        } catch (MalformedURLException e) {
+            if (rminame != null) {
+                System.out.println("Bad RMI server name: " + rminame);
+            } else {
+                System.out.println("Bad RMI URL: " + name);
+            }
+            e.printStackTrace(System.out);
+            System.exit(1);
+        } catch (java.rmi.ConnectException e) {
+            // could not attach to or create a registry
+            System.out.println("Could not contact RMI registry");
+            e.printStackTrace(System.out);
+            System.exit(1);
+        } catch (RemoteException e) {
+            System.out.println("Could not bind " + name + " to RMI Registry");
+            e.printStackTrace(System.out);
+            System.exit(1);
+        } catch (Exception e) {
+            System.out.println("Could not create remote object");
+            e.printStackTrace(System.out);
+            System.exit(1);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jstatd/share/classes/sun/tools/jstatd/RemoteHostImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.tools.jstatd;
+
+import java.util.*;
+import java.nio.*;
+import java.io.*;
+import java.net.*;
+import java.rmi.*;
+import java.rmi.server.*;
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.event.*;
+import sun.jvmstat.monitor.remote.*;
+
+/**
+ * Concrete implementation of the RemoteHost interface for the HotSpot
+ * PerfData <em>rmi:</em> protocol.
+ * <p>
+ * This class provides remote access to the instrumentation exported
+ * by HotSpot Java Virtual Machines through the PerfData shared memory
+ * interface.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class RemoteHostImpl implements RemoteHost, HostListener {
+
+    private MonitoredHost monitoredHost;
+    private Set<Integer> activeVms;
+
+    public RemoteHostImpl() throws MonitorException {
+        try {
+            monitoredHost = MonitoredHost.getMonitoredHost("localhost");
+        } catch (URISyntaxException e) { }
+
+        activeVms = monitoredHost.activeVms();
+        monitoredHost.addHostListener(this);
+    }
+
+    public RemoteVm attachVm(int lvmid, String mode)
+                    throws RemoteException, MonitorException {
+        Integer v = lvmid;
+        RemoteVm stub = null;
+        StringBuilder sb = new StringBuilder();
+
+        sb.append("local://").append(lvmid).append("@localhost");
+        if (mode != null) {
+            sb.append("?mode=").append(mode);
+        }
+
+        String vmidStr = sb.toString();
+
+        try {
+            VmIdentifier vmid = new VmIdentifier(vmidStr);
+            MonitoredVm mvm = monitoredHost.getMonitoredVm(vmid);
+            RemoteVmImpl rvm = new RemoteVmImpl((BufferedMonitoredVm)mvm);
+            stub = (RemoteVm) UnicastRemoteObject.exportObject(rvm, 0);
+        }
+        catch (URISyntaxException e) {
+            throw new RuntimeException("Malformed VmIdentifier URI: "
+                                       + vmidStr, e);
+        }
+        return stub;
+    }
+
+    public void detachVm(RemoteVm rvm) throws RemoteException {
+        rvm.detach();
+    }
+
+    public int[] activeVms() throws MonitorException {
+        Object[] vms = null;
+        int[] vmids = null;
+
+        vms = monitoredHost.activeVms().toArray();
+        vmids = new int[vms.length];
+
+        for (int i = 0; i < vmids.length; i++) {
+            vmids[i] = ((Integer)vms[i]).intValue();
+        }
+        return vmids;
+    }
+
+    public void vmStatusChanged(VmStatusChangeEvent ev) {
+        synchronized(this.activeVms) {
+            activeVms.retainAll(ev.getActive());
+        }
+    }
+
+    public void disconnected(HostEvent ev) {
+        // we only monitor the local host, so this event shouldn't occur.
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jstatd/share/classes/sun/tools/jstatd/RemoteVmImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.tools.jstatd;
+
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.remote.*;
+
+/**
+ * Concrete implementation of the RemoteVm interface for the HotSpot PerfData
+ * shared memory implementation of the jvmstat monitoring APIs. This class
+ * providing remote access to the instrumentation exported by a local HotSpot
+ * Java Virtual Machine. The instrumentation buffer is shipped in whole to
+ * the remote machine, which is responsible for parsing and provide access
+ * to the contained data.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class RemoteVmImpl implements RemoteVm {
+
+    private BufferedMonitoredVm mvm;
+
+    RemoteVmImpl(BufferedMonitoredVm mvm) {
+        this.mvm = mvm;
+    }
+
+    public byte[] getBytes() {
+        return mvm.getBytes();
+    }
+
+    public int getCapacity() {
+        return mvm.getCapacity();
+    }
+
+    public void detach() {
+        mvm.detach();
+    }
+
+    public int getLocalVmId() {
+        return mvm.getVmIdentifier().getLocalVmId();
+    }
+}
--- a/jdk/src/jdk.jvmstat.rmi/share/classes/module-info.java	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2015, 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.
- */
-
-module jdk.jvmstat.rmi {
-    requires java.rmi;
-    requires jdk.jvmstat;
-
-    // RMI needs to serialize types in this package
-    exports sun.jvmstat.monitor.remote to java.rmi;
-
-    provides sun.jvmstat.monitor.MonitoredHostService with sun.jvmstat.perfdata.monitor.protocol.rmi.MonitoredHostRmiService;
-}
-
--- a/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/RemoteHost.java	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.jvmstat.monitor.remote;
-
-import sun.jvmstat.monitor.*;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.io.IOException;
-
-/**
- * Remote Interface for discovering and attaching to remote
- * monitorable Java Virtual Machines.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public interface RemoteHost extends Remote {
-
-    /**
-     * Remote method to attach to a remote HotSpot Java Virtual Machine
-     * identified by <code>vmid</code>.
-     *
-     * @param vmid The identifier for the target virtual machine.
-     * @return RemoteVm - A remote object for accessing the remote Java
-     *                    Virtual Machine.
-     *
-     * @throws MonitorException Thrown when any other error is encountered
-     *                          while communicating with the target virtual
-     *                          machine.
-     * @throws RemoteException
-     *
-     */
-    RemoteVm attachVm(int vmid, String mode) throws RemoteException,
-                                                    MonitorException;
-
-    /**
-     * Remote method to detach from a remote HotSpot Java Virtual Machine
-     * identified by <code>vmid</code>.
-     *
-     * @param rvm The remote object for the target Java Virtual
-     *            Machine.
-     *
-     * @throws MonitorException Thrown when any other error is encountered
-     *                          while communicating with the target virtual
-     *                          machine.
-     * @throws RemoteException
-     */
-    void detachVm(RemoteVm rvm) throws RemoteException, MonitorException;
-
-    /**
-     * Get a list of Local Virtual Machine Identifiers for the active
-     * Java Virtual Machine the remote system. A Local Virtual Machine
-     * Identifier is also known as an <em>lvmid</em>.
-     *
-     * @return int[] - A array of <em>lvmid</em>s.
-     * @throws MonitorException Thrown when any other error is encountered
-     *                          while communicating with the target virtual
-     *                          machine.
-     * @throws RemoteException
-     */
-    int[] activeVms() throws RemoteException, MonitorException;
-}
--- a/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/RemoteVm.java	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.jvmstat.monitor.remote;
-
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-/**
- * Interface for accessing the instrumentation exported by a
- * Java Virtual Machine running on a remote host.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public interface RemoteVm extends Remote {
-
-    /**
-     * Interface to get the bytes associated with the instrumentation
-     * for the remote Java Virtual Machine.
-     *
-     * @return byte[] - a byte array containing the current bytes
-     *                  for the instrumentation exported by the
-     *                  remote Java Virtual Machine.
-     * @throws RemoteException Thrown on any communication error
-     */
-    byte[] getBytes() throws RemoteException;
-
-    /**
-     * Interface to get the size of the instrumentation buffer
-     * for the target Java Virtual Machine.
-     *
-     * @return int - the size of the instrumentation buffer for the
-     *               remote Java Virtual Machine.
-     * @throws RemoteException Thrown on any communication error
-     */
-    int getCapacity() throws RemoteException;
-
-    /**
-     * Interface to return the Local Virtual Machine Identifier for
-     * the remote Java Virtual Machine. The Local Virtual Machine
-     * Identifier is also know as the <em>lvmid</em>.
-     *
-     * @throws RemoteException Thrown on any communication error
-     */
-    int getLocalVmId() throws RemoteException;
-
-    /**
-     * Interface to detach from the remote Java Virtual Machine.
-     *
-     * @throws RemoteException Thrown on any communication error
-     */
-    void detach() throws RemoteException;
-}
--- a/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/package.html	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-<!doctype html public "-//IETF//DTD HTML/EN">
-<html>
-<head>
-<!--
- 
-
- Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-
- This code is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License version 2 only, as
- published by the Free Software Foundation.  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.
-
-
--->
-</head>
-<body bgcolor="white">
-<p>
-Provides interfaces supporting remote monitoring for instrumented
-HotSpot Java Virtual Machines.
-</p>
-</body>
-</html>
--- a/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostProvider.java	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,343 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.jvmstat.perfdata.monitor.protocol.rmi;
-
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.event.*;
-import sun.jvmstat.monitor.remote.*;
-import sun.jvmstat.perfdata.monitor.*;
-import java.util.*;
-import java.net.*;
-import java.io.*;
-import java.rmi.*;
-import java.util.HashMap;
-
-/**
- * Concrete implementation of the MonitoredHost interface for the
- * <em>rmi</em> protocol of the HotSpot PerfData monitoring implementation.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class MonitoredHostProvider extends MonitoredHost {
-    private static final String serverName = "/JStatRemoteHost";
-    private static final int DEFAULT_POLLING_INTERVAL = 1000;
-
-    private ArrayList<HostListener> listeners;
-    private NotifierTask task;
-    private HashSet<Integer> activeVms;
-    private RemoteVmManager vmManager;
-    private RemoteHost remoteHost;
-    private Timer timer;
-
-    /**
-     * Create a MonitoredHostProvider instance using the given HostIdentifier.
-     *
-     * @param hostId the host identifier for this MonitoredHost
-     * @throws MonitorException Thrown on any error encountered while
-     *                          communicating with the remote host.
-     */
-    public MonitoredHostProvider(HostIdentifier hostId)
-           throws MonitorException {
-        this.hostId = hostId;
-        this.listeners = new ArrayList<HostListener>();
-        this.interval = DEFAULT_POLLING_INTERVAL;
-        this.activeVms = new HashSet<Integer>();
-
-        String rmiName;
-        String sn = serverName;
-        String path = hostId.getPath();
-
-        if ((path != null) && (path.length() > 0)) {
-            sn = path;
-        }
-
-        if (hostId.getPort() != -1) {
-            rmiName = "rmi://" + hostId.getHost() + ":" + hostId.getPort() + sn;
-        } else {
-            rmiName = "rmi://" + hostId.getHost() + sn;
-        }
-
-        try {
-            remoteHost = (RemoteHost)Naming.lookup(rmiName);
-
-        } catch (RemoteException e) {
-            /*
-             * rmi registry not available
-             *
-             * Access control exceptions, where the rmi server refuses a
-             * connection based on policy file configuration, come through
-             * here on the client side. Unfortunately, the RemoteException
-             * doesn't contain enough information to determine the true cause
-             * of the exception. So, we have to output a rather generic message.
-             */
-            String message = "RMI Registry not available at "
-                             + hostId.getHost();
-
-            if (hostId.getPort() == -1) {
-                message = message + ":"
-                          + java.rmi.registry.Registry.REGISTRY_PORT;
-            } else {
-                message = message + ":" + hostId.getPort();
-            }
-
-            if (e.getMessage() != null) {
-                throw new MonitorException(message + "\n" + e.getMessage(), e);
-            } else {
-                throw new MonitorException(message, e);
-            }
-
-        } catch (NotBoundException e) {
-            // no server with given name
-            String message = e.getMessage();
-            if (message == null) message = rmiName;
-            throw new MonitorException("RMI Server " + message
-                                       + " not available", e);
-        } catch (MalformedURLException e) {
-            // this is a programming problem
-            e.printStackTrace();
-            throw new IllegalArgumentException("Malformed URL: " + rmiName);
-        }
-        this.vmManager = new RemoteVmManager(remoteHost);
-        this.timer = new Timer(true);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public MonitoredVm getMonitoredVm(VmIdentifier vmid)
-                       throws MonitorException {
-        return getMonitoredVm(vmid, DEFAULT_POLLING_INTERVAL);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public MonitoredVm getMonitoredVm(VmIdentifier vmid, int interval)
-                       throws MonitorException {
-        VmIdentifier nvmid = null;
-        try {
-            nvmid = hostId.resolve(vmid);
-            RemoteVm rvm = remoteHost.attachVm(vmid.getLocalVmId(),
-                                               vmid.getMode());
-            RemoteMonitoredVm rmvm = new RemoteMonitoredVm(rvm, nvmid, timer,
-                                                           interval);
-            rmvm.attach();
-            return rmvm;
-
-        } catch (RemoteException e) {
-            throw new MonitorException("Remote Exception attaching to "
-                                       + nvmid.toString(), e);
-        } catch (URISyntaxException e) {
-            /*
-             * the VmIdentifier is expected to be a valid and should resolve
-             * easonably against the host identifier. A URISyntaxException
-             * here is most likely a programming error.
-             */
-            throw new IllegalArgumentException("Malformed URI: "
-                                               + vmid.toString(), e);
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void detach(MonitoredVm vm) throws MonitorException {
-        RemoteMonitoredVm rmvm = (RemoteMonitoredVm)vm;
-        rmvm.detach();
-        try {
-            remoteHost.detachVm(rmvm.getRemoteVm());
-
-        } catch (RemoteException e) {
-            throw new MonitorException("Remote Exception detaching from "
-                                       + vm.getVmIdentifier().toString(), e);
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void addHostListener(HostListener listener) {
-        synchronized(listeners) {
-            listeners.add(listener);
-            if (task == null) {
-                task = new NotifierTask();
-                timer.schedule(task, 0, interval);
-            }
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void removeHostListener(HostListener listener) {
-        /*
-         * XXX: if a disconnect method is added, make sure it calls
-         * this method to unregister this object from the watcher. otherwise,
-         * an unused MonitoredHostProvider instance may go uncollected.
-         */
-        synchronized(listeners) {
-            listeners.remove(listener);
-            if (listeners.isEmpty() && (task != null)) {
-                task.cancel();
-                task = null;
-            }
-        }
-    }
-
-    public void setInterval(int newInterval) {
-        synchronized(listeners) {
-            if (newInterval == interval) {
-                return;
-            }
-
-            int oldInterval = interval;
-            super.setInterval(newInterval);
-
-            if (task != null) {
-                task.cancel();
-                NotifierTask oldTask = task;
-                task = new NotifierTask();
-                CountedTimerTaskUtils.reschedule(timer, oldTask, task,
-                                                 oldInterval, newInterval);
-            }
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public Set<Integer> activeVms() throws MonitorException {
-        return vmManager.activeVms();
-    }
-
-    /**
-     * Fire VmStatusChangeEvent events to HostListener objects
-     *
-     * @param active Set of Integer objects containing the local
-     *               Vm Identifiers of the active JVMs
-     * @param started Set of Integer objects containing the local
-     *                Vm Identifiers of new JVMs started since last
-     *                interval.
-     * @param terminated Set of Integer objects containing the local
-     *                   Vm Identifiers of terminated JVMs since last
-     *                   interval.
-     */
-    @SuppressWarnings("unchecked") // Cast of result of clone
-    private void fireVmStatusChangedEvents(Set<Integer> active, Set<Integer> started,
-                                           Set<Integer> terminated) {
-        ArrayList<HostListener> registered = null;
-        VmStatusChangeEvent ev = null;
-
-        synchronized(listeners) {
-            registered = (ArrayList)listeners.clone();
-        }
-
-        for (Iterator<HostListener> i = registered.iterator(); i.hasNext(); /* empty */) {
-            HostListener l = i.next();
-            if (ev == null) {
-                ev = new VmStatusChangeEvent(this, active, started, terminated);
-            }
-            l.vmStatusChanged(ev);
-        }
-    }
-
-    /**
-     * Fire hostDisconnectEvent events.
-     */
-    @SuppressWarnings("unchecked") // Cast of result of clone
-    void fireDisconnectedEvents() {
-        ArrayList<HostListener> registered = null;
-        HostEvent ev = null;
-
-        synchronized(listeners) {
-            registered = (ArrayList)listeners.clone();
-        }
-
-        for (Iterator<HostListener> i = registered.iterator(); i.hasNext(); /* empty */) {
-            HostListener l = i.next();
-            if (ev == null) {
-                ev = new HostEvent(this);
-            }
-            l.disconnected(ev);
-        }
-    }
-
-    /**
-     * class to poll the remote machine and generate local event notifications.
-     */
-    private class NotifierTask extends CountedTimerTask {
-        public void run() {
-            super.run();
-
-            // save the last set of active JVMs
-            Set<Integer> lastActiveVms = activeVms;
-
-            try {
-                // get the current set of active JVMs
-                activeVms = (HashSet<Integer>)vmManager.activeVms();
-
-            } catch (MonitorException e) {
-                // XXX: use logging api
-                System.err.println("MonitoredHostProvider: polling task "
-                                   + "caught MonitorException:");
-                e.printStackTrace();
-
-                // mark the HostManager as errored and notify listeners
-                setLastException(e);
-                fireDisconnectedEvents();
-            }
-
-            if (activeVms.isEmpty()) {
-                return;
-            }
-
-            Set<Integer> startedVms = new HashSet<>();
-            Set<Integer> terminatedVms = new HashSet<>();
-
-            for (Iterator<Integer> i = activeVms.iterator(); i.hasNext(); /* empty */ ) {
-                Integer vmid = i.next();
-                if (!lastActiveVms.contains(vmid)) {
-                    // a new file has been detected, add to set
-                    startedVms.add(vmid);
-                }
-            }
-
-            for (Iterator<Integer> i = lastActiveVms.iterator(); i.hasNext();
-                    /* empty */ ) {
-                Integer o = i.next();
-                if (!activeVms.contains(o)) {
-                    // JVM has terminated, remove it from the active list
-                    terminatedVms.add(o);
-                }
-            }
-
-            if (!startedVms.isEmpty() || !terminatedVms.isEmpty()) {
-                fireVmStatusChangedEvents(activeVms, startedVms, terminatedVms);
-            }
-        }
-    }
-}
--- a/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostRmiService.java	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.jvmstat.perfdata.monitor.protocol.rmi;
-
-import sun.jvmstat.monitor.HostIdentifier;
-import sun.jvmstat.monitor.MonitorException;
-import sun.jvmstat.monitor.MonitoredHost;
-import sun.jvmstat.monitor.MonitoredHostService;
-
-public final class MonitoredHostRmiService implements MonitoredHostService {
-
-    @Override
-    public MonitoredHost getMonitoredHost(HostIdentifier hostId) throws MonitorException {
-        return new MonitoredHostProvider(hostId);
-    }
-
-    @Override
-    public String getScheme() {
-        return "rmi";
-    }
-
-}
--- a/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/PerfDataBuffer.java	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.jvmstat.perfdata.monitor.protocol.rmi;
-
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.remote.*;
-import sun.jvmstat.perfdata.monitor.*;
-import java.io.*;
-import java.rmi.RemoteException;
-import java.nio.ByteBuffer;
-
-/**
- * The concrete PerfDataBuffer implementation for the <em>rmi:</em>
- * protocol for the HotSpot PerfData monitoring implementation.
- * <p>
- * This class is responsible for acquiring the instrumentation buffer
- * data for a remote target HotSpot Java Virtual Machine.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class PerfDataBuffer extends AbstractPerfDataBuffer {
-
-    private RemoteVm rvm;
-
-    /**
-     * Create a PerfDataBuffer instance for accessing the specified
-     * instrumentation buffer.
-     *
-     * @param rvm the proxy to the remote MonitredVm object
-     * @param lvmid the local Java Virtual Machine Identifier of the
-     *              remote target.
-     *
-     * @throws MonitorException
-     */
-    public PerfDataBuffer(RemoteVm rvm, int lvmid) throws MonitorException {
-
-        this.rvm = rvm;
-        try {
-            ByteBuffer buffer = ByteBuffer.allocate(rvm.getCapacity());
-            sample(buffer);
-            createPerfDataBuffer(buffer, lvmid);
-
-        } catch (RemoteException e) {
-            throw new MonitorException("Could not read data for remote JVM "
-                                       + lvmid, e);
-        }
-    }
-
-    /**
-     * Get a copy of the remote instrumentation buffer.
-     *<p>
-     * The data in the remote instrumentation buffer is copied into
-     * the local byte buffer.
-     *
-     * @param buffer the buffer to receive the copy of the remote
-     *               instrumentation buffer.
-     * @throws RemoteException Thrown on any communications errors with
-     *                         the remote system.
-     */
-    public void sample(ByteBuffer buffer) throws RemoteException {
-        assert buffer != null;
-        assert rvm != null;
-        synchronized(buffer) {
-            buffer.clear();
-            buffer.put(rvm.getBytes());
-        }
-    }
-}
--- a/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteMonitoredVm.java	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,300 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.jvmstat.perfdata.monitor.protocol.rmi;
-
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.event.*;
-import sun.jvmstat.monitor.remote.*;
-import sun.jvmstat.perfdata.monitor.*;
-import java.lang.reflect.*;
-import java.util.*;
-import java.io.*;
-import java.nio.ByteBuffer;
-import java.rmi.*;
-
-/**
- * Concrete implementation of the AbstractMonitoredVm class for the
- * <em>rmi:</em> protocol for the HotSpot PerfData monitoring implementation.
- * <p>
- * This class provides the ability to acquire to the instrumentation buffer
- * of a live, remote target Java Virtual Machine through an RMI server.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class RemoteMonitoredVm extends AbstractMonitoredVm {
-
-    private ArrayList<VmListener> listeners;
-    private NotifierTask notifierTask;
-    private SamplerTask samplerTask;
-    private Timer timer;
-
-    private RemoteVm rvm;
-    private ByteBuffer updateBuffer;
-
-    /**
-     * Create a RemoteMonitoredVm instance.
-     *
-     * @param rvm the proxy to the remote MonitoredVm instance.
-     * @param vmid the vm identifier specifying the remot target JVM
-     * @param timer the timer used to run polling tasks
-     * @param interval the sampling interval
-     */
-    public RemoteMonitoredVm(RemoteVm rvm, VmIdentifier vmid,
-                             Timer timer, int interval)
-           throws MonitorException {
-        super(vmid, interval);
-        this.rvm = rvm;
-        pdb = new PerfDataBuffer(rvm, vmid.getLocalVmId());
-        this.listeners = new ArrayList<VmListener>();
-        this.timer = timer;
-    }
-
-    /**
-     * Method to attach to the remote MonitoredVm.
-     */
-    public void attach() throws MonitorException {
-        updateBuffer = pdb.getByteBuffer().duplicate();
-
-        // if continuous sampling is requested, register with the sampler thread
-        if (interval > 0) {
-            samplerTask = new SamplerTask();
-            timer.schedule(samplerTask, 0, interval);
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void detach() {
-        try {
-            if (interval > 0) {
-                if (samplerTask != null) {
-                    samplerTask.cancel();
-                    samplerTask = null;
-                }
-                if (notifierTask != null) {
-                    notifierTask.cancel();
-                    notifierTask = null;
-                }
-                sample();
-            }
-        } catch (RemoteException e) {
-            // XXX: - use logging api? throw an exception instead?
-            System.err.println("Could not read data for remote JVM " + vmid);
-            e.printStackTrace();
-
-        } finally {
-            super.detach();
-        }
-    }
-
-    /**
-     * Get a copy of the remote instrumentation buffer.
-     *<p>
-     * The data in the remote instrumentation buffer is copied into
-     * a local byte buffer.
-     *
-     * @throws RemoteException Thrown on any communications errors with
-     *                         the remote system.
-     */
-    public void sample() throws RemoteException {
-        assert updateBuffer != null;
-        ((PerfDataBuffer)pdb).sample(updateBuffer);
-    }
-
-    /**
-     * Get the proxy to the remote MonitoredVm.
-     *
-     * @return RemoteVm - the proxy to the remote MonitoredVm.
-     */
-    public RemoteVm getRemoteVm() {
-        return rvm;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void addVmListener(VmListener l) {
-        synchronized(listeners) {
-            listeners.add(l);
-            if (notifierTask == null) {
-                notifierTask = new NotifierTask();
-                timer.schedule(notifierTask, 0, interval);
-            }
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void removeVmListener(VmListener l) {
-        synchronized(listeners) {
-            listeners.remove(l);
-            if (listeners.isEmpty() && (notifierTask != null)) {
-                notifierTask.cancel();
-                notifierTask = null;
-            }
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void setInterval(int newInterval) {
-        synchronized(listeners) {
-            if (newInterval == interval) {
-                return;
-            }
-
-            int oldInterval = interval;
-            super.setInterval(newInterval);
-
-            if (samplerTask != null) {
-                samplerTask.cancel();
-                SamplerTask oldSamplerTask = samplerTask;
-                samplerTask = new SamplerTask();
-                CountedTimerTaskUtils.reschedule(timer, oldSamplerTask,
-                                                 samplerTask, oldInterval,
-                                                 newInterval);
-            }
-            if (notifierTask != null) {
-                notifierTask.cancel();
-                NotifierTask oldNotifierTask = notifierTask;
-                notifierTask = new NotifierTask();
-                CountedTimerTaskUtils.reschedule(timer, oldNotifierTask,
-                                                 notifierTask, oldInterval,
-                                                 newInterval);
-            }
-        }
-    }
-
-    /**
-     * Fire MonitoredVmStructureChanged events.
-     *
-     * @param inserted List of Monitor objects inserted.
-     * @param removed List of Monitor objects removed.
-     */
-    @SuppressWarnings("unchecked") // Cast of result of clone
-    void fireMonitorStatusChangedEvents(List<Monitor> inserted, List<Monitor> removed) {
-        ArrayList<VmListener> registered = null;
-        MonitorStatusChangeEvent ev = null;
-
-        synchronized(listeners) {
-            registered = (ArrayList)listeners.clone();
-        }
-
-        for (Iterator<VmListener> i = registered.iterator(); i.hasNext(); /* empty */) {
-            VmListener l = i.next();
-            if (ev == null) {
-                ev = new MonitorStatusChangeEvent(this, inserted, removed);
-            }
-            l.monitorStatusChanged(ev);
-        }
-    }
-
-    /**
-     * Fire MonitoredVmStructureChanged events.
-     */
-    @SuppressWarnings("unchecked") // Cast of result of clone
-    void fireMonitorsUpdatedEvents() {
-        ArrayList<VmListener> registered = null;
-        VmEvent ev = null;
-
-        synchronized(listeners) {
-            registered = (ArrayList)listeners.clone();
-        }
-
-        for (Iterator<VmListener> i = registered.iterator(); i.hasNext(); /* empty */) {
-            VmListener l = i.next();
-            if (ev == null) {
-                ev = new VmEvent(this);
-            }
-            l.monitorsUpdated(ev);
-        }
-    }
-
-    /*
-     * Timer Tasks. There are two separate timer tasks here. The SamplerTask
-     * is active whenever we are attached to the remote JVM with a periodic
-     * sampling interval > 0. The NotifierTask is only active if a VmListener
-     * has registered with this RemoteMonitoredVm instance. Also, in the future
-     * we may want to run these tasks at different intervals. Currently,
-     * they run at the same interval and some significant work may
-     * need to be done to complete the separation of these two intervals.
-     */
-
-    /**
-     * Class to periodically check the state of the defined monitors
-     * for the remote MonitoredVm instance and to notify listeners of
-     * any detected changes.
-     */
-    private class NotifierTask extends CountedTimerTask {
-        public void run() {
-            super.run();
-            try {
-                MonitorStatus status = getMonitorStatus();
-
-                List<Monitor> inserted = status.getInserted();
-                List<Monitor> removed = status.getRemoved();
-
-                if (!inserted.isEmpty() || !removed.isEmpty()) {
-                    fireMonitorStatusChangedEvents(inserted, removed);
-                }
-            } catch (MonitorException e) {
-                // XXX: use logging api? fire disconnect events? mark errored?
-                // fireDisconnectedEvents();
-                System.err.println("Exception updating monitors for "
-                                   + getVmIdentifier());
-                e.printStackTrace();
-                // XXX: should we cancle the notifierTask here?
-                // this.cancel();
-            }
-        }
-    }
-
-    /**
-     * Class to periodically sample the remote instrumentation byte buffer
-     * and refresh the local copy. Registered listeners are notified of
-     * the completion of a sampling event.
-     */
-    private class SamplerTask extends CountedTimerTask {
-        public void run() {
-            super.run();
-            try {
-                sample();
-                fireMonitorsUpdatedEvents();
-
-            } catch (RemoteException e) {
-                // XXX: use logging api, mark vm as errored.
-                System.err.println("Exception taking sample for "
-                                   + getVmIdentifier());
-                e.printStackTrace();
-                this.cancel();
-            }
-        }
-    }
-}
--- a/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteVmManager.java	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.jvmstat.perfdata.monitor.protocol.rmi;
-
-import java.util.*;
-import java.util.regex.*;
-import java.io.*;
-import java.rmi.RemoteException;
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.event.*;
-import sun.jvmstat.monitor.remote.*;
-
-/**
- * Class for managing the RemoteMonitoredVm instances on a remote system.
- * <p>
- * This class is responsible for the mechanism that detects the active
- * HotSpot Java Virtual Machines on the remote host and possibly for a
- * specific user. The ability to detect all possible HotSpot Java Virtual
- * Machines on the remote host may be limited by the permissions of the
- * principal running the RMI server application on the remote host.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class RemoteVmManager {
-
-    private RemoteHost remoteHost;
-    private String user;
-
-    /**
-     * Creates a RemoteVmManager instance for the remote system.
-     * <p>
-     * Manages RemoteMonitordVm instances for which the principal
-     * running the remote server has appropriate permissions.
-     *
-     * @param remoteHost the remote proxy object to the RMI server on
-     *                   the remote system.
-     */
-    public RemoteVmManager(RemoteHost remoteHost) {
-        this(remoteHost, null);
-    }
-
-    /**
-     * Creates a RemoteVmManager instance for the given user.
-     * <p>
-     * Manages RemoteMonitoredVm instances for all remote Java Virtual
-     * machines owned by the specified user on the remote system. The
-     * RMI server on the remote system must have the appropriate permissions
-     * to access the named users Java Virtual Machines.
-     *
-     * @param remoteHost the remote proxy object to the RMI server on
-     *                   the remote system.
-     * @param user the name of the user
-     */
-    public RemoteVmManager(RemoteHost remoteHost, String user) {
-        this.user = user;
-        this.remoteHost = remoteHost;
-    }
-
-    /**
-     * Return the current set of monitorable Java Virtual Machines.
-     * <p>
-     * The set returned by this method depends on the user name passed
-     * to the constructor. If no user name was specified, then this
-     * method will return all candidate JVMs on the system. Otherwise,
-     * only the JVMs for the given user will be returned. This assumes
-     * that the RMI server process has the appropriate permissions to
-     * access the target set of JVMs.
-     *
-     * @return Set - the Set of monitorable Java Virtual Machines
-     */
-    public Set<Integer> activeVms() throws MonitorException {
-        int[] active = null;
-
-        try {
-            active = remoteHost.activeVms();
-
-        } catch (RemoteException e) {
-            throw new MonitorException("Error communicating with remote host: "
-                                       + e.getMessage(), e);
-        }
-
-        Set<Integer> activeSet = new HashSet<Integer>(active.length);
-
-        for (int i = 0; i < active.length; i++) {
-            activeSet.add(active[i]);
-        }
-
-        return activeSet;
-    }
-}
--- a/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/package.html	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-<!doctype html public "-//IETF//DTD HTML/EN">
-<html>
-<head>
-<!--
- 
-
- Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-
- This code is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License version 2 only, as
- published by the Free Software Foundation.  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.
-
--->
-</head>
-<body bgcolor="white">
-<p>
-Provides the implementation classes for the <em>rmi:</em> protocol for
-the HotSpot PerfData instrumentation buffer monitoring implementation.
-</p>
-<p>
-The <em>rmi:</em> protocol is the default protocol for the PerfData
-implementation when a hostname is specified as part of a HostIdentifier
-or VMIdentifier. It communicates with an RMI server on the remote machine
-that provides functions to get a list of available Java Virtual Machines
-and to acquire a copy of a Java Virtual Machine's instrumentation buffer.
-The RMI server may or may not use the PerfData implementation on the
-remote host to acquire this information. The <em>jstatd</em> server
-provides a PerfData implementation of the RMI server.
-</body>
-</html>
--- a/jdk/src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/Jstatd.java	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,164 +0,0 @@
-/*
- * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.tools.jstatd;
-
-import java.rmi.*;
-import java.rmi.server.*;
-import java.rmi.registry.Registry;
-import java.rmi.registry.LocateRegistry;
-import java.net.MalformedURLException;
-import sun.jvmstat.monitor.remote.*;
-
-/**
- * Application providing remote access to the jvmstat instrumentation
- * exported by local Java Virtual Machine processes. Remote access is
- * provided through an RMI interface.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class Jstatd {
-
-    private static Registry registry;
-    private static int port = -1;
-    private static boolean startRegistry = true;
-
-    private static void printUsage() {
-        System.err.println("usage: jstatd [-nr] [-p port] [-n rminame]");
-    }
-
-    static void bind(String name, RemoteHostImpl remoteHost)
-                throws RemoteException, MalformedURLException, Exception {
-
-        try {
-            Naming.rebind(name, remoteHost);
-        } catch (java.rmi.ConnectException e) {
-            /*
-             * either the registry is not running or we cannot contact it.
-             * start an internal registry if requested.
-             */
-            if (startRegistry && registry == null) {
-                int localport = (port < 0) ? Registry.REGISTRY_PORT : port;
-                registry = LocateRegistry.createRegistry(localport);
-                bind(name, remoteHost);
-            } else {
-                throw e;
-            }
-        }
-    }
-
-    @SuppressWarnings("deprecation") // Use of RMISecurityManager
-    public static void main(String[] args) {
-        String rminame = null;
-        int argc = 0;
-
-        for ( ; (argc < args.length) && (args[argc].startsWith("-")); argc++) {
-            String arg = args[argc];
-
-            if (arg.compareTo("-nr") == 0) {
-                startRegistry = false;
-            } else if (arg.startsWith("-p")) {
-                if (arg.compareTo("-p") != 0) {
-                    port = Integer.parseInt(arg.substring(2));
-                } else {
-                  argc++;
-                  if (argc >= args.length) {
-                      printUsage();
-                      System.exit(1);
-                  }
-                  port = Integer.parseInt(args[argc]);
-                }
-            } else if (arg.startsWith("-n")) {
-                if (arg.compareTo("-n") != 0) {
-                    rminame = arg.substring(2);
-                } else {
-                    argc++;
-                    if (argc >= args.length) {
-                        printUsage();
-                        System.exit(1);
-                    }
-                    rminame = args[argc];
-                }
-            } else {
-                printUsage();
-                System.exit(1);
-            }
-        }
-
-        if (argc < args.length) {
-            printUsage();
-            System.exit(1);
-        }
-
-        if (System.getSecurityManager() == null) {
-            System.setSecurityManager(new RMISecurityManager());
-        }
-
-        StringBuilder name = new StringBuilder();
-
-        if (port >= 0) {
-            name.append("//:").append(port);
-        }
-
-        if (rminame == null) {
-            rminame = "JStatRemoteHost";
-        }
-
-        name.append("/").append(rminame);
-
-        try {
-            // use 1.5.0 dynamically generated subs.
-            System.setProperty("java.rmi.server.ignoreSubClasses", "true");
-            RemoteHostImpl remoteHost = new RemoteHostImpl();
-            RemoteHost stub = (RemoteHost) UnicastRemoteObject.exportObject(
-                    remoteHost, 0);
-            bind(name.toString(), remoteHost);
-            System.out.println("jstatd started (bound to " + name.toString() + ")");
-            System.out.flush();
-        } catch (MalformedURLException e) {
-            if (rminame != null) {
-                System.out.println("Bad RMI server name: " + rminame);
-            } else {
-                System.out.println("Bad RMI URL: " + name);
-            }
-            e.printStackTrace(System.out);
-            System.exit(1);
-        } catch (java.rmi.ConnectException e) {
-            // could not attach to or create a registry
-            System.out.println("Could not contact RMI registry");
-            e.printStackTrace(System.out);
-            System.exit(1);
-        } catch (RemoteException e) {
-            System.out.println("Could not bind " + name + " to RMI Registry");
-            e.printStackTrace(System.out);
-            System.exit(1);
-        } catch (Exception e) {
-            System.out.println("Could not create remote object");
-            e.printStackTrace(System.out);
-            System.exit(1);
-        }
-    }
-}
--- a/jdk/src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/RemoteHostImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.tools.jstatd;
-
-import java.util.*;
-import java.nio.*;
-import java.io.*;
-import java.net.*;
-import java.rmi.*;
-import java.rmi.server.*;
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.event.*;
-import sun.jvmstat.monitor.remote.*;
-
-/**
- * Concrete implementation of the RemoteHost interface for the HotSpot
- * PerfData <em>rmi:</em> protocol.
- * <p>
- * This class provides remote access to the instrumentation exported
- * by HotSpot Java Virtual Machines through the PerfData shared memory
- * interface.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class RemoteHostImpl implements RemoteHost, HostListener {
-
-    private MonitoredHost monitoredHost;
-    private Set<Integer> activeVms;
-
-    public RemoteHostImpl() throws MonitorException {
-        try {
-            monitoredHost = MonitoredHost.getMonitoredHost("localhost");
-        } catch (URISyntaxException e) { }
-
-        activeVms = monitoredHost.activeVms();
-        monitoredHost.addHostListener(this);
-    }
-
-    public RemoteVm attachVm(int lvmid, String mode)
-                    throws RemoteException, MonitorException {
-        Integer v = lvmid;
-        RemoteVm stub = null;
-        StringBuilder sb = new StringBuilder();
-
-        sb.append("local://").append(lvmid).append("@localhost");
-        if (mode != null) {
-            sb.append("?mode=").append(mode);
-        }
-
-        String vmidStr = sb.toString();
-
-        try {
-            VmIdentifier vmid = new VmIdentifier(vmidStr);
-            MonitoredVm mvm = monitoredHost.getMonitoredVm(vmid);
-            RemoteVmImpl rvm = new RemoteVmImpl((BufferedMonitoredVm)mvm);
-            stub = (RemoteVm) UnicastRemoteObject.exportObject(rvm, 0);
-        }
-        catch (URISyntaxException e) {
-            throw new RuntimeException("Malformed VmIdentifier URI: "
-                                       + vmidStr, e);
-        }
-        return stub;
-    }
-
-    public void detachVm(RemoteVm rvm) throws RemoteException {
-        rvm.detach();
-    }
-
-    public int[] activeVms() throws MonitorException {
-        Object[] vms = null;
-        int[] vmids = null;
-
-        vms = monitoredHost.activeVms().toArray();
-        vmids = new int[vms.length];
-
-        for (int i = 0; i < vmids.length; i++) {
-            vmids[i] = ((Integer)vms[i]).intValue();
-        }
-        return vmids;
-    }
-
-    public void vmStatusChanged(VmStatusChangeEvent ev) {
-        synchronized(this.activeVms) {
-            activeVms.retainAll(ev.getActive());
-        }
-    }
-
-    public void disconnected(HostEvent ev) {
-        // we only monitor the local host, so this event shouldn't occur.
-    }
-}
--- a/jdk/src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/RemoteVmImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.tools.jstatd;
-
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.remote.*;
-
-/**
- * Concrete implementation of the RemoteVm interface for the HotSpot PerfData
- * shared memory implementation of the jvmstat monitoring APIs. This class
- * providing remote access to the instrumentation exported by a local HotSpot
- * Java Virtual Machine. The instrumentation buffer is shipped in whole to
- * the remote machine, which is responsible for parsing and provide access
- * to the contained data.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class RemoteVmImpl implements RemoteVm {
-
-    private BufferedMonitoredVm mvm;
-
-    RemoteVmImpl(BufferedMonitoredVm mvm) {
-        this.mvm = mvm;
-    }
-
-    public byte[] getBytes() {
-        return mvm.getBytes();
-    }
-
-    public int getCapacity() {
-        return mvm.getCapacity();
-    }
-
-    public void detach() {
-        mvm.detach();
-    }
-
-    public int getLocalVmId() {
-        return mvm.getVmIdentifier().getLocalVmId();
-    }
-}
--- a/jdk/src/jdk.jvmstat/share/classes/module-info.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/jdk.jvmstat/share/classes/module-info.java	Thu Apr 28 23:08:16 2016 -0700
@@ -28,12 +28,12 @@
         jdk.attach,
         jdk.jcmd,
         jdk.jconsole,
-        jdk.jvmstat.rmi;
+        jdk.jstatd;
     exports sun.jvmstat.monitor.event to
         jdk.jcmd,
-        jdk.jvmstat.rmi;
+        jdk.jstatd;
     exports sun.jvmstat.perfdata.monitor to
-        jdk.jvmstat.rmi;
+        jdk.jstatd;
 
     uses sun.jvmstat.monitor.MonitoredHostService;
     provides sun.jvmstat.monitor.MonitoredHostService with sun.jvmstat.perfdata.monitor.protocol.file.MonitoredHostFileService;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.net/share/classes/jdk/net/ExtendedSocketOptions.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.net;
+
+import java.io.FileDescriptor;
+import java.net.SocketException;
+import java.net.SocketOption;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collections;
+import java.util.Set;
+import jdk.internal.misc.JavaIOFileDescriptorAccess;
+import jdk.internal.misc.SharedSecrets;
+
+/**
+ * Defines extended socket options, beyond those defined in
+ * {@link java.net.StandardSocketOptions}. These options may be platform
+ * specific.
+ *
+ * @since 1.8
+ */
+public final class ExtendedSocketOptions {
+
+    private static class ExtSocketOption<T> implements SocketOption<T> {
+        private final String name;
+        private final Class<T> type;
+        ExtSocketOption(String name, Class<T> type) {
+            this.name = name;
+            this.type = type;
+        }
+        @Override public String name() { return name; }
+        @Override public Class<T> type() { return type; }
+        @Override public String toString() { return name; }
+    }
+
+    private ExtendedSocketOptions() { }
+
+    /**
+     * Service level properties. When a security manager is installed,
+     * setting or getting this option requires a {@link NetworkPermission}
+     * {@code ("setOption.SO_FLOW_SLA")} or {@code "getOption.SO_FLOW_SLA"}
+     * respectively.
+     */
+    public static final SocketOption<SocketFlow> SO_FLOW_SLA = new
+        ExtSocketOption<SocketFlow>("SO_FLOW_SLA", SocketFlow.class);
+
+
+    private static final PlatformSocketOptions platformSocketOptions =
+            PlatformSocketOptions.get();
+
+    private static final boolean flowSupported =
+            platformSocketOptions.flowSupported();
+
+    private static final Set<SocketOption<?>> extendedOptions = options();
+
+    static Set<SocketOption<?>> options() {
+        if (flowSupported)
+            return Set.of(SO_FLOW_SLA);
+        else
+            return Collections.<SocketOption<?>>emptySet();
+    }
+
+    static {
+        // Registers the extended socket options with the base module.
+        sun.net.ext.ExtendedSocketOptions.register(
+                new sun.net.ext.ExtendedSocketOptions(extendedOptions) {
+
+            @Override
+            public void setOption(FileDescriptor fd,
+                                  SocketOption<?> option,
+                                  Object value)
+                throws SocketException
+            {
+                SecurityManager sm = System.getSecurityManager();
+                if (sm != null)
+                    sm.checkPermission(new NetworkPermission("setOption." + option.name()));
+
+                if (fd == null || !fd.valid())
+                    throw new SocketException("socket closed");
+
+                if (option == SO_FLOW_SLA) {
+                    assert flowSupported;
+                    SocketFlow flow = checkValueType(value, option.type());
+                    setFlowOption(fd, flow);
+                } else {
+                    throw new InternalError("Unexpected option " + option);
+                }
+            }
+
+            @Override
+            public Object getOption(FileDescriptor fd,
+                                    SocketOption<?> option)
+                throws SocketException
+            {
+                SecurityManager sm = System.getSecurityManager();
+                if (sm != null)
+                    sm.checkPermission(new NetworkPermission("getOption." + option.name()));
+
+                if (fd == null || !fd.valid())
+                    throw new SocketException("socket closed");
+
+                if (option == SO_FLOW_SLA) {
+                    assert flowSupported;
+                    SocketFlow flow = SocketFlow.create();
+                    getFlowOption(fd, flow);
+                    return flow;
+                } else {
+                    throw new InternalError("Unexpected option " + option);
+                }
+            }
+        });
+    }
+
+    @SuppressWarnings("unchecked")
+    private static <T> T checkValueType(Object value, Class<?> type) {
+        if (!type.isAssignableFrom(value.getClass())) {
+            String s = "Found: " + value.getClass() + ", Expected: " + type;
+            throw new IllegalArgumentException(s);
+        }
+        return (T) value;
+    }
+
+    private static final JavaIOFileDescriptorAccess fdAccess =
+            SharedSecrets.getJavaIOFileDescriptorAccess();
+
+    private static void setFlowOption(FileDescriptor fd, SocketFlow f)
+        throws SocketException
+    {
+        int status = platformSocketOptions.setFlowOption(fdAccess.get(fd),
+                                                         f.priority(),
+                                                         f.bandwidth());
+        f.status(status);  // augment the given flow with the status
+    }
+
+    private static void getFlowOption(FileDescriptor fd, SocketFlow f)
+        throws SocketException
+    {
+        int status = platformSocketOptions.getFlowOption(fdAccess.get(fd), f);
+        f.status(status);  // augment the given flow with the status
+    }
+
+    static class PlatformSocketOptions {
+
+        protected PlatformSocketOptions() {}
+
+        @SuppressWarnings("unchecked")
+        private static PlatformSocketOptions newInstance(String cn) {
+            Class<PlatformSocketOptions> c;
+            try {
+                c = (Class<PlatformSocketOptions>)Class.forName(cn);
+                return c.getConstructor(new Class<?>[] { }).newInstance();
+            } catch (ReflectiveOperationException x) {
+                throw new AssertionError(x);
+            }
+        }
+
+        private static PlatformSocketOptions create() {
+            String osname = AccessController.doPrivileged(
+                    new PrivilegedAction<String>() {
+                        public String run() {
+                            return System.getProperty("os.name");
+                        }
+                    });
+            if ("SunOS".equals(osname))
+                return newInstance("jdk.net.SolarisSocketOptions");
+            return new PlatformSocketOptions();
+        }
+
+        private static final PlatformSocketOptions instance = create();
+
+        static PlatformSocketOptions get() {
+            return instance;
+        }
+
+        int setFlowOption(int fd, int priority, long bandwidth)
+            throws SocketException
+        {
+            throw new UnsupportedOperationException("unsupported socket option");
+        }
+
+        int getFlowOption(int fd, SocketFlow f) throws SocketException {
+            throw new UnsupportedOperationException("unsupported socket option");
+        }
+
+        boolean flowSupported() {
+            return false;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.net/share/classes/jdk/net/NetworkPermission.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.net;
+
+import java.security.BasicPermission;
+
+/**
+ * Represents permission to access the extended networking capabilities
+ * defined in the jdk.net package. These permissions contain a target
+ * name, but no actions list. Callers either possess the permission or not.
+ * <p>
+ * The following targets are defined:
+ *
+ * <table border=1 cellpadding=5 summary="permission target name,
+ *  what the target allows,and associated risks">
+ * <tr>
+ *   <th>Permission Target Name</th>
+ *   <th>What the Permission Allows</th>
+ *   <th>Risks of Allowing this Permission</th>
+ * </tr>
+ * <tr>
+ *   <td>setOption.SO_FLOW_SLA</td>
+ *   <td>set the {@link ExtendedSocketOptions#SO_FLOW_SLA SO_FLOW_SLA} option
+ *       on any socket that supports it</td>
+ *   <td>allows caller to set a higher priority or bandwidth allocation
+ *       to sockets it creates, than they might otherwise be allowed.</td>
+ * </tr>
+ * <tr>
+ *   <td>getOption.SO_FLOW_SLA</td>
+ *   <td>retrieve the {@link ExtendedSocketOptions#SO_FLOW_SLA SO_FLOW_SLA}
+ *       setting from any socket that supports the option</td>
+ *   <td>allows caller access to SLA information that it might not
+ *       otherwise have</td>
+ * </tr></table>
+ *
+ * @see jdk.net.ExtendedSocketOptions
+ *
+ * @since 1.8
+ */
+
+public final class NetworkPermission extends BasicPermission {
+
+    private static final long serialVersionUID = -2012939586906722291L;
+
+    /**
+     * Creates a NetworkPermission with the given target name.
+     *
+     * @param name the permission target name
+     * @throws NullPointerException if {@code name} is {@code null}.
+     * @throws IllegalArgumentException if {@code name} is empty.
+     */
+    public NetworkPermission(String name)
+    {
+        super(name);
+    }
+
+    /**
+     * Creates a NetworkPermission with the given target name.
+     *
+     * @param name the permission target name
+     * @param actions should be {@code null}. Is ignored if not.
+     * @throws NullPointerException if {@code name} is {@code null}.
+     * @throws IllegalArgumentException if {@code name} is empty.
+     */
+    public NetworkPermission(String name, String actions)
+    {
+        super(name, actions);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.net/share/classes/jdk/net/SocketFlow.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.net;
+
+import java.lang.annotation.Native;
+
+/**
+ * Represents the service level properties for the platform specific socket
+ * option {@link ExtendedSocketOptions#SO_FLOW_SLA}.
+ * <p>
+ * The priority and bandwidth parameters must be set before
+ * setting the socket option.
+ * <p>
+ * When the {@code SO_FLOW_SLA} option is set then it may not take effect
+ * immediately. If the value of the socket option is obtained with
+ * {@code getOption()} then the status may be returned as {@code INPROGRESS}
+ * until it takes effect. The priority and bandwidth values are only valid when
+ * the status is returned as OK.
+ * <p>
+ * When a security manager is installed, a {@link NetworkPermission}
+ * is required to set or get this option.
+ *
+ * @since 1.8
+ */
+public class SocketFlow {
+
+    @Native public static final int UNSET = -1;
+    @Native public static final int NORMAL_PRIORITY = 1;
+    @Native public static final int HIGH_PRIORITY = 2;
+
+    @Native private static final int NO_STATUS_VALUE = 0;
+    @Native private static final int OK_VALUE = 1;
+    @Native private static final int NO_PERMISSION_VALUE = 2;
+    @Native private static final int NOT_CONNECTED_VALUE = 3;
+    @Native private static final int NOT_SUPPORTED_VALUE = 4;
+    @Native private static final int ALREADY_CREATED_VALUE = 5;
+    @Native private static final int IN_PROGRESS_VALUE = 6;
+    @Native private static final int OTHER_VALUE = 7;
+
+    /**
+     * Enumeration of the return values from the SO_FLOW_SLA
+     * socket option. Both setting and getting the option return
+     * one of these statuses, which reflect the state of socket's
+     * flow.
+     *
+     * @since 1.8
+     */
+    public enum Status {
+        /**
+         * Set or get socket option has not been called yet. Status
+         * values can only be retrieved after calling set or get.
+         */
+        NO_STATUS(NO_STATUS_VALUE),
+        /**
+         * Flow successfully created.
+         */
+        OK(OK_VALUE),
+        /**
+         * Caller has no permission to create flow.
+         */
+        NO_PERMISSION(NO_PERMISSION_VALUE),
+        /**
+         * Flow can not be created because socket is not connected.
+         */
+        NOT_CONNECTED(NOT_CONNECTED_VALUE),
+        /**
+         * Flow creation not supported for this socket.
+         */
+        NOT_SUPPORTED(NOT_SUPPORTED_VALUE),
+        /**
+         * A flow already exists with identical attributes.
+         */
+        ALREADY_CREATED(ALREADY_CREATED_VALUE),
+        /**
+         * A flow is being created.
+         */
+        IN_PROGRESS(IN_PROGRESS_VALUE),
+        /**
+         * Some other unspecified error.
+         */
+        OTHER(OTHER_VALUE);
+
+        private final int value;
+        Status(int value) { this.value = value; }
+
+        static Status from(int value) {
+            if      (value == NO_STATUS.value)       return NO_STATUS;
+            else if (value == OK.value)              return OK;
+            else if (value == NO_PERMISSION.value)   return NO_PERMISSION;
+            else if (value == NOT_CONNECTED.value)   return NOT_CONNECTED;
+            else if (value == NOT_SUPPORTED.value)   return NOT_SUPPORTED;
+            else if (value == ALREADY_CREATED.value) return ALREADY_CREATED;
+            else if (value == IN_PROGRESS.value)     return IN_PROGRESS;
+            else if (value == OTHER.value)           return OTHER;
+            else     throw new InternalError("Unknown value: " + value);
+        }
+    }
+
+    private int priority = NORMAL_PRIORITY;
+    private long bandwidth = UNSET;
+    private Status status = Status.NO_STATUS;
+
+    /**
+     * Creates a new SocketFlow that can be used to set the SO_FLOW_SLA
+     * socket option and create a socket flow.
+     */
+    public static SocketFlow create() {
+        return new SocketFlow();
+    }
+
+    private SocketFlow() { }
+
+    /**
+     * Sets this SocketFlow's priority. Must be either NORMAL_PRIORITY
+     * HIGH_PRIORITY. If not set, a flow's priority is normal.
+     *
+     * @throws IllegalArgumentException if priority is not NORMAL_PRIORITY or
+     *         HIGH_PRIORITY.
+     */
+    public SocketFlow priority(int priority) {
+        if (priority != NORMAL_PRIORITY && priority != HIGH_PRIORITY)
+            throw new IllegalArgumentException("invalid priority :" + priority);
+        this.priority = priority;
+        return this;
+    }
+
+    /**
+     * Sets this SocketFlow's bandwidth. Must be greater than or equal to zero.
+     * A value of zero drops all packets for the socket.
+     *
+     * @throws IllegalArgumentException if bandwidth is less than zero.
+     */
+    public SocketFlow bandwidth(long bandwidth) {
+        if (bandwidth < 0)
+            throw new IllegalArgumentException("invalid bandwidth: " + bandwidth);
+        this.bandwidth = bandwidth;
+        return this;
+    }
+
+    /**
+     * Returns this SocketFlow's priority.
+     */
+    public int priority() {
+        return priority;
+    }
+
+    /**
+     * Returns this SocketFlow's bandwidth.
+     *
+     * @return this SocketFlow's bandwidth, or {@code -1} if status is not OK.
+     */
+    public long bandwidth() {
+        return bandwidth;
+    }
+
+    /**
+     * Returns the Status value of this SocketFlow. NO_STATUS is returned
+     * if the object was not used in a call to set or get the option.
+     */
+    public Status status() {
+        return status;
+    }
+
+    void status(int status) {
+        this.status = Status.from(status);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder(super.toString());
+        sb.append(" [ priority=").append(priority())
+          .append(", bandwidth=").append(bandwidth())
+          .append(", status=").append(status())
+          .append(" ]");
+        return sb.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.net/share/classes/jdk/net/Sockets.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 2016, 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 jdk.net;
+
+import java.net.*;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import jdk.net.ExtendedSocketOptions.PlatformSocketOptions;
+
+/**
+ * Defines static methods to set and get socket options defined by the
+ * {@link java.net.SocketOption} interface. All of the standard options defined
+ * by {@link java.net.Socket}, {@link java.net.ServerSocket}, and
+ * {@link java.net.DatagramSocket} can be set this way, as well as additional
+ * or platform specific options supported by each socket type.
+ * <p>
+ * The {@link #supportedOptions(Class)} method can be called to determine
+ * the complete set of options available (per socket type) on the
+ * current system.
+ * <p>
+ * When a security manager is installed, some non-standard socket options
+ * may require a security permission before being set or get.
+ * The details are specified in {@link ExtendedSocketOptions}. No permission
+ * is required for {@link java.net.StandardSocketOptions}.
+ *
+ * @see java.nio.channels.NetworkChannel
+ */
+public class Sockets {
+
+    private static final Map<Class<?>,Set<SocketOption<?>>>
+            options = optionSets();
+
+    private Sockets() {}
+
+    /**
+     * Sets the value of a socket option on a {@link java.net.Socket}
+     *
+     * @param s the socket
+     * @param name The socket option
+     * @param value The value of the socket option. May be null for some
+     *              options.
+     *
+     * @throws UnsupportedOperationException if the socket does not support
+     *         the option.
+     *
+     * @throws IllegalArgumentException if the value is not valid for
+     *         the option.
+     *
+     * @throws IOException if an I/O error occurs, or socket is closed.
+     *
+     * @throws SecurityException if a security manager is set and the
+     *         caller does not have any required permission.
+     *
+     * @throws NullPointerException if name is null
+     *
+     * @see java.net.StandardSocketOptions
+     */
+    public static <T> void setOption(Socket s, SocketOption<T> name, T value) throws IOException
+    {
+        s.setOption(name, value);
+    }
+
+    /**
+     * Returns the value of a socket option from a {@link java.net.Socket}
+     *
+     * @param s the socket
+     * @param name The socket option
+     *
+     * @return The value of the socket option.
+     *
+     * @throws UnsupportedOperationException if the socket does not support
+     *         the option.
+     *
+     * @throws IOException if an I/O error occurs
+     *
+     * @throws SecurityException if a security manager is set and the
+     *         caller does not have any required permission.
+     *
+     * @throws NullPointerException if name is null
+     *
+     * @see java.net.StandardSocketOptions
+     */
+    public static <T> T getOption(Socket s, SocketOption<T> name) throws IOException
+    {
+        return s.getOption(name);
+    }
+
+    /**
+     * Sets the value of a socket option on a {@link java.net.ServerSocket}
+     *
+     * @param s the socket
+     * @param name The socket option
+     * @param value The value of the socket option.
+     *
+     * @throws UnsupportedOperationException if the socket does not support
+     *         the option.
+     *
+     * @throws IllegalArgumentException if the value is not valid for
+     *         the option.
+     *
+     * @throws IOException if an I/O error occurs
+     *
+     * @throws NullPointerException if name is null
+     *
+     * @throws SecurityException if a security manager is set and the
+     *         caller does not have any required permission.
+     *
+     * @see java.net.StandardSocketOptions
+     */
+    public static <T> void setOption(ServerSocket s, SocketOption<T> name, T value) throws IOException
+    {
+        s.setOption(name, value);
+    }
+
+    /**
+     * Returns the value of a socket option from a {@link java.net.ServerSocket}
+     *
+     * @param s the socket
+     * @param name The socket option
+     *
+     * @return The value of the socket option.
+     *
+     * @throws UnsupportedOperationException if the socket does not support
+     *         the option.
+     *
+     * @throws IOException if an I/O error occurs
+     *
+     * @throws NullPointerException if name is null
+     *
+     * @throws SecurityException if a security manager is set and the
+     *         caller does not have any required permission.
+     *
+     * @see java.net.StandardSocketOptions
+     */
+    public static <T> T getOption(ServerSocket s, SocketOption<T> name) throws IOException
+    {
+        return s.getOption(name);
+    }
+
+    /**
+     * Sets the value of a socket option on a {@link java.net.DatagramSocket}
+     * or {@link java.net.MulticastSocket}
+     *
+     * @param s the socket
+     * @param name The socket option
+     * @param value The value of the socket option.
+     *
+     * @throws UnsupportedOperationException if the socket does not support
+     *         the option.
+     *
+     * @throws IllegalArgumentException if the value is not valid for
+     *         the option.
+     *
+     * @throws IOException if an I/O error occurs
+     *
+     * @throws NullPointerException if name is null
+     *
+     * @throws SecurityException if a security manager is set and the
+     *         caller does not have any required permission.
+     *
+     * @see java.net.StandardSocketOptions
+     */
+    public static <T> void setOption(DatagramSocket s, SocketOption<T> name, T value) throws IOException
+    {
+        s.setOption(name, value);
+    }
+
+    /**
+     * Returns the value of a socket option from a
+     * {@link java.net.DatagramSocket} or {@link java.net.MulticastSocket}
+     *
+     * @param s the socket
+     * @param name The socket option
+     *
+     * @return The value of the socket option.
+     *
+     * @throws UnsupportedOperationException if the socket does not support
+     *         the option.
+     *
+     * @throws IOException if an I/O error occurs
+     *
+     * @throws NullPointerException if name is null
+     *
+     * @throws SecurityException if a security manager is set and the
+     *         caller does not have any required permission.
+     *
+     * @see java.net.StandardSocketOptions
+     */
+    public static <T> T getOption(DatagramSocket s, SocketOption<T> name) throws IOException
+    {
+        return s.getOption(name);
+    }
+
+    /**
+     * Returns a set of {@link java.net.SocketOption}s supported by the
+     * given socket type. This set may include standard options and also
+     * non standard extended options.
+     *
+     * @param socketType the type of java.net socket
+     *
+     * @throws IllegalArgumentException if socketType is not a valid
+     *         socket type from the java.net package.
+     */
+    public static Set<SocketOption<?>> supportedOptions(Class<?> socketType) {
+        Set<SocketOption<?>> set = options.get(socketType);
+        if (set == null) {
+            throw new IllegalArgumentException("unknown socket type");
+        }
+        return set;
+    }
+
+    private static void checkValueType(Object value, Class<?> type) {
+        if (!type.isAssignableFrom(value.getClass())) {
+            String s = "Found: " + value.getClass().toString() + " Expected: "
+                        + type.toString();
+            throw new IllegalArgumentException(s);
+        }
+    }
+
+    private static volatile boolean checkedReusePort;
+    private static volatile boolean isReusePortAvailable;
+
+    /**
+     * Tells whether SO_REUSEPORT is supported.
+     */
+    static boolean isReusePortAvailable() {
+        if (!checkedReusePort) {
+            Set<SocketOption<?>> s = new Socket().supportedOptions();
+            isReusePortAvailable = s.contains(StandardSocketOptions.SO_REUSEPORT);
+            checkedReusePort = true;
+        }
+        return isReusePortAvailable;
+    }
+
+    private static Map<Class<?>,Set<SocketOption<?>>> optionSets() {
+        Map<Class<?>,Set<SocketOption<?>>> options = new HashMap<>();
+        boolean flowsupported = PlatformSocketOptions.get().flowSupported();
+        boolean reuseportsupported = isReusePortAvailable();
+        // Socket
+
+        Set<SocketOption<?>> set = new HashSet<>();
+        set.add(StandardSocketOptions.SO_KEEPALIVE);
+        set.add(StandardSocketOptions.SO_SNDBUF);
+        set.add(StandardSocketOptions.SO_RCVBUF);
+        set.add(StandardSocketOptions.SO_REUSEADDR);
+        if (reuseportsupported) {
+            set.add(StandardSocketOptions.SO_REUSEPORT);
+        }
+        set.add(StandardSocketOptions.SO_LINGER);
+        set.add(StandardSocketOptions.IP_TOS);
+        set.add(StandardSocketOptions.TCP_NODELAY);
+        if (flowsupported) {
+            set.add(ExtendedSocketOptions.SO_FLOW_SLA);
+        }
+        set = Collections.unmodifiableSet(set);
+        options.put(Socket.class, set);
+
+        // ServerSocket
+
+        set = new HashSet<>();
+        set.add(StandardSocketOptions.SO_RCVBUF);
+        set.add(StandardSocketOptions.SO_REUSEADDR);
+        if (reuseportsupported) {
+            set.add(StandardSocketOptions.SO_REUSEPORT);
+        }
+        set.add(StandardSocketOptions.IP_TOS);
+        set = Collections.unmodifiableSet(set);
+        options.put(ServerSocket.class, set);
+
+        // DatagramSocket
+
+        set = new HashSet<>();
+        set.add(StandardSocketOptions.SO_SNDBUF);
+        set.add(StandardSocketOptions.SO_RCVBUF);
+        set.add(StandardSocketOptions.SO_REUSEADDR);
+        if (reuseportsupported) {
+            set.add(StandardSocketOptions.SO_REUSEPORT);
+        }
+        set.add(StandardSocketOptions.IP_TOS);
+        if (flowsupported) {
+            set.add(ExtendedSocketOptions.SO_FLOW_SLA);
+        }
+        set = Collections.unmodifiableSet(set);
+        options.put(DatagramSocket.class, set);
+
+        // MulticastSocket
+
+        set = new HashSet<>();
+        set.add(StandardSocketOptions.SO_SNDBUF);
+        set.add(StandardSocketOptions.SO_RCVBUF);
+        set.add(StandardSocketOptions.SO_REUSEADDR);
+        if (reuseportsupported) {
+            set.add(StandardSocketOptions.SO_REUSEPORT);
+        }
+        set.add(StandardSocketOptions.IP_TOS);
+        set.add(StandardSocketOptions.IP_MULTICAST_IF);
+        set.add(StandardSocketOptions.IP_MULTICAST_TTL);
+        set.add(StandardSocketOptions.IP_MULTICAST_LOOP);
+        if (flowsupported) {
+            set.add(ExtendedSocketOptions.SO_FLOW_SLA);
+        }
+        set = Collections.unmodifiableSet(set);
+        options.put(MulticastSocket.class, set);
+
+        return Collections.unmodifiableMap(options);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.net/share/classes/jdk/net/package-info.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Platform specific socket options for the {@code java.net} and {@code java.nio.channels}
+ * socket classes.
+ *
+ * @since 1.8
+ */
+
+package jdk.net;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.net/share/classes/module-info.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+module jdk.net {
+    exports jdk.net;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.net/solaris/classes/jdk/net/SolarisSocketOptions.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016, 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 jdk.net;
+
+import java.net.SocketException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import jdk.net.ExtendedSocketOptions.PlatformSocketOptions;
+
+class SolarisSocketOptions extends PlatformSocketOptions {
+
+    public SolarisSocketOptions() { }
+
+    @Override native int setFlowOption(int fd, int priority, long bandwidth)
+            throws SocketException;
+
+    @Override native int getFlowOption(int fd, SocketFlow f)
+            throws SocketException;
+
+    @Override native boolean flowSupported();
+
+    private static native void init();
+
+    static {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
+                System.loadLibrary("extnet");
+                return null;
+            }
+        });
+        init();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.net/solaris/native/libextnet/SolarisSocketOptions.c	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+#include "SolarisSocketOptions.h"
+
+static jfieldID sf_priority;
+static jfieldID sf_bandwidth;
+
+static int initialized = 0;
+
+/*
+ * Class:     jdk_net_SolarisSocketOptions
+ * Method:    init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_jdk_net_SolarisSocketOptions_init
+  (JNIEnv *env, jclass unused)
+{
+    if (!initialized) {
+        jclass c = (*env)->FindClass(env, "jdk/net/SocketFlow");
+        CHECK_NULL(c);
+        sf_priority = (*env)->GetFieldID(env, c, "priority", "I");
+        CHECK_NULL(sf_priority);
+        sf_bandwidth = (*env)->GetFieldID(env, c, "bandwidth", "J");
+        CHECK_NULL(sf_bandwidth);
+        initialized = 1;
+    }
+}
+
+/** Return the Status value. */
+static jint toStatus(int errval)
+{
+    switch (errval) {
+      case 0:           return jdk_net_SocketFlow_OK_VALUE;
+      case EPERM:       return jdk_net_SocketFlow_NO_PERMISSION_VALUE;
+      case ENOTCONN:    return jdk_net_SocketFlow_NOT_CONNECTED_VALUE;
+      case EOPNOTSUPP:  return jdk_net_SocketFlow_NOT_SUPPORTED_VALUE;
+      case EALREADY:    return jdk_net_SocketFlow_ALREADY_CREATED_VALUE;
+      case EINPROGRESS: return jdk_net_SocketFlow_IN_PROGRESS_VALUE;
+      default:          return jdk_net_SocketFlow_OTHER_VALUE;
+    }
+}
+
+void throwByNameWithLastError
+  (JNIEnv *env, const char *name, const char *defaultDetail)
+{
+  char defaultMsg[255];
+  sprintf(defaultMsg, "errno: %d, %s", errno, defaultDetail);
+  JNU_ThrowByNameWithLastError(env, name, defaultMsg);
+}
+
+/*
+ * Class:     jdk_net_SolarisSocketOptions
+ * Method:    setFlowOption0
+ * Signature: (IIJ)I
+ */
+JNIEXPORT jint JNICALL Java_jdk_net_SolarisSocketOptions_setFlowOption
+  (JNIEnv *env, jobject unused, jint fd, jint priority, jlong bandwidth)
+{
+    int rv;
+    sock_flow_props_t props;
+    memset(&props, 0, sizeof(props));
+    props.sfp_version = SOCK_FLOW_PROP_VERSION1;
+
+    if (priority != jdk_net_SocketFlow_UNSET) {
+        props.sfp_mask |= SFP_PRIORITY;
+        props.sfp_priority = priority;
+    }
+    if (bandwidth > jdk_net_SocketFlow_UNSET)  {
+        props.sfp_mask |= SFP_MAXBW;
+        props.sfp_maxbw = (uint64_t) bandwidth;
+    }
+
+    rv = setsockopt(fd, SOL_SOCKET, SO_FLOW_SLA, &props, sizeof(props));
+
+    if (rv < 0) {
+        if (errno == ENOPROTOOPT) {
+            JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+                            "unsupported socket option");
+        } else if (errno == EACCES || errno == EPERM) {
+            JNU_ThrowByName(env, "java/net/SocketException", "Permission denied");
+        } else {
+            throwByNameWithLastError(env, "java/net/SocketException",
+                                     "set option SO_FLOW_SLA failed");
+        }
+        return 0;
+    }
+    return toStatus(props.sfp_status);
+}
+
+/*
+ * Class:     jdk_net_SolarisSocketOptions
+ * Method:    getFlowOption0
+ * Signature: (ILjdk/net/SocketFlow;)I
+ */
+JNIEXPORT jint JNICALL Java_jdk_net_SolarisSocketOptions_getFlowOption
+  (JNIEnv *env, jobject unused, jint fd, jobject flow)
+{
+    sock_flow_props_t props;
+    socklen_t sz = sizeof(props);
+
+    int rv = getsockopt(fd, SOL_SOCKET, SO_FLOW_SLA, &props, &sz);
+
+    if (rv < 0) {
+        if (errno == ENOPROTOOPT) {
+            JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+                            "unsupported socket option");
+        } else if (errno == EACCES || errno == EPERM) {
+            JNU_ThrowByName(env, "java/net/SocketException", "Permission denied");
+        } else {
+            throwByNameWithLastError(env, "java/net/SocketException",
+                                     "get option SO_FLOW_SLA failed");
+        }
+        return -1;
+    }
+    /* first check status to see if flow exists */
+    if (props.sfp_status == 0) { /* OK */
+        /* can set the other fields now */
+        if (props.sfp_mask & SFP_PRIORITY) {
+            (*env)->SetIntField(env, flow, sf_priority, props.sfp_priority);
+        }
+        if (props.sfp_mask & SFP_MAXBW) {
+            (*env)->SetLongField(env, flow, sf_bandwidth,
+                                    (jlong)props.sfp_maxbw);
+        }
+    }
+    return toStatus(props.sfp_status);
+}
+
+JNIEXPORT jboolean JNICALL Java_jdk_net_SolarisSocketOptions_flowSupported
+  (JNIEnv *env, jobject unused)
+{
+    /* Do a simple dummy call, and try to figure out from that */
+    sock_flow_props_t props;
+    int rv, s;
+
+    s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+    if (s < 0) {
+        return JNI_FALSE;
+    }
+    memset(&props, 0, sizeof(props));
+    props.sfp_version = SOCK_FLOW_PROP_VERSION1;
+    props.sfp_mask |= SFP_PRIORITY;
+    props.sfp_priority = SFP_PRIO_NORMAL;
+    rv = setsockopt(s, SOL_SOCKET, SO_FLOW_SLA, &props, sizeof(props));
+    if (rv != 0 && errno == ENOPROTOOPT) {
+        rv = JNI_FALSE;
+    } else {
+        rv = JNI_TRUE;
+    }
+    close(s);
+    return rv;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.net/solaris/native/libextnet/SolarisSocketOptions.h	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+#ifndef SOLARIS_SOCKET_OPTIONS_H
+#define SOLARIS_SOCKET_OPTIONS_H
+
+#include <sys/socket.h>
+#include <jni.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "jni_util.h"
+#include "jdk_net_SocketFlow.h"
+#include "SolarisSocketOptions.h"
+#include "jdk_net_SolarisSocketOptions.h"
+
+#ifndef SO_FLOW_SLA
+#define SO_FLOW_SLA 0x1018
+
+#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
+#pragma pack(4)
+#endif
+
+/*
+ * Used with the setsockopt(SO_FLOW_SLA, ...) call to set
+ * per socket service level properties.
+ * When the application uses per-socket API, we will enforce the properties
+ * on both outbound and inbound packets.
+ *
+ * For now, only priority and maxbw are supported in SOCK_FLOW_PROP_VERSION1.
+ */
+typedef struct sock_flow_props_s {
+        int             sfp_version;
+        uint32_t        sfp_mask;
+        int             sfp_priority;   /* flow priority */
+        uint64_t        sfp_maxbw;      /* bandwidth limit in bps */
+        int             sfp_status;     /* flow create status for getsockopt */
+} sock_flow_props_t;
+
+#define SOCK_FLOW_PROP_VERSION1 1
+
+/* bit mask values for sfp_mask */
+#define SFP_MAXBW       0x00000001      /* Flow Bandwidth Limit */
+#define SFP_PRIORITY    0x00000008      /* Flow priority */
+
+/* possible values for sfp_priority */
+#define SFP_PRIO_NORMAL 1
+#define SFP_PRIO_HIGH   2
+
+#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
+#pragma pack()
+#endif /* _LONG_LONG_ALIGNMENT */
+
+#endif /* SO_FLOW_SLA */
+
+#endif /* SOLARIS_SOCKET_OPTIONS_H */
--- a/jdk/src/jdk.policytool/share/classes/module-info.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/src/jdk.policytool/share/classes/module-info.java	Thu Apr 28 23:08:16 2016 -0700
@@ -28,6 +28,7 @@
     requires java.logging;
     requires java.management;
     requires java.sql;
+    requires jdk.net;
     requires java.security.jgss;
     requires jdk.security.jgss;
 }
--- a/jdk/src/jdk.unsupported/share/classes/sun/misc/ManagedLocalsThread.java	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc;
-
-/**
- * A thread that has it's thread locals, and inheritable thread
- * locals erased on construction.
- */
-public class ManagedLocalsThread extends Thread {
-    private static final jdk.internal.misc.Unsafe UNSAFE;
-    private static final long THREAD_LOCALS;
-    private static final long INHERITABLE_THREAD_LOCALS;
-
-    public ManagedLocalsThread() {
-        eraseThreadLocals();
-    }
-
-    public ManagedLocalsThread(Runnable target) {
-        super(target);
-        eraseThreadLocals();
-    }
-
-    public ManagedLocalsThread(String name) {
-        super(name);
-        eraseThreadLocals();
-    }
-
-    public ManagedLocalsThread(ThreadGroup group, Runnable target) {
-        super(group, target);
-        eraseThreadLocals();
-    }
-
-    public ManagedLocalsThread(Runnable target, String name) {
-        super(target, name);
-        eraseThreadLocals();
-    }
-
-    public ManagedLocalsThread(ThreadGroup group, String name) {
-        super(group, name);
-        eraseThreadLocals();
-    }
-
-    public ManagedLocalsThread(ThreadGroup group, Runnable target, String name) {
-        super(group, target, name);
-        eraseThreadLocals();
-    }
-
-    /**
-     * Drops all thread locals (and inherited thread locals).
-     */
-    public final void eraseThreadLocals() {
-        UNSAFE.putObject(this, THREAD_LOCALS, null);
-        UNSAFE.putObject(this, INHERITABLE_THREAD_LOCALS, null);
-    }
-
-    static {
-        UNSAFE = jdk.internal.misc.Unsafe.getUnsafe();
-        Class<?> t = Thread.class;
-        try {
-            THREAD_LOCALS = UNSAFE.objectFieldOffset
-                (t.getDeclaredField("threadLocals"));
-            INHERITABLE_THREAD_LOCALS = UNSAFE.objectFieldOffset
-                (t.getDeclaredField("inheritableThreadLocals"));
-        } catch (Exception e) {
-            throw new Error(e);
-        }
-    }
-}
-
--- a/jdk/test/ProblemList.txt	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/ProblemList.txt	Thu Apr 28 23:08:16 2016 -0700
@@ -319,6 +319,8 @@
 
 tools/launcher/FXLauncherTest.java                              8068049 linux-all,macosx-all
 
+tools/pack200/Pack200Props.java                                 8155857 generic-all
+
 ############################################################################
 
 # jdk_jdi
@@ -335,10 +337,6 @@
 
 com/sun/jdi/GetLocalVariables4Test.sh                           8067354 windows-all
 
-com/sun/jdi/InterfaceMethodsTest.java				8152586 generic-all
-
-com/sun/jdi/InvokeTest.java					8152586 generic-all
-
 ############################################################################
 
 # jdk_util
--- a/jdk/test/TEST.groups	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/TEST.groups	Thu Apr 28 23:08:16 2016 -0700
@@ -32,7 +32,6 @@
     -java/util/WeakHashMap/GCDuringIteration.java \
     -java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java \
     -java/util/concurrent/forkjoin/FJExceptionTableLeak.java \
-    -java/util/TimeZone/Bug6772689.java \
     sun/nio/cs/ISO8859x.java \
     java/nio/Buffer \
     com/sun/crypto/provider/Cipher \
@@ -43,7 +42,6 @@
     java/util/WeakHashMap/GCDuringIteration.java \
     java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java \
     java/util/concurrent/forkjoin/FJExceptionTableLeak.java \
-    java/util/TimeZone/Bug6772689.java \
     :jdk_io \
     :jdk_nio \
     -sun/nio/cs/ISO8859x.java \
--- a/jdk/test/com/sun/jdi/ShellScaffold.sh	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/com/sun/jdi/ShellScaffold.sh	Thu Apr 28 23:08:16 2016 -0700
@@ -924,7 +924,7 @@
         # If jstack exists, so will jps
         # Show stack traces of jdb and debuggee as a possible debugging aid.
         jdbCmd=`$jdk/bin/jps -v | $grep $jdbKeyword`
-        realJdbPid=`echo "$jdbCmd" | sed -e 's@ TTY.*@@'`
+        realJdbPid=`echo "$jdbCmd" | sed -e 's@ .*@@'`
         if [ ! -z "$realJdbPid" ] ; then
             echo "-- jdb process info ----------------------" >&2
             echo "      $jdbCmd"                              >&2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/jdi/SunBootClassPathEmptyTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.sun.jdi.connect.*;
+import com.sun.jdi.*;
+import java.util.Map;
+import java.util.List;
+import jdk.test.lib.Asserts;
+
+/*
+ * @test
+ * @summary Verifies that PathSearchingVirtualMachine.bootClassPath()
+ *          returns an empty list in case no bootclass path specified
+ *          regardless of sun.boot.class.path option, which is now obsolete
+ * @library /test/lib/share/classes
+ * @compile TestClass.java
+ * @compile SunBootClassPathEmptyTest.java
+ * @run main/othervm SunBootClassPathEmptyTest
+ */
+public class SunBootClassPathEmptyTest {
+
+    /**
+     * Helper class to facilitate the debuggee VM launching
+     */
+    private static class VmConnector {
+
+        LaunchingConnector lc;
+        VirtualMachine vm;
+
+        VmConnector() {
+            for (LaunchingConnector c : Bootstrap.virtualMachineManager().launchingConnectors()) {
+                System.out.println("name: " + c.name());
+                if (c.name().equals("com.sun.jdi.CommandLineLaunch")) {
+                    lc = c;
+                    break;
+                }
+            }
+            if (lc == null) {
+                throw new RuntimeException("Connector not found");
+            }
+        }
+
+        PathSearchingVirtualMachine launchVm(String cmdLine, String options) throws Exception {
+            Map<String, Connector.Argument> vmArgs = lc.defaultArguments();
+            vmArgs.get("main").setValue(cmdLine);
+            if (options != null) {
+                vmArgs.get("options").setValue(options);
+            }
+            System.out.println("Debugger is launching vm ...");
+            vm = lc.launch(vmArgs);
+            if (!(vm instanceof PathSearchingVirtualMachine)) {
+                throw new RuntimeException("VM is not a PathSearchingVirtualMachine");
+            }
+            return (PathSearchingVirtualMachine) vm;
+        }
+
+    }
+
+    private static VmConnector connector = new VmConnector();
+
+    public static void main(String[] args) throws Exception {
+        testWithObsoleteClassPathOption(null);
+        testWithObsoleteClassPathOption("someclasspath");
+    }
+
+    private static void testWithObsoleteClassPathOption(String obsoleteClassPath) throws Exception {
+        PathSearchingVirtualMachine vm = connector.launchVm("TestClass", makeClassPathOptions(obsoleteClassPath));
+        List<String> bootClassPath = vm.bootClassPath();
+        Asserts.assertNotNull(bootClassPath, "Expected bootClassPath to be empty but was null");
+        Asserts.assertEquals(0, bootClassPath.size(), "Expected bootClassPath.size() 0 but was: " + bootClassPath.size());
+    }
+
+    private static String makeClassPathOptions(String obsoleteClassPath) {
+        return obsoleteClassPath == null ? null : "-Dsun.boot.class.path=" + obsoleteClassPath;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/jdi/TestClass.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+public class TestClass {
+
+    public static void main(String[] args) {
+        System.out.println("This is a test");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Button/ActionEventTest/ActionEventTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2016, 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 6191390
+ * @summary Verify that ActionEvent is received with correct modifiers set.
+ * @run main/manual ActionEventTest
+ */
+
+import java.awt.AWTException;
+import java.awt.FlowLayout;
+import java.awt.Frame;
+import java.awt.Button;
+import java.awt.TextArea;
+import java.awt.Robot;
+import java.awt.Point;
+import java.awt.event.InputEvent;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+
+public class ActionEventTest extends Frame {
+    Button button;
+    Robot robot;
+    TextArea instructions;
+    public static boolean isProgInterruption = false;
+    static Thread mainThread = null;
+    static int sleepTime = 300000;
+
+    public ActionEventTest() {
+        try {
+            robot = new Robot();
+        } catch(AWTException e) {
+            throw new RuntimeException(e.getMessage());
+        }
+
+        button = new Button("ClickMe");
+        button.setEnabled(true);
+
+        instructions = new TextArea(10, 50);
+        instructions.setText(
+        " This is a manual test\n" +
+        " Keep the Alt, Shift & Ctrl Keys pressed &\n" +
+        " Click 'ClickMe' button with left mouse button\n" +
+        " Test exits automatically after mouse click.");
+
+        add(button);
+        add(instructions);
+        setSize(400,400);
+        setLayout(new FlowLayout());
+        pack();
+        setVisible(true);
+        robot.waitForIdle();
+
+        button.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent ae) {
+                int md = ae.getModifiers();
+                int expectedMask = ActionEvent.ALT_MASK | ActionEvent.CTRL_MASK
+                        | ActionEvent.SHIFT_MASK;
+
+                isProgInterruption = true;
+                mainThread.interrupt();
+                if ((md & expectedMask) != expectedMask) {
+                    throw new RuntimeException("Action Event modifiers"
+                        + " are not set correctly.");
+                }
+            }
+        });
+    }
+
+    public static void main(String args[]) throws Exception {
+        mainThread = Thread.currentThread();
+        ActionEventTest test = new ActionEventTest();
+        try {
+            mainThread.sleep(sleepTime);
+        } catch (InterruptedException e) {
+            if (!isProgInterruption) {
+                throw e;
+            }
+        }
+        test.dispose();
+        if (!isProgInterruption) {
+            throw new RuntimeException("Timed out after " + sleepTime / 1000
+                    + " seconds");
+        }
+    }
+}
--- a/jdk/test/java/awt/Component/CompEventOnHiddenComponent/CompEventOnHiddenComponent.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/awt/Component/CompEventOnHiddenComponent/CompEventOnHiddenComponent.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,7 +25,7 @@
 
 /*
   @test
-  @bug 6383903
+  @bug 6383903 8144166
   @summary REGRESSION: componentMoved is now getting called for some hidden components
   @author andrei.dmitriev: area=awt.component
   @run main CompEventOnHiddenComponent
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Focus/Cause/FocusCauseTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2016, 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 8080395
+  @summary consider making sun.awt.CausedFocusEvent functionality public
+  @run main FocusCauseTest
+*/
+
+
+import java.awt.*;
+import java.awt.event.FocusEvent.Cause;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.lang.IllegalArgumentException;
+import java.lang.Override;
+import java.lang.RuntimeException;
+import java.util.Arrays;
+
+public class FocusCauseTest {
+
+    private static Cause[] causes1 = {Cause.ACTIVATION,
+            Cause.UNKNOWN, Cause.UNKNOWN, Cause.TRAVERSAL_FORWARD,
+            Cause.TRAVERSAL_FORWARD, Cause.TRAVERSAL_BACKWARD,
+            Cause.TRAVERSAL_BACKWARD, Cause.TRAVERSAL_UP,
+            Cause.TRAVERSAL_DOWN, Cause.CLEAR_GLOBAL_FOCUS_OWNER};
+    private static Cause[] causes2 = new Cause[10];
+    private static int cnt;
+
+    static byte[] data =
+            {-84, -19, 0, 5, 115, 114, 0, 24, 115, 117, 110, 46, 97, 119,
+            116, 46, 67, 97, 117, 115, 101, 100, 70, 111, 99, 117, 115, 69, 118,
+            101, 110, 116, -51, 98, 39, -75, 86, 52, 107, 30, 2, 0, 1, 76, 0, 5,
+            99, 97, 117, 115, 101, 116, 0, 32, 76, 115, 117, 110, 47, 97, 119,
+            116, 47, 67, 97, 117, 115, 101, 100, 70, 111, 99, 117, 115, 69, 118,
+            101, 110, 116, 36, 67, 97, 117, 115, 101, 59, 120, 114, 0, 25, 106,
+            97, 118, 97, 46, 97, 119, 116, 46, 101, 118, 101, 110, 116, 46, 70,
+            111, 99, 117, 115, 69, 118, 101, 110, 116, 7, 68, -65, 75, 55, -113,
+            98, -52, 2, 0, 1, 90, 0, 9, 116, 101, 109, 112, 111, 114, 97, 114,
+            121, 120, 114, 0, 29, 106, 97, 118, 97, 46, 97, 119, 116, 46, 101,
+            118, 101, 110, 116, 46, 67, 111, 109, 112, 111, 110, 101, 110, 116,
+            69, 118, 101, 110, 116, 112, 109, -6, -107, 79, -87, -38, 69, 2, 0,
+            0, 120, 114, 0, 17, 106, 97, 118, 97, 46, 97, 119, 116, 46, 65, 87,
+            84, 69, 118, 101, 110, 116, -26, -85, 45, -31, 24, -33, -118, -61,
+            2, 0, 3, 90, 0, 8, 99, 111, 110, 115, 117, 109, 101, 100, 73, 0, 2,
+            105, 100, 91, 0, 5, 98, 100, 97, 116, 97, 116, 0, 2, 91, 66, 120,
+            114, 0, 21, 106, 97, 118, 97, 46, 117, 116, 105, 108, 46, 69, 118,
+            101, 110, 116, 79, 98, 106, 101, 99, 116, 76, -115, 9, 78, 24, 109,
+            125, -88, 2, 0, 0, 120, 112, 0, 0, 0, 3, -20, 112, 0, 126, 114, 0,
+            30, 115, 117, 110, 46, 97, 119, 116, 46, 67, 97, 117, 115, 101, 100,
+            70, 111, 99, 117, 115, 69, 118, 101, 110, 116, 36, 67, 97, 117, 115,
+            101, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 120, 114, 0, 14, 106, 97,
+            118, 97, 46, 108, 97, 110, 103, 46, 69, 110, 117, 109, 0, 0, 0, 0,
+            0, 0, 0, 0, 18, 0, 0, 120, 112, 116, 0};
+
+    static byte[] dataOld =
+            {-84, -19, 0, 5, 115, 114, 0, 25, 106, 97, 118, 97, 46, 97, 119,
+            116, 46, 101, 118, 101, 110, 116, 46, 70, 111, 99, 117, 115, 69,
+            118, 101, 110, 116, 7, 68, -65, 75, 55, -113, 98, -52, 2, 0, 1, 90,
+            0, 9, 116, 101, 109, 112, 111, 114, 97, 114, 121, 120, 114, 0, 29,
+            106, 97, 118, 97, 46, 97, 119, 116, 46, 101, 118, 101, 110, 116, 46,
+            67, 111, 109, 112, 111, 110, 101, 110, 116, 69, 118, 101, 110, 116,
+            112, 109, -6, -107, 79, -87, -38, 69, 2, 0, 0, 120, 114, 0, 17, 106,
+            97, 118, 97, 46, 97, 119, 116, 46, 65, 87, 84, 69, 118, 101, 110,
+            116, -26, -85, 45, -31, 24, -33, -118, -61, 2, 0, 3, 90, 0, 8, 99,
+            111, 110, 115, 117, 109, 101, 100, 73, 0, 2, 105, 100, 91, 0, 5, 98,
+            100, 97, 116, 97, 116, 0, 2, 91, 66, 120, 114, 0, 21, 106, 97, 118,
+            97, 46, 117, 116, 105, 108, 46, 69, 118, 101, 110, 116, 79, 98, 106,
+            101, 99, 116, 76, -115, 9, 78, 24, 109, 125, -88, 2, 0, 0, 120, 112,
+            0, 0, 0, 0, 100, 112, 0};
+
+    static String[] causesIn = {"UNKNOWN", "MOUSE_EVENT", "TRAVERSAL",
+            "TRAVERSAL_UP", "TRAVERSAL_DOWN", "TRAVERSAL_FORWARD",
+            "TRAVERSAL_BACKWARD", "MANUAL_REQUEST", "AUTOMATIC_TRAVERSE"
+            ,"ROLLBACK", "NATIVE_SYSTEM", "ACTIVATION",
+            "CLEAR_GLOBAL_FOCUS_OWNER", "RETARGETED"};
+
+    static FocusEvent.Cause[] causesOut = {FocusEvent.Cause.UNKNOWN,
+            FocusEvent.Cause.MOUSE_EVENT,
+            FocusEvent.Cause.TRAVERSAL, FocusEvent.Cause.TRAVERSAL_UP,
+            FocusEvent.Cause.TRAVERSAL_DOWN, FocusEvent.Cause.TRAVERSAL_FORWARD,
+            FocusEvent.Cause.TRAVERSAL_BACKWARD, FocusEvent.Cause.UNKNOWN,
+            FocusEvent.Cause.UNKNOWN, FocusEvent.Cause.ROLLBACK,
+            FocusEvent.Cause.UNEXPECTED, FocusEvent.Cause.ACTIVATION,
+            FocusEvent.Cause.CLEAR_GLOBAL_FOCUS_OWNER, FocusEvent.Cause.UNKNOWN
+    };
+
+    public static void main(String[] args) throws Exception {
+        testCauses();
+        testNullCause();
+        testCausedFocusEventDeserialization();
+        testFocusEventDeserialization();
+        System.out.println("ok");
+    }
+
+    private static void testNullCause() {
+        try {
+            new FocusEvent(new Frame(), FocusEvent.FOCUS_GAINED, true,
+                    null, null);
+            throw new RuntimeException("Exception is not thrown when the " +
+                    "cause is null");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    private static void testCauses() throws Exception {
+        cnt = 0;
+        Frame frame = new Frame();
+        TextField comp1 = new TextField();
+        comp1.addFocusListener(new FocusListener() {
+            @Override
+            public void focusGained(FocusEvent e) {
+                System.out.println(e.getCause());
+                causes2[cnt++] = e.getCause();
+            }
+
+            @Override
+            public void focusLost(FocusEvent e) {
+                System.out.println(e.getCause());
+                causes2[cnt++] = e.getCause();
+            }
+        });
+        TextField comp2 = new TextField();
+        comp2.addFocusListener(new FocusListener() {
+            @Override
+            public void focusGained(FocusEvent e) {
+                System.out.println(e.getCause());
+                causes2[cnt++] = e.getCause();
+            }
+
+            @Override
+            public void focusLost(FocusEvent e) {
+                System.out.println(e.getCause());
+                causes2[cnt++] = e.getCause();
+            }
+        });
+        frame.add(comp1, BorderLayout.NORTH);
+        frame.add(comp2, BorderLayout.SOUTH);
+        frame.setVisible(true);
+
+        Robot robot = new Robot();
+        robot.delay(200);
+        robot.waitForIdle();
+        comp2.requestFocus();
+        robot.waitForIdle();
+        comp2.transferFocus();
+        robot.waitForIdle();
+        comp1.transferFocusBackward();
+        robot.waitForIdle();
+        comp2.transferFocusUpCycle();
+        robot.waitForIdle();
+        frame.transferFocusDownCycle();
+        robot.waitForIdle();
+        frame.dispose();
+        robot.waitForIdle();
+        if (!Arrays.equals(causes1, causes2)) {
+            throw new RuntimeException("wrong cause " + causes2);
+        }
+    }
+
+    private static void  testCausedFocusEventDeserialization() throws
+            Exception {
+        for (int i = 0; i < causesIn.length; i++) {
+            final String causeIn = causesIn[i];
+            ObjectInputStream oi = new ObjectInputStream(new InputStream() {
+                int cnt = 0;
+                @Override
+                public int read() throws IOException {
+                    if(cnt < data.length) {
+                        return data[cnt++];
+                    } else if(cnt == data.length){
+                        cnt++;
+                        return causeIn.length();
+                    } else if(cnt - data.length - 1 < causeIn.length()) {
+                        return causeIn.getBytes()[cnt++ - data.length - 1];
+                    }
+                    return -1;
+                }
+            });
+            FocusEvent ev = (FocusEvent) oi.readObject();
+            System.out.println(ev);
+            if(ev.getCause() != causesOut[i]) {
+                throw new RuntimeException("Wrong cause read :" +ev.getCause());
+            }
+        }
+    }
+
+    private static void testFocusEventDeserialization() throws
+            Exception {
+        ObjectInputStream oi = new ObjectInputStream(
+                new ByteArrayInputStream(dataOld));
+        FocusEvent ev = (FocusEvent)oi.readObject();
+        if(ev.getCause() != FocusEvent.Cause.UNKNOWN) {
+            throw new RuntimeException("Wrong cause in deserialized FocusEvent "
+                    + ev.getCause());
+        }
+    }
+
+}
--- a/jdk/test/java/awt/FontClass/CreateFont/CreateFontArrayTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/awt/FontClass/CreateFont/CreateFontArrayTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -23,9 +23,9 @@
 
 /*
  * @test
- * @bug 8055463
+ * @bug 8055463 8153272
  * @summary Test createFont APIs
- * @run CreateFontArrayTest
+ * @run main CreateFontArrayTest
  */
 
 import java.awt.Font;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/FontClass/TextRequiresLayoutTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2016, 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 8146324
+ * @summary Test Font.textRequiresLayout
+ */
+
+import java.awt.Font;
+
+public class TextRequiresLayoutTest {
+
+    public static void main(String args[]) {
+
+        String simpleStr = "Hello World";
+        String complexStr = "\u0641\u0642\u0643";
+        char[] simpleChars = simpleStr.toCharArray();
+        char[] complexChars = complexStr.toCharArray();
+
+        if (Font.textRequiresLayout(simpleChars, 0, simpleChars.length)) {
+            throw new RuntimeException("Simple text should not need layout");
+        }
+
+        if (!Font.textRequiresLayout(complexChars, 0, complexChars.length)) {
+            throw new RuntimeException("Complex text should need layout");
+        }
+
+        if (Font.textRequiresLayout(complexChars, 0, 0)) {
+            throw new RuntimeException("Empty text should not need layout");
+        }
+
+        boolean except = false;
+        try {
+             Font.textRequiresLayout(null, 0, 0);
+        } catch (NullPointerException npe) {
+           except = true;
+        }
+        if (!except) {
+            throw new RuntimeException("No expected IllegalArgumentException");
+        }
+
+        except = false;
+        try {
+             Font.textRequiresLayout(complexChars, -1, 0);
+        } catch (ArrayIndexOutOfBoundsException aioobe) {
+           except = true;
+        }
+        if (!except) {
+            throw new
+                RuntimeException("No expected ArrayIndexOutOfBoundsException");
+        }
+
+        except = false;
+        try {
+             Font.textRequiresLayout(complexChars, 0, complexChars.length+1);
+        } catch (ArrayIndexOutOfBoundsException aioobe) {
+           except = true;
+        }
+        if (!except) {
+            throw new
+                RuntimeException("No expected ArrayIndexOutOfBoundsException");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/List/ActionEventTest/ActionEventTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2016, 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 6191390
+ * @summary Verify that ActionEvent is received with correct modifiers set.
+ * @run main ActionEventTest
+ */
+
+import java.awt.AWTException;
+import java.awt.FlowLayout;
+import java.awt.Frame;
+import java.awt.List;
+import java.awt.Robot;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+
+public class ActionEventTest extends Frame {
+    List list;
+    Robot robot;
+
+    public ActionEventTest() {
+        try {
+            robot = new Robot();
+        } catch(AWTException e) {
+            throw new RuntimeException(e.getMessage());
+        }
+
+        list = new List(1, false);
+        list.add("0");
+        add(list);
+        setSize(400,400);
+        setLayout(new FlowLayout());
+        pack();
+        setVisible(true);
+        robot.waitForIdle();
+    }
+
+    void performTest() {
+        list.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent ae) {
+                int md = ae.getModifiers();
+                int expectedMask = ActionEvent.ALT_MASK | ActionEvent.CTRL_MASK
+                        | ActionEvent.SHIFT_MASK;
+
+                if ((md & expectedMask) != expectedMask) {
+
+                    robot.keyRelease(KeyEvent.VK_ALT);
+                    robot.keyRelease(KeyEvent.VK_SHIFT);
+                    robot.keyRelease(KeyEvent.VK_CONTROL);
+                    dispose();
+                    throw new RuntimeException("Action Event modifiers are not"
+                        + " set correctly.");
+                }
+            }
+        });
+
+        list.select(0);
+        robot.keyPress(KeyEvent.VK_ALT);
+        robot.keyPress(KeyEvent.VK_SHIFT);
+        robot.keyPress(KeyEvent.VK_CONTROL);
+        // Press Enter on list item, to generate action event.
+        robot.keyPress(KeyEvent.VK_ENTER);
+        robot.keyRelease(KeyEvent.VK_ENTER);
+        robot.waitForIdle();
+        robot.keyRelease(KeyEvent.VK_ALT);
+        robot.keyRelease(KeyEvent.VK_SHIFT);
+        robot.keyRelease(KeyEvent.VK_CONTROL);
+        robot.waitForIdle();
+    }
+
+    public static void main(String args[]) {
+       ActionEventTest test = new ActionEventTest();
+       test.performTest();
+       test.dispose();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/List/ItemEventTest/ItemEventTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2016, 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 8033936
+ *  @summary Verify that correct ItemEvent is received while selection &
+ *           deselection of multi select List items.
+ */
+
+import java.awt.AWTException;
+import java.awt.Event;
+import java.awt.FlowLayout;
+import java.awt.Frame;
+import java.awt.List;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.event.KeyEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+
+public class ItemEventTest extends Frame
+{
+    List list;
+    final String expectedSelectionOrder;
+    StringBuilder actualSelectionOrder;
+    Robot robot;
+
+    public ItemEventTest()
+    {
+        try {
+            robot = new Robot();
+        } catch(AWTException e) {
+            throw new RuntimeException(e.getMessage());
+        }
+        expectedSelectionOrder = "01230123";
+
+        list = new List(4, true);
+        list.add("0");
+        list.add("1");
+        list.add("2");
+        list.add("3");
+
+        add(list);
+        setSize(400,400);
+        setLayout(new FlowLayout());
+        pack();
+        setVisible(true);
+        robot.waitForIdle();
+    }
+
+    @Override
+    public boolean handleEvent(Event e) {
+        if (e.target instanceof List) {
+            if (e.id == Event.LIST_DESELECT || e.id == Event.LIST_SELECT) {
+                actualSelectionOrder.append(e.arg);
+            }
+        }
+        return true;
+    }
+
+    void testHandleEvent() {
+        // When no ItemListener is added to List, parent's handleEvent is
+        // called with ItemEvent.
+        performTest();
+    }
+
+    void testItemListener() {
+        list.addItemListener(new ItemListener() {
+            @Override
+            public void itemStateChanged(ItemEvent ie) {
+                actualSelectionOrder.append(ie.getItem());
+            }
+        });
+        performTest();
+    }
+
+    void performTest() {
+        actualSelectionOrder = new StringBuilder();
+        Point loc = list.getLocationOnScreen();
+        Rectangle rect = list.getBounds();
+        int dY = rect.height / list.getItemCount();
+        loc = new Point(loc.x + 10, loc.y + 5);
+
+        String osName = System.getProperty("os.name");
+        boolean isMac = osName.contains("Mac") || osName.contains("mac");
+        if(isMac) {
+            robot.keyPress(KeyEvent.VK_META);
+        }
+
+        // First loop to select & Second loop to deselect the list items.
+        for (int j = 0; j < 2; ++j) {
+            for (int i = 0; i < list.getItemCount(); ++i) {
+                robot.mouseMove(loc.x, loc.y + i * dY);
+                robot.mousePress(InputEvent.BUTTON1_MASK);
+                robot.delay(100);
+                robot.mouseRelease(InputEvent.BUTTON1_MASK);
+                robot.waitForIdle();
+            }
+        }
+
+        if(isMac) {
+            robot.keyRelease(KeyEvent.VK_META);
+        }
+
+        if (!expectedSelectionOrder.equals(actualSelectionOrder.toString())) {
+            dispose();
+            throw new RuntimeException("ItemEvent for selection & deselection"
+                + " of multi select List's item is not correct"
+                + " Expected : " + expectedSelectionOrder
+                + " Actual : " + actualSelectionOrder);
+        }
+    }
+
+    public static void main(String args[]) {
+       ItemEventTest test = new ItemEventTest();
+       test.testHandleEvent();
+       test.testItemListener();
+       test.dispose();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/MenuBar/ActionEventTest/ActionEventTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2016, 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 6191390
+ * @summary Verify that ActionEvent is received with correct modifiers set.
+ * @run main/manual ActionEventTest
+ */
+
+import java.awt.Frame;
+import java.awt.Menu;
+import java.awt.MenuBar;
+import java.awt.MenuItem;
+import java.awt.TextArea;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+public final class ActionEventTest extends Frame {
+
+    MenuBar menuBar;
+    TextArea instructions;
+    public static boolean isProgInterruption = false;
+    static Thread mainThread = null;
+    static int sleepTime = 300000;
+
+    public ActionEventTest() {
+        menuBar = new MenuBar();
+        Menu menu = new Menu("Menu1");
+        MenuItem menuItem = new MenuItem("MenuItem");
+
+        menuItem.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent ae) {
+                System.out.println("actionPerformed");
+                int md = ae.getModifiers();
+                int expectedMask = ActionEvent.ALT_MASK | ActionEvent.CTRL_MASK
+                        | ActionEvent.SHIFT_MASK;
+
+                isProgInterruption = true;
+                mainThread.interrupt();
+                if ((md & expectedMask) != expectedMask) {
+                    throw new RuntimeException("Action Event modifiers are not"
+                        + " set correctly.");
+                }
+            }
+        });
+        menu.add(menuItem);
+        menuBar.add(menu);
+        setMenuBar(menuBar);
+
+        instructions = new TextArea(10, 50);
+        instructions.setText(
+        " This is a manual test\n" +
+        " Keep the Alt, Shift & Ctrl Keys pressed while doing next steps\n" +
+        " Click 'Menu1' Menu from the Menu Bar\n" +
+        " It will show 'MenuItem'\n" +
+        " Left mouse Click the 'MenuItem'\n" +
+        " Test exits automatically after mouse click.");
+        add(instructions);
+
+        setSize(400, 400);
+        setVisible(true);
+        validate();
+    }
+
+
+    public static void main(final String[] args) throws Exception {
+        mainThread = Thread.currentThread();
+        ActionEventTest test = new ActionEventTest();
+        try {
+            mainThread.sleep(sleepTime);
+        } catch (InterruptedException e) {
+            if (!isProgInterruption) {
+                throw e;
+            }
+        }
+        test.dispose();
+        if (!isProgInterruption) {
+            throw new RuntimeException("Timed out after " + sleepTime / 1000
+                    + " seconds");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/PrintJob/JobAttrUpdateTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2016, 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 6357905
+ * @summary  JobAttributes.getFromPage() and getToPage() always returns 1
+ * @run main/manual JobAttrUpdateTest
+ */
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.JobAttributes;
+import java.awt.PrintJob;
+import java.awt.Toolkit;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+
+public class JobAttrUpdateTest {
+
+    private static Thread mainThread;
+    private static boolean testPassed;
+    private static boolean testGeneratedInterrupt;
+
+    public static void main(String[] args) throws Exception {
+        SwingUtilities.invokeAndWait(() -> {
+            doTest(JobAttrUpdateTest::printTest);
+        });
+        mainThread = Thread.currentThread();
+        try {
+            Thread.sleep(30000);
+        } catch (InterruptedException e) {
+            if (!testPassed && testGeneratedInterrupt) {
+                throw new RuntimeException(""
+                        + "JobAttributes.getFromPage(),getToPage() not updated correctly");
+            }
+        }
+        if (!testGeneratedInterrupt) {
+            throw new RuntimeException("user has not executed the test");
+        }
+    }
+
+    private static void printTest() {
+        JobAttributes ja = new JobAttributes();
+
+        Toolkit tk = Toolkit.getDefaultToolkit();
+        // ja.setToPage(4);
+        // ja.setFromPage(3);
+        // show dialog
+        PrintJob pjob = tk.getPrintJob(new JFrame(), "test", ja, null);
+        if (pjob == null) {
+            return;
+        }
+
+
+        if (ja.getDefaultSelection() == JobAttributes.DefaultSelectionType.RANGE) {
+            int fromPage = ja.getFromPage();
+            int toPage = ja.getToPage();
+            if (fromPage != 2 || toPage != 3) {
+                fail();
+            } else {
+                pass();
+            }
+        }
+    }
+
+    public static synchronized void pass() {
+        testPassed = true;
+        testGeneratedInterrupt = true;
+        mainThread.interrupt();
+    }
+
+    public static synchronized void fail() {
+        testPassed = false;
+        testGeneratedInterrupt = true;
+        mainThread.interrupt();
+    }
+
+    private static void doTest(Runnable action) {
+        String description
+                = " A print dialog will be shown.\n "
+                + " Please select Pages within Page-range.\n"
+                + " and enter From 2 and To 3. Then Select OK.";
+
+        final JDialog dialog = new JDialog();
+        dialog.setTitle("JobAttribute Updation Test");
+        JTextArea textArea = new JTextArea(description);
+        textArea.setEditable(false);
+        final JButton testButton = new JButton("Start Test");
+
+        testButton.addActionListener((e) -> {
+            testButton.setEnabled(false);
+            action.run();
+        });
+        JPanel mainPanel = new JPanel(new BorderLayout());
+        mainPanel.add(textArea, BorderLayout.CENTER);
+        JPanel buttonPanel = new JPanel(new FlowLayout());
+        buttonPanel.add(testButton);
+        mainPanel.add(buttonPanel, BorderLayout.SOUTH);
+        dialog.add(mainPanel);
+        dialog.pack();
+        dialog.setVisible(true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/PrintJob/NullFrameTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016, 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 8154057
+ * @summary  getPrintJob doesn't throw NPE if frame is null
+ * @run main NullFrameTest
+ */
+import java.awt.JobAttributes;
+import java.awt.Toolkit;
+
+public class NullFrameTest {
+    public static void main(String[] args) {
+        JobAttributes ja = new JobAttributes();
+        ja.setDialog(JobAttributes.DialogType.COMMON);
+        boolean npeThrown = false;
+        try {
+            Toolkit.getDefaultToolkit().getPrintJob(null,
+                                               "test Printing", ja, null);
+        } catch (NullPointerException ex) {
+            npeThrown = true;
+        }
+        if (!npeThrown) {
+            throw
+            new RuntimeException("getPrintJob didn't throw NPE for null Frame");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/TrayIcon/ActionEventTest/ActionEventTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2016, 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 6191390
+ * @summary Verify that ActionEvent is received with correct modifiers set.
+ * @library ../../../../lib/testlibrary ../
+ * @build ExtendedRobot SystemTrayIconHelper
+ */
+
+import java.awt.Image;
+import java.awt.TrayIcon;
+import java.awt.SystemTray;
+import java.awt.Robot;
+import java.awt.EventQueue;
+import java.awt.Point;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.awt.image.BufferedImage;
+
+public class ActionEventTest {
+
+    Image image;
+    TrayIcon icon;
+    Robot robot;
+
+    public static void main(String[] args) throws Exception {
+        if (!SystemTray.isSupported()) {
+            System.out.println("SystemTray not supported on the platform." +
+                " Marking the test passed.");
+        } else {
+            if (System.getProperty("os.name").toLowerCase().startsWith("win")) {
+                System.err.println(
+                    "Test can fail on Windows platform\n"+
+                    "On Windows 7, by default icon hides behind icon pool\n" +
+                    "Due to which test might fail\n" +
+                    "Set \"Right mouse click\" -> " +
+                    "\"Customize notification icons\" -> \"Always show " +
+                    "all icons and notifications on the taskbar\" true " +
+                    "to avoid this problem.\nOR change behavior only for " +
+                    "Java SE tray icon and rerun test.");
+            }
+
+            ActionEventTest test = new ActionEventTest();
+            test.doTest();
+            test.clear();
+        }
+    }
+
+    public ActionEventTest() throws Exception {
+        robot = new Robot();
+        EventQueue.invokeAndWait(this::initializeGUI);
+    }
+
+    private void initializeGUI() {
+
+        icon = new TrayIcon(
+            new BufferedImage(20, 20, BufferedImage.TYPE_INT_RGB), "ti");
+        icon.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent ae) {
+                int md = ae.getModifiers();
+                int expectedMask = ActionEvent.ALT_MASK | ActionEvent.CTRL_MASK
+                        | ActionEvent.SHIFT_MASK;
+
+                if ((md & expectedMask) != expectedMask) {
+                    clear();
+                    throw new RuntimeException("Action Event modifiers are not"
+                        + " set correctly.");
+                }
+            }
+        });
+
+        try {
+            SystemTray.getSystemTray().add(icon);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public void clear() {
+        SystemTray.getSystemTray().remove(icon);
+    }
+
+    void doTest() throws Exception {
+        robot.keyPress(KeyEvent.VK_ALT);
+        robot.keyPress(KeyEvent.VK_SHIFT);
+        robot.keyPress(KeyEvent.VK_CONTROL);
+
+        Point iconPosition = SystemTrayIconHelper.getTrayIconLocation(icon);
+        if (iconPosition == null) {
+            throw new RuntimeException("Unable to find the icon location!");
+        }
+
+        robot.mouseMove(iconPosition.x, iconPosition.y);
+        robot.waitForIdle();
+
+        robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+        robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+        robot.delay(100);
+        robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+        robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+        robot.delay(100);
+        robot.waitForIdle();
+        robot.keyRelease(KeyEvent.VK_ALT);
+        robot.keyRelease(KeyEvent.VK_SHIFT);
+        robot.keyRelease(KeyEvent.VK_CONTROL);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/TrayIcon/UpdatePopupMenu/UpdatePopupMenu.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2016, 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 8147841
+ @summary Updating Tray Icon popup menu does not update menu items on Mac OS X
+ @run main/manual UpdatePopupMenu
+ */
+
+import java.awt.SystemTray;
+import java.awt.TrayIcon;
+import java.awt.PopupMenu;
+import java.awt.MenuItem;
+import java.awt.Image;
+import java.awt.Graphics2D;
+import java.awt.Color;
+import java.awt.image.BufferedImage;
+import java.awt.RenderingHints;
+import java.awt.AWTException;
+import java.awt.Button;
+import java.awt.Frame;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Panel;
+import java.awt.TextArea;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+public class UpdatePopupMenu implements ActionListener {
+
+    private static final int imageSize = 32;
+    private static final int imageInset = 4;
+    private static GridBagLayout layout;
+    private static Panel mainControlPanel;
+    private static Panel resultButtonPanel;
+    private static TextArea instructionTextArea;
+    private static Button passButton;
+    private static Button failButton;
+    private static Frame mainFrame;
+    private static Thread mainThread = null;
+    private static boolean testPassed = false;
+    private static boolean isInterrupted = false;
+    private static final int testTimeOut = 300000;
+
+    private Image createSystemTrayIconImage() {
+        final BufferedImage trayImage = new BufferedImage(
+                imageSize,
+                imageSize,
+                BufferedImage.TYPE_INT_ARGB);
+
+        final Graphics2D imageGraphics = (Graphics2D) trayImage.getGraphics();
+
+        imageGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                RenderingHints.VALUE_ANTIALIAS_ON);
+
+        imageGraphics.setColor(new Color(255, 255, 255, 0));
+        imageGraphics.fillRect(0, 0, trayImage.getWidth(),
+                trayImage.getHeight());
+
+        imageGraphics.setColor(Color.green);
+
+        int imageWidth = trayImage.getWidth() - 2 * imageInset;
+        int imageHeight = trayImage.getHeight() - 2 * imageInset;
+
+        imageGraphics.fillOval(imageInset, imageInset, imageWidth, imageHeight);
+        imageGraphics.setColor(Color.darkGray);
+        imageGraphics.drawOval(imageInset, imageInset, imageWidth, imageHeight);
+
+        return trayImage;
+    }
+
+    private PopupMenu createPopupMenu(final TrayIcon trayIcon,
+            final int menuCount) {
+
+        final PopupMenu trayIconPopupMenu = new PopupMenu();
+
+        for (int i = 1; i <= menuCount; ++i) {
+            final MenuItem popupMenuItem = new MenuItem("MenuItem_" + i);
+
+            popupMenuItem.addActionListener(new ActionListener() {
+                @Override
+                public void actionPerformed(final ActionEvent ae) {
+                    trayIcon.setPopupMenu(createPopupMenu(trayIcon,
+                            menuCount + 1));
+                }
+            });
+
+            trayIconPopupMenu.add(popupMenuItem);
+        }
+
+        return trayIconPopupMenu;
+    }
+
+    private void createSystemTrayIcons() {
+
+        final TrayIcon trayIcon = new TrayIcon(createSystemTrayIconImage());
+        trayIcon.setImageAutoSize(true);
+        trayIcon.setToolTip("Update Popup Menu items");
+
+        try {
+            trayIcon.setPopupMenu(createPopupMenu(trayIcon, 2));
+            SystemTray.getSystemTray().add(trayIcon);
+
+        } catch (AWTException ex) {
+            throw new RuntimeException("System Tray cration failed");
+        }
+    }
+
+    private void createInstructionUI() {
+        mainFrame = new Frame("Updating TrayIcon Popup Menu Item Test");
+        layout = new GridBagLayout();
+        mainControlPanel = new Panel(layout);
+        resultButtonPanel = new Panel(layout);
+
+        GridBagConstraints gbc = new GridBagConstraints();
+        String instructions
+                = "INSTRUCTIONS:"
+                + "\n   1. Click on the System Tray Icon"
+                + "\n   2. Click on any of the displayed Menu items"
+                + "\n   3. Repeat step 1 and count the number of items in the "
+                + "Menu"
+                + "\n   4. The number of items in the Menu should increase by 1"
+                + "\n   5. Repeating steps 1, 2 and 3 should not break 4th step"
+                + "\n   6. Click Fail if the 4th step is broken, Otherwise "
+                + "click Pass ";
+
+        instructionTextArea = new TextArea();
+        instructionTextArea.setText(instructions);
+        instructionTextArea.setEnabled(false);
+        instructionTextArea.setBackground(Color.white);
+
+        gbc.gridx = 0;
+        gbc.gridy = 0;
+        gbc.fill = GridBagConstraints.HORIZONTAL;
+        mainControlPanel.add(instructionTextArea, gbc);
+
+        passButton = new Button("Pass");
+        passButton.setName("Pass");
+        passButton.addActionListener(this);
+
+        failButton = new Button("Fail");
+        failButton.setName("Fail");
+        failButton.addActionListener(this);
+
+        gbc.gridx = 0;
+        gbc.gridy = 0;
+        resultButtonPanel.add(passButton, gbc);
+        gbc.gridx = 1;
+        gbc.gridy = 0;
+        resultButtonPanel.add(failButton, gbc);
+        gbc.gridx = 0;
+        gbc.gridy = 1;
+        mainControlPanel.add(resultButtonPanel, gbc);
+
+        mainFrame.add(mainControlPanel);
+        mainFrame.pack();
+        mainFrame.setVisible(true);
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent ae) {
+        if (ae.getSource() instanceof Button) {
+            Button btn = (Button) ae.getSource();
+            switch (btn.getName()) {
+                case "Pass":
+                    testPassed = true;
+                    isInterrupted = true;
+                    mainThread.interrupt();
+                    break;
+
+                case "Fail":
+                    testPassed = false;
+                    isInterrupted = true;
+                    mainThread.interrupt();
+                    break;
+            }
+        }
+    }
+
+    private static void cleanUp() {
+        mainFrame.dispose();
+    }
+
+    public static void main(final String[] args) throws Exception {
+        if (SystemTray.isSupported()) {
+
+            UpdatePopupMenu updatePopupMenu = new UpdatePopupMenu();
+            updatePopupMenu.createInstructionUI();
+            updatePopupMenu.createSystemTrayIcons();
+
+            mainThread = Thread.currentThread();
+            try {
+                mainThread.sleep(testTimeOut);
+            } catch (InterruptedException ex) {
+                if (!testPassed) {
+                    throw new RuntimeException("Updating TrayIcon popup menu"
+                            + " items FAILED");
+                }
+            } finally {
+                cleanUp();
+            }
+
+            if (!isInterrupted) {
+                throw new RuntimeException("Test Timed out after "
+                        + testTimeOut / 1000 + " seconds");
+            }
+
+        } else {
+            System.out.println("System Tray is not supported on this platform");
+        }
+    }
+}
--- a/jdk/test/java/awt/dnd/DisposeFrameOnDragCrash/DisposeFrameOnDragTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/awt/dnd/DisposeFrameOnDragCrash/DisposeFrameOnDragTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016 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,17 +56,24 @@
             }
         });
 
-        Util.waitForIdle(null);
+        Robot testRobot = null;
         try {
-            Point loc = textArea.getLocationOnScreen();
-            Util.drag(new Robot(),
-                    new Point((int) loc.x + 3, (int) loc.y + 3),
-                    new Point((int) loc.x + 40, (int) loc.y + 40),
-                    InputEvent.BUTTON1_MASK);
-        } catch (AWTException ex) {
-            throw new RuntimeException("Could not initiate a drag operation");
+            testRobot = new Robot();
+        } catch(AWTException ex) {
+            throw new RuntimeException("Error while creating Robot");
         }
-        Util.waitForIdle(null);
+
+        Util.waitForIdle(testRobot);
+
+        Point loc = textArea.getLocationOnScreen();
+        Util.drag(testRobot,
+                new Point((int) loc.x + 3, (int) loc.y + 3),
+                new Point((int) loc.x + 40, (int) loc.y + 40),
+                InputEvent.BUTTON1_MASK);
+
+        Util.waitForIdle(testRobot);
+
+        testRobot.delay(200);
     }
 
     private static void constructTestUI() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/font/MonospacedGlyphWidth/MonospacedGlyphWidthTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016, 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 8073400
+ * @summary Some Monospaced logical fonts have a different width
+ * @author Dmitry Markov
+ * @run main MonospacedGlyphWidthTest
+ */
+import java.awt.*;
+import java.awt.font.FontRenderContext;
+
+public class MonospacedGlyphWidthTest {
+    private static final int START_INDEX = 0x2018;
+    private static final int END_INDEX = 0x201F;
+
+    public static void main(String[] args) {
+        Font font = new Font(Font.MONOSPACED, Font.PLAIN, 12);
+        double width = getCharWidth(font, 'a');
+
+        for (int i = START_INDEX; i <= END_INDEX; i++) {
+            if (width != getCharWidth(font, (char)i)) {
+                throw new RuntimeException("Test Failed: characters have different width!");
+            }
+        }
+        System.out.println("Test Passed!");
+    }
+
+    private static double getCharWidth(Font font, char c) {
+        FontRenderContext fontRenderContext = new FontRenderContext(null, false, false);
+        return font.getStringBounds(new char[] {c}, 0, 1, fontRenderContext).getWidth();
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/image/RasterCreationTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Point;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferDouble;
+import java.awt.image.DataBufferFloat;
+import java.awt.image.DataBufferInt;
+import java.awt.image.DataBufferShort;
+import java.awt.image.DataBufferUShort;
+import java.awt.image.Raster;
+import java.awt.image.SampleModel;
+import java.awt.image.MultiPixelPackedSampleModel;
+import java.awt.image.PixelInterleavedSampleModel;
+import java.awt.image.SinglePixelPackedSampleModel;
+
+/*
+ * @test
+ * @bug  6353518
+ * @summary  Test possible combinations of Raster creation
+ *           Test fails if any of Raster.createXXX() method throws exception.
+ */
+public class RasterCreationTest {
+
+    public static void main(String[] args) {
+
+        final int width = 10;
+        final int height = 5;
+        final int imageSize = width * height;
+        Point location = new Point(0, 0);
+        int[] bandOffsets = {0};
+        int[] bitMask = {0x00ff0000, 0x0000ff00, 0xff, 0x0};
+
+        SampleModel[] inputSampleModels = {
+            new PixelInterleavedSampleModel(DataBuffer.TYPE_BYTE,
+                    1, 1, 1, 1, bandOffsets),
+            new PixelInterleavedSampleModel(DataBuffer.TYPE_USHORT,
+                    1, 1, 1, 1, bandOffsets),
+            new PixelInterleavedSampleModel(DataBuffer.TYPE_INT,
+                    1, 1, 1, 1, bandOffsets),
+            new SinglePixelPackedSampleModel(DataBuffer.TYPE_BYTE,
+                    width, height, bitMask),
+            new SinglePixelPackedSampleModel(DataBuffer.TYPE_USHORT,
+                    width, height, bitMask),
+            new SinglePixelPackedSampleModel(DataBuffer.TYPE_INT,
+                    width, height, bitMask),
+            new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE,
+                    width, height, 4),
+            new MultiPixelPackedSampleModel(DataBuffer.TYPE_USHORT,
+                    width, height, 2),
+            new MultiPixelPackedSampleModel(DataBuffer.TYPE_INT,
+                    width, height, 2)
+        };
+
+        // ---------------------------------------------------------------------
+        // Test ability to create Raster & WritableRaster with DataBuffer
+        // classes
+        // ---------------------------------------------------------------------
+        DataBuffer[] inputDataBuffer = {
+            new DataBufferByte(imageSize),
+            new DataBufferUShort(imageSize),
+            new DataBufferInt(imageSize, 1),
+            new DataBufferShort(imageSize),
+            new DataBufferFloat(imageSize),
+            new DataBufferDouble(imageSize)
+        };
+
+        for (SampleModel sm : inputSampleModels) {
+            for (DataBuffer db : inputDataBuffer) {
+                // Test Raster creation
+                Raster.createRaster(sm, db, location);
+
+                // Test writableRaster creation
+                Raster.createWritableRaster(sm, db, location);
+                Raster.createWritableRaster(sm, location);
+            }
+        }
+
+        // ---------------------------------------------------------------------
+        // Test ability to create Raster & WritableRaster with custom DataBuffer
+        // classes
+        // ---------------------------------------------------------------------
+        DataBuffer[] myDataBuffer = {
+            new MyDataBufferByte(imageSize),
+            new MyDataBufferUShort(imageSize),
+            new MyDataBufferInt(imageSize),
+            new MyDataBufferShort(imageSize),
+            new MyDataBufferDouble(imageSize),
+            new MyDataBufferFloat(imageSize)
+        };
+
+        for (SampleModel sm : inputSampleModels) {
+            for (DataBuffer db : myDataBuffer) {
+                // Test Raster creation
+                Raster.createRaster(sm, db, location);
+
+                // Test writableRaster creation
+                Raster.createWritableRaster(sm, db, location);
+                Raster.createWritableRaster(sm, location);
+            }
+        }
+
+        // ---------------------------------------------------------------------
+        // Test ability to create InterleavedRaster
+        // ---------------------------------------------------------------------
+        int[] interleavedInputDataTypes = {
+            DataBuffer.TYPE_BYTE,
+            DataBuffer.TYPE_USHORT
+        };
+
+        int numBands = 1;
+
+        for (int i : interleavedInputDataTypes) {
+            Raster.createInterleavedRaster(i, width, height, 1, location);
+            Raster.createInterleavedRaster(i, width, height, width * numBands,
+                    numBands, bandOffsets, location);
+        }
+
+        for (int i = 0; i < interleavedInputDataTypes.length ; i++) {
+            DataBuffer d1 = inputDataBuffer[i];
+            DataBuffer d2 = myDataBuffer[i];
+
+            Raster.createInterleavedRaster(d1, width, height, width * numBands,
+                    numBands, bandOffsets, location);
+            Raster.createInterleavedRaster(d2, width, height, width * numBands,
+                    numBands, bandOffsets, location);
+        }
+
+        // ---------------------------------------------------------------------
+        // Test ability to create BandedRaster
+        // ---------------------------------------------------------------------
+        int[] bankIndices = new int[numBands];
+        bankIndices[0] = 0;
+
+        int[] bandedInputDataTypes = {
+            DataBuffer.TYPE_BYTE,
+            DataBuffer.TYPE_USHORT,
+            DataBuffer.TYPE_INT
+        };
+
+        for (int i : bandedInputDataTypes) {
+            Raster.createBandedRaster(i, width, height, 1, location);
+            Raster.createBandedRaster(i, width, height, width,
+                    bankIndices, bandOffsets, location);
+        }
+
+        for (int i = 0; i < bandedInputDataTypes.length; i++) {
+            DataBuffer d1 = inputDataBuffer[i];
+            DataBuffer d2 = myDataBuffer[i];
+
+            Raster.createBandedRaster(d1, width, height, width,
+                    bankIndices, bandOffsets, location);
+            Raster.createBandedRaster(d2, width, height, width,
+                    bankIndices, bandOffsets, location);
+        }
+
+        // ---------------------------------------------------------------------
+        // Test ability to create PackedRaster
+        // ---------------------------------------------------------------------
+        int[] bandMasks = new int[numBands];
+        bandMasks[0] = 0;
+
+        int packedInputDataTypes[] = {
+            DataBuffer.TYPE_BYTE,
+            DataBuffer.TYPE_USHORT,
+            DataBuffer.TYPE_INT
+        };
+
+        for (int i : packedInputDataTypes) {
+            Raster.createPackedRaster(i, width, height, bandMasks, location);
+
+            for (int bits = 1; bits < 5; bits *= 2) {
+                Raster.createPackedRaster(i, width, height, 1, bits, location);
+            }
+        }
+
+        for (int i = 0; i < packedInputDataTypes.length; i++) {
+            DataBuffer d1 = inputDataBuffer[i];
+            DataBuffer d2 = myDataBuffer[i];
+
+            for (int bits = 1; bits < 5; bits *= 2) {
+                Raster.createPackedRaster(d1, width, height, bits, location);
+                Raster.createPackedRaster(d2, width, height, bits, location);
+            }
+
+            Raster.createPackedRaster(d1, width, height, 1,bandMasks, location);
+            Raster.createPackedRaster(d2, width, height, 1,bandMasks, location);
+        }
+    }
+}
+
+// ---------------------------------------------------------------------
+// Custom DataBuffer classes for testing purpose
+// ---------------------------------------------------------------------
+final class MyDataBufferByte extends DataBuffer {
+
+    byte[] data;
+    byte[][] bankdata;
+
+    public MyDataBufferByte(int size) {
+        super(TYPE_BYTE, size);
+        data = new byte[size];
+        bankdata = new byte[1][];
+        bankdata[0] = data;
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return bankdata[bank][i + offsets[bank]];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        bankdata[bank][i + offsets[bank]] = (byte) val;
+    }
+}
+
+final class MyDataBufferDouble extends DataBuffer {
+
+    double[] data;
+    double[][] bankdata;
+
+    public MyDataBufferDouble(int size) {
+        super(TYPE_DOUBLE, size);
+        data = new double[size];
+        bankdata = new double[1][];
+        bankdata[0] = data;
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return (int) bankdata[bank][i + offsets[bank]];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        bankdata[bank][i + offsets[bank]] = (double) val;
+    }
+}
+
+final class MyDataBufferFloat extends DataBuffer {
+
+    float[] data;
+    float[][] bankdata;
+
+    public MyDataBufferFloat(int size) {
+        super(TYPE_FLOAT, size);
+        data = new float[size];
+        bankdata = new float[1][];
+        bankdata[0] = data;
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return (int) bankdata[bank][i + offsets[bank]];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        bankdata[bank][i + offsets[bank]] = (float) val;
+    }
+}
+
+final class MyDataBufferShort extends DataBuffer {
+
+    short[] data;
+    short[][] bankdata;
+
+    public MyDataBufferShort(int size) {
+        super(TYPE_SHORT, size);
+        data = new short[size];
+        bankdata = new short[1][];
+        bankdata[0] = data;
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return bankdata[bank][i + offsets[bank]];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        bankdata[bank][i + offsets[bank]] = (short) val;
+    }
+}
+
+final class MyDataBufferUShort extends DataBuffer {
+
+    short[] data;
+    short[][] bankdata;
+
+    public MyDataBufferUShort(int size) {
+        super(TYPE_USHORT, size);
+        data = new short[size];
+        bankdata = new short[1][];
+        bankdata[0] = data;
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return bankdata[bank][i + offsets[bank]];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        bankdata[bank][i + offsets[bank]] = (short) val;
+    }
+}
+
+final class MyDataBufferInt extends DataBuffer {
+
+    int[] data;
+    int[][] bankdata;
+
+    public MyDataBufferInt(int size) {
+        super(TYPE_INT, size);
+        data = new int[size];
+        bankdata = new int[1][];
+        bankdata[0] = data;
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return bankdata[bank][i + offsets[bank]];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        bankdata[bank][i + offsets[bank]] = (int) val;
+    }
+}
--- a/jdk/test/java/awt/image/multiresolution/MultiResolutionTrayIconTest/MultiResolutionTrayIconTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/awt/image/multiresolution/MultiResolutionTrayIconTest/MultiResolutionTrayIconTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -24,8 +24,7 @@
 
 /*
   @test
-  @bug 8150176
-  @ignore 8150176
+  @bug 8150176 8151773
   @summary Check if correct resolution variant is used for tray icon.
   @author a.stepanov
   @run applet/manual=yesno MultiResolutionTrayIconTest.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/print/PrinterJob/DlgAttrsBug.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2016, 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 8061258
+ * @summary  PrinterJob's native Print Dialog does not reflect
+ *           specified Copies or Page Ranges
+ * @run main/manual DlgAttrsBug
+ */
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.Graphics;
+import java.awt.print.PageFormat;
+import java.awt.print.Printable;
+import java.awt.print.PrinterException;
+import java.awt.print.PrinterJob;
+import javax.print.attribute.HashPrintRequestAttributeSet;
+import javax.print.attribute.PrintRequestAttributeSet;
+import javax.print.attribute.standard.Copies;
+import javax.print.attribute.standard.PageRanges;
+import javax.print.attribute.standard.DialogTypeSelection;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+
+
+public class DlgAttrsBug implements Printable {
+    private static Thread mainThread;
+    private static boolean testPassed;
+    private static boolean testGeneratedInterrupt;
+
+    public static void main(String[] args)  throws Exception {
+        SwingUtilities.invokeAndWait(() -> {
+            doTest(DlgAttrsBug::printTest);
+        });
+        mainThread = Thread.currentThread();
+        try {
+            Thread.sleep(30000);
+        } catch (InterruptedException e) {
+            if (!testPassed && testGeneratedInterrupt) {
+                throw new RuntimeException("Print Dialog does not " +
+                          "reflect Copies or Page Ranges");
+            }
+        }
+        if (!testGeneratedInterrupt) {
+            throw new RuntimeException("user has not executed the test");
+        }
+    }
+
+    private static void printTest() {
+        PrinterJob job = PrinterJob.getPrinterJob();
+        if (job.getPrintService() == null) {
+            System.out.println("No printers. Test cannot continue");
+            return;
+        }
+        job.setPrintable(new DlgAttrsBug());
+        PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
+        aset.add(new Copies(5));
+        aset.add(new PageRanges(3,4));
+        aset.add(DialogTypeSelection.NATIVE);
+        job.printDialog(aset);
+    }
+
+    public static synchronized void pass() {
+        testPassed = true;
+        testGeneratedInterrupt = true;
+        mainThread.interrupt();
+    }
+
+    public static synchronized void fail() {
+        testPassed = false;
+        testGeneratedInterrupt = true;
+        mainThread.interrupt();
+    }
+
+    private static void doTest(Runnable action) {
+        String description
+                = " Visual inspection of print dialog is required.\n"
+                + " A print dialog will be shown.\n "
+                + " Please verify Copies 5 is selected.\n"
+                + " Also verify, Page Range is selected with "
+                + " from page 3 and to Page 4.\n"
+                + " If ok, press PASS else press FAIL";
+
+        final JDialog dialog = new JDialog();
+        dialog.setTitle("printSelectionTest");
+        JTextArea textArea = new JTextArea(description);
+        textArea.setEditable(false);
+        final JButton testButton = new JButton("Start Test");
+        final JButton passButton = new JButton("PASS");
+        passButton.setEnabled(false);
+        passButton.addActionListener((e) -> {
+            dialog.dispose();
+            pass();
+        });
+        final JButton failButton = new JButton("FAIL");
+        failButton.setEnabled(false);
+        failButton.addActionListener((e) -> {
+            dialog.dispose();
+            fail();
+        });
+        testButton.addActionListener((e) -> {
+            testButton.setEnabled(false);
+            action.run();
+            passButton.setEnabled(true);
+            failButton.setEnabled(true);
+        });
+        JPanel mainPanel = new JPanel(new BorderLayout());
+        mainPanel.add(textArea, BorderLayout.CENTER);
+        JPanel buttonPanel = new JPanel(new FlowLayout());
+        buttonPanel.add(testButton);
+        buttonPanel.add(passButton);
+        buttonPanel.add(failButton);
+        mainPanel.add(buttonPanel, BorderLayout.SOUTH);
+        dialog.add(mainPanel);
+        dialog.pack();
+        dialog.setVisible(true);
+    }
+
+    public int print(Graphics g, PageFormat pf, int pi)
+            throws PrinterException {
+        System.out.println("pi = " + pi);
+        if (pi >= 5) {
+            return NO_SUCH_PAGE;
+        }
+        g.drawString("Page : " + (pi+1), 200, 200);
+        return PAGE_EXISTS;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/print/PrinterJob/DummyPrintTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2016, 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      6921664
+ * @summary  Verifies number of copies and the job name are passed to a
+ *           3rd party PrintService.
+ * @run      main DummyPrintTest
+ */
+import java.awt.Graphics;
+import java.awt.print.PageFormat;
+import java.awt.print.Printable;
+import java.awt.print.PrinterException;
+import java.awt.print.PrinterJob;
+import java.util.HashSet;
+import java.util.Set;
+import javax.print.Doc;
+import javax.print.DocFlavor;
+import javax.print.DocPrintJob;
+import javax.print.PrintException;
+import javax.print.PrintService;
+import javax.print.PrintServiceLookup;
+import javax.print.ServiceUIFactory;
+import javax.print.attribute.Attribute;
+import javax.print.attribute.AttributeSet;
+import javax.print.attribute.HashPrintJobAttributeSet;
+import javax.print.attribute.HashPrintServiceAttributeSet;
+import javax.print.attribute.PrintJobAttributeSet;
+import javax.print.attribute.PrintRequestAttributeSet;
+import javax.print.attribute.PrintServiceAttribute;
+import javax.print.attribute.PrintServiceAttributeSet;
+import javax.print.attribute.standard.Copies;
+import javax.print.attribute.standard.JobName;
+import javax.print.attribute.standard.PrinterName;
+import javax.print.attribute.standard.PrinterState;
+import javax.print.event.PrintJobAttributeListener;
+import javax.print.event.PrintJobListener;
+import javax.print.event.PrintServiceAttributeListener;
+
+
+public class DummyPrintTest {
+
+    public static void main(String[] args) throws Exception {
+        // register custom print service implementation
+        String printerName = "myDummyPrintService";
+        PrintServiceLookup.registerService(new DummyPrintService(printerName));
+        // calling third party print logic
+        thirdPartyPrintLogic(printerName);
+    }
+
+    static void thirdPartyPrintLogic(String printerName) throws Exception {
+        PrinterJob printerjob = PrinterJob.getPrinterJob();
+        printerjob.setCopies(2);
+        printerjob.setJobName("myJobName");
+        printerjob.setPrintable(new DummyPrintable());
+        for (PrintService printService : PrinterJob.lookupPrintServices()) {
+            System.out.println("check printer name of service " + printService);
+            if (printerName.equals(printService.getName())) {
+                System.out.println("correct printer service do print...");
+                printerjob.setPrintService(printService);
+                printerjob.print();
+                break;
+            }
+        }
+    }
+}
+
+class DummyPrintService implements PrintService {
+    private final String _name;
+    private final Set<DocFlavor> _supportedFlavors;
+    private final PrintServiceAttributeSet _printServiceAttributeSet;
+
+    public DummyPrintService(String name) {
+        _name = name;
+        _supportedFlavors = new HashSet<DocFlavor>();
+        _supportedFlavors.add(DocFlavor.SERVICE_FORMATTED.PAGEABLE);
+        _supportedFlavors.add(DocFlavor.SERVICE_FORMATTED.PRINTABLE);
+        _printServiceAttributeSet = new HashPrintServiceAttributeSet();
+        _printServiceAttributeSet.add(new PrinterName(name, null));
+        _printServiceAttributeSet.add(PrinterState.IDLE);
+    }
+
+    @Override
+    public String toString() {
+        return "Dummy Printer : " + getName();
+    }
+
+    @Override
+    public String getName() {
+        return _name;
+    }
+
+    @Override
+    public DocPrintJob createPrintJob() {
+        return new DummyDocPrintJob(this);
+    }
+
+    @Override
+    public boolean isDocFlavorSupported(DocFlavor flavor) {
+        return _supportedFlavors.contains(flavor);
+    }
+
+    @Override
+    public <T extends PrintServiceAttribute> T getAttribute(Class<T> category) {
+        return category.cast(_printServiceAttributeSet.get(category));
+    }
+
+    @Override
+    public PrintServiceAttributeSet getAttributes() {
+        return _printServiceAttributeSet;
+    }
+
+    @Override
+    public DocFlavor[] getSupportedDocFlavors() {
+        return _supportedFlavors.toArray(new DocFlavor[_supportedFlavors.size()]);
+    }
+
+    @Override
+    public Object getDefaultAttributeValue(Class<? extends Attribute> category) {
+        return null;
+    }
+
+    @Override
+    public ServiceUIFactory getServiceUIFactory() {
+        return null;
+    }
+
+    @Override
+    public Class<?>[] getSupportedAttributeCategories() {
+        return null;
+    }
+
+    @Override
+    public Object getSupportedAttributeValues(Class<? extends Attribute> category,
+                                    DocFlavor flavor, AttributeSet attributes) {
+        return null;
+    }
+
+    @Override
+    public AttributeSet getUnsupportedAttributes(DocFlavor flavor,
+                                                 AttributeSet attributes) {
+        return null;
+    }
+
+    @Override
+    public boolean isAttributeCategorySupported(Class<? extends Attribute> category) {
+        return false;
+    }
+
+    @Override
+    public boolean isAttributeValueSupported(Attribute attrval,
+                                             DocFlavor flavor,
+                                             AttributeSet attributes) {
+        return false;
+    }
+
+    @Override
+    public void addPrintServiceAttributeListener(PrintServiceAttributeListener listener) {
+    }
+
+    @Override
+    public void removePrintServiceAttributeListener(PrintServiceAttributeListener listener) {
+    }
+}
+
+class DummyDocPrintJob implements DocPrintJob {
+    private static int _counter;
+    private final PrintService _printService;
+    private final PrintJobAttributeSet _printJobAttributeSet;
+
+    public DummyDocPrintJob(PrintService printService) {
+        _counter++;
+        _printService = printService;
+        _printJobAttributeSet = new HashPrintJobAttributeSet();
+    }
+
+    @Override
+    public PrintService getPrintService() {
+        return _printService;
+    }
+
+    @Override
+    public PrintJobAttributeSet getAttributes() {
+        return _printJobAttributeSet;
+    }
+
+    @Override
+    public void addPrintJobAttributeListener(PrintJobAttributeListener listener,
+                                    PrintJobAttributeSet printJobAttributeSet) {
+    }
+
+    @Override
+    public void removePrintJobAttributeListener(PrintJobAttributeListener listener) {
+    }
+
+    @Override
+    public void addPrintJobListener(PrintJobListener listener) {
+    }
+
+    @Override
+    public void removePrintJobListener(PrintJobListener listener) {
+    }
+
+    @Override
+    public void print(Doc doc,
+                      PrintRequestAttributeSet printRequestAttributeSet)
+          throws PrintException {
+        System.out.println("job name: " + printRequestAttributeSet.get(JobName.class));
+        System.out.println("copies: " + printRequestAttributeSet.get(Copies.class));
+        if(printRequestAttributeSet.get(JobName.class) == null ||
+            printRequestAttributeSet.get(Copies.class) == null) {
+            throw new RuntimeException("Copies and JobName is not passed correctly");
+        }
+    }
+}
+
+class DummyPrintable implements Printable {
+    @Override
+    public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
+            throws PrinterException {
+        if (pageIndex == 0) {
+            return Printable.PAGE_EXISTS;
+        } else {
+            return Printable.NO_SUCH_PAGE;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/print/PrinterJob/GetUserNameTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016, 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 6197099
+ * @summary Verifies PrinterJob's getUserName() throws a security exception when
+ *          username permission is not given
+ * @run main/othervm/java.security.policy=GetUserNameTest.policy GetUserNameTest
+ */
+import java.awt.print.PrinterJob;
+
+public class GetUserNameTest {
+
+    public static void main(String args[]) {
+        System.setSecurityManager(new SecurityManager());
+        PrinterJob pj = PrinterJob.getPrinterJob();
+        boolean secExcpn = false;
+        try {
+            System.out.println(pj.getUserName());
+        } catch (SecurityException ex) {
+            secExcpn = true;
+            System.out.println("SecurityException thrown as user.name permission "
+                    + "not given");
+        }
+        if (!secExcpn) {
+            throw new RuntimeException("SecurityException not thrown");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/print/PrinterJob/GetUserNameTest.policy	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+grant {
+  permission java.lang.RuntimePermission "setSecurityManager";
+  permission java.lang.RuntimePermission "createSecurityManager";
+  permission java.lang.RuntimePermission "usePolicy";
+  permission java.lang.RuntimePermission "queuePrintJob";
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/print/PrinterJob/PageDialogMarginTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2016, 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      6801613
+ * @summary  Verifies if cross-platform pageDialog and printDialog top margin
+ *           entry is working
+ * @run      main/manual PageDialogMarginTest
+ */
+import java.awt.Component;
+import java.awt.print.PageFormat;
+import java.awt.print.PrinterJob;
+import javax.print.attribute.HashPrintRequestAttributeSet;
+import javax.print.attribute.PrintRequestAttributeSet;
+import javax.print.attribute.standard.MediaPrintableArea;
+import javax.swing.JOptionPane;
+import javax.swing.SwingUtilities;
+
+public class PageDialogMarginTest {
+
+    public static void main(String args[]) throws Exception {
+        String[] instructions
+                = {
+                    "Page Dialog will be shown.",
+                    "Change top(in) margin value from 1.0 to 2.0",
+                    "Then select OK."
+                };
+        SwingUtilities.invokeAndWait(() -> {
+            JOptionPane.showMessageDialog((Component) null,
+                    instructions, "Instructions",
+                    JOptionPane.INFORMATION_MESSAGE);
+        });
+        PrinterJob pj = PrinterJob.getPrinterJob();
+        try {
+            HashPrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
+            PageFormat pf;
+            pf = pj.pageDialog(aset);
+            double left = pf.getImageableX();
+            double top = pf.getImageableY();
+            System.out.println("pageDialog - left/top from pageFormat: " + left / 72
+                    + " " + top / 72);
+            System.out.println("pageDialog - left/top from attribute set: "
+                    + getPrintableXFromASet(aset) + " "
+                    + getPrintableYFromASet(aset));
+            if (top / 72 != 2.0f || getPrintableYFromASet(aset) != 2.0f) {
+                throw new RuntimeException("Top margin value not updated");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    static double getPrintableXFromASet(PrintRequestAttributeSet aset) {
+        try {
+            return ((MediaPrintableArea) aset.get(
+                    MediaPrintableArea.class)).getX(MediaPrintableArea.INCH);
+        } catch (Exception e) {
+            return -1.0;
+        }
+    }
+
+    static double getPrintableYFromASet(PrintRequestAttributeSet aset) {
+        try {
+            return ((MediaPrintableArea) aset.get(
+                    MediaPrintableArea.class)).getY(MediaPrintableArea.INCH);
+        } catch (Exception e) {
+            return -1.0;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/print/PrinterJob/PrintAttributeUpdateTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2016, 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 8042713
+  @summary  Print Dialog does not update attribute set with page range
+  @run main/manual PrintAttributeUpdateTest
+ */
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.print.PageFormat;
+import java.awt.print.Pageable;
+import java.awt.print.Printable;
+import java.awt.print.PrinterJob;
+import javax.print.attribute.Attribute;
+import javax.print.attribute.HashPrintRequestAttributeSet;
+import javax.print.attribute.standard.DialogTypeSelection;
+import javax.print.attribute.standard.PageRanges;
+import javax.swing.JOptionPane;
+import javax.swing.SwingUtilities;
+
+public class PrintAttributeUpdateTest implements Pageable, Printable {
+
+    public static void main(String args[]) throws Exception {
+        String[] instructions
+                = {
+                    "Select Pages Range From instead of All in print dialog. ",
+                    "Then select Print"
+                };
+        SwingUtilities.invokeAndWait(() -> {
+            JOptionPane.showMessageDialog((Component) null,
+                    instructions, "Instructions",
+                    JOptionPane.INFORMATION_MESSAGE);
+        });
+        HashPrintRequestAttributeSet as = new HashPrintRequestAttributeSet();
+        PrinterJob j = PrinterJob.getPrinterJob();
+        j.setPageable(new PrintAttributeUpdateTest());
+        as.add(DialogTypeSelection.NATIVE);
+        j.printDialog(as);
+        if (as.containsKey(PageRanges.class) == false) {
+            throw new RuntimeException("Print Dialog did not update "
+                    + " attribute set with page range");
+        }
+        Attribute attrs[] = as.toArray();
+        for (int i = 0; i < attrs.length; i++) {
+            System.out.println("attr " + attrs[i]);
+        }
+        j.print(as);
+    }
+
+    public int getNumberOfPages() {
+        return UNKNOWN_NUMBER_OF_PAGES;
+    }
+
+    public PageFormat getPageFormat(int pageIndex) {
+        PageFormat pf = new PageFormat();
+        return pf;
+    }
+
+    public Printable getPrintable(int pageIndex) {
+        return this;
+    }
+
+    public int print(Graphics g, PageFormat pgFmt, int pi) {
+        g.drawString("Page : " + (pi + 1), 200, 200);
+
+        return PAGE_EXISTS;
+    }
+
+}
--- a/jdk/test/java/awt/xembed/server/TestXEmbedServerJava.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/awt/xembed/server/TestXEmbedServerJava.java	Thu Apr 28 23:08:16 2016 -0700
@@ -76,7 +76,23 @@
     public Process startClient(Rectangle[] bounds, long window) {
         try {
             String java_home = System.getProperty("java.home");
-            return Runtime.getRuntime().exec(java_home + "/bin/java  -XaddExports:java.desktop/sun.awt.X11=ALL-UNNAMED  JavaClient " + window);
+            boolean hasModules = true;
+            try {
+                Class.class.getMethod("getModule");
+            }catch(Exception hasModulesEx) {
+                hasModules = false;
+            }
+            if (hasModules) {
+                System.out.println(java_home +
+                               "/bin/java  -XaddExports:java.desktop/sun.awt.X11=ALL-UNNAMED "+
+                               "-XaddExports:java.desktop/sun.awt=ALL-UNNAMED  JavaClient " + window);
+                return Runtime.getRuntime().exec(java_home +
+                               "/bin/java  -XaddExports:java.desktop/sun.awt.X11=ALL-UNNAMED "+
+                               "-XaddExports:java.desktop/sun.awt=ALL-UNNAMED  JavaClient " + window);
+            }else{
+                System.out.println(java_home + "/bin/java JavaClient " + window);
+                return Runtime.getRuntime().exec(java_home + "/bin/java JavaClient " + window);
+            }
         } catch (IOException ex1) {
             ex1.printStackTrace();
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/Introspector/AnonymousClassBeanPropertyTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,867 @@
+/*
+ * Copyright (c) 2016, 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.beans.BeanInfo;
+import java.beans.BeanProperty;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyDescriptor;
+
+import java.util.Arrays;
+
+
+/**
+ * @test
+ * @bug 8132973 8132732 8155013
+ * @summary Some check for BeanProperty annotation
+ * @author a.stepanov
+ * @run main AnonymousClassBeanPropertyTest
+ */
+
+
+public class AnonymousClassBeanPropertyTest {
+
+    private final static String  DESCRIPTION = "TEST";
+    private final static boolean BOUND       = true;
+    private final static boolean EXPERT      = false;
+    private final static boolean HIDDEN      = true;
+    private final static boolean PREFERRED   = false;
+    private final static boolean REQUIRED    = true;
+    private final static boolean UPDATE      = false;
+
+    private final static double X = java.lang.Math.PI;
+
+    private final static String
+        V_NAME  = "java.lang.Math.PI",
+        V_SHORT = "PI",
+        V = Double.toString(X);
+
+    private final static String DESCRIPTION_2 = "XYZ";
+
+
+    // ---------- test cases (interfaces) ----------
+
+    private interface IGet {
+        double getX();
+    }
+
+    private interface ISet {
+        void setX(double v);
+    }
+
+    private interface IGetByIndex {
+        double getX(int i);
+    }
+
+    private interface ISetByIndex {
+        void setX(int i, double v);
+    }
+
+    private interface IGetArray {
+        double[] getX();
+    }
+
+    private interface ISetArray {
+        void setX(double a[]);
+    }
+
+    private interface IGetBoth {
+        double   getX(int i);
+        double[] getX();
+    }
+
+    private interface ISetBoth {
+        void setX(int i, double v);
+        void setX(double a[]);
+    }
+
+    private interface IGetSet {
+        double getX();
+        void setX(double v);
+    }
+
+    private interface IGetSetByIndex {
+        double getX(int i);
+        void setX(int i, double v);
+    }
+
+    private interface IGetSetBoth {
+        double   getX(int i);
+        double[] getX();
+        void setX(int i, double v);
+        void setX(double a[]);
+    }
+
+
+    // ---------- checks ----------
+
+    private static boolean check(String what, boolean v, boolean ref) {
+
+        boolean ok = (v == ref);
+        if (!ok) { System.out.println(
+            "invalid " + what + ": " + v + ", expected: " + ref); }
+        return ok;
+    }
+
+    private static boolean checkInfo(Class<?> c, String what) {
+
+        BeanInfo i;
+        try { i = Introspector.getBeanInfo(c, Object.class); }
+        catch (IntrospectionException e) { throw new RuntimeException(e); }
+
+        System.out.println("\nchecking info for " + what);
+
+        PropertyDescriptor descriptors[] = i.getPropertyDescriptors();
+        int nd = descriptors.length;
+        if (nd != 1) {
+            System.out.println("invalid number of descriptors: " + nd);
+            return false;
+        }
+
+        PropertyDescriptor d = descriptors[0];
+
+        String descr = d.getShortDescription();
+        boolean ok = descr.equals(DESCRIPTION);
+        if (!ok) { System.out.println("invalid description: " + descr +
+                ", expected: " + DESCRIPTION); }
+
+        ok &= check("isBound",  d.isBound(),  BOUND);
+        ok &= check("isExpert", d.isExpert(), EXPERT);
+        ok &= check("isHidden", d.isHidden(), HIDDEN);
+        ok &= check("isPreferred", d.isPreferred(), PREFERRED);
+        ok &= check("required", (boolean) d.getValue("required"), REQUIRED);
+        ok &= check("visualUpdate",
+            (boolean) d.getValue("visualUpdate"), UPDATE);
+
+        Object vals[] = (Object[]) d.getValue("enumerationValues");
+        if (vals == null) {
+            System.out.println("null enumerationValues");
+            return false;
+        }
+
+        if (vals.length == 0) {
+            System.out.println("empty enumerationValues");
+            return false;
+        }
+
+        boolean okVals = (
+            (vals.length == 3) &&
+             vals[0].toString().equals(V_SHORT) &&
+             vals[1].toString().equals(V)       &&
+             vals[2].toString().equals(V_NAME));
+
+        if (!okVals) {
+            System.out.println("invalid enumerationValues:");
+            for (Object v: vals) { System.out.println(v.toString()); }
+        }
+
+        return (ok && okVals);
+    }
+
+    private static boolean checkAlternativeInfo(Class<?> c, String what) {
+
+        BeanInfo i;
+        try { i = Introspector.getBeanInfo(c, Object.class); }
+        catch (IntrospectionException e) { throw new RuntimeException(e); }
+
+        System.out.println("checking alternative info for " + what);
+
+        PropertyDescriptor descriptors[] = i.getPropertyDescriptors();
+        int nd = descriptors.length;
+        if (nd != 1) {
+            System.out.println("invalid number of descriptors: " + nd);
+            return false;
+        }
+
+        PropertyDescriptor d = descriptors[0];
+
+        String descr = d.getShortDescription();
+        boolean ok = descr.equals(DESCRIPTION_2);
+        if (!ok) { System.out.println("invalid alternative description: " +
+            descr + ", expected: " + DESCRIPTION_2); }
+
+        ok &= check("isBound",  d.isBound(),  !BOUND);
+        ok &= check("isExpert", d.isExpert(), !EXPERT);
+        ok &= check("isHidden", d.isHidden(), !HIDDEN);
+        ok &= check("isPreferred", d.isPreferred(), !PREFERRED);
+        ok &= check("required", (boolean) d.getValue("required"), !REQUIRED);
+        ok &= check("visualUpdate",
+            (boolean) d.getValue("visualUpdate"), !UPDATE);
+
+        Object vals[] = (Object[]) d.getValue("enumerationValues");
+        if (vals != null || vals.length > 0) {
+            System.out.println("non-empty enumerationValues");
+            return false;
+        }
+
+        return ok;
+    }
+
+
+
+    // ---------- run tests ----------
+
+    public static void main(String[] args) {
+
+        boolean passed = true, ok, ok2;
+
+        //----------------------------------------------------------------------
+
+        IGet testGet = new IGet() {
+            @BeanProperty(
+                description  = DESCRIPTION,
+                bound        = BOUND,
+                expert       = EXPERT,
+                hidden       = HIDDEN,
+                preferred    = PREFERRED,
+                required     = REQUIRED,
+                visualUpdate = UPDATE,
+                enumerationValues = {V_NAME})
+            @Override
+            public double getX() { return X; }
+
+            public void addPropertyChangeListener(PropertyChangeListener l)    {}
+            public void removePropertyChangeListener(PropertyChangeListener l) {}
+        };
+        ok = checkInfo(testGet.getClass(), "IGet");
+        System.out.println("OK = " + ok);
+        passed = passed && ok;
+
+        //----------------------------------------------------------------------
+
+        ISet testSet = new ISet() {
+
+            private double x;
+
+            @BeanProperty(
+                description  = DESCRIPTION,
+                bound        = BOUND,
+                expert       = EXPERT,
+                hidden       = HIDDEN,
+                preferred    = PREFERRED,
+                required     = REQUIRED,
+                visualUpdate = UPDATE,
+                enumerationValues = {V_NAME})
+            @Override
+            public void setX(double v) { x = v; }
+
+            public void addPropertyChangeListener(PropertyChangeListener l)    {}
+            public void removePropertyChangeListener(PropertyChangeListener l) {}
+        };
+        ok = checkInfo(testSet.getClass(), "ISet");
+        System.out.println("OK = " + ok);
+        passed = passed && ok;
+
+        //----------------------------------------------------------------------
+
+        IGetByIndex testGetByIndex = new IGetByIndex() {
+
+            private final double x[] = {X, X};
+
+            @BeanProperty(
+                description  = DESCRIPTION,
+                bound        = BOUND,
+                expert       = EXPERT,
+                hidden       = HIDDEN,
+                preferred    = PREFERRED,
+                required     = REQUIRED,
+                visualUpdate = UPDATE,
+                enumerationValues = {V_NAME})
+            @Override
+            public double getX(int i) { return x[i]; }
+
+            public void addPropertyChangeListener(PropertyChangeListener l)    {}
+            public void removePropertyChangeListener(PropertyChangeListener l) {}
+        };
+        ok = checkInfo(testGetByIndex.getClass(), "IGetByIndex");
+        System.out.println("OK = " + ok);
+        passed = passed && ok;
+
+        //----------------------------------------------------------------------
+
+        ISetByIndex testSetByIndex = new ISetByIndex() {
+
+            private final double x[] = {X, X, X};
+
+            @BeanProperty(
+                description  = DESCRIPTION,
+                bound        = BOUND,
+                expert       = EXPERT,
+                hidden       = HIDDEN,
+                preferred    = PREFERRED,
+                required     = REQUIRED,
+                visualUpdate = UPDATE,
+                enumerationValues = {V_NAME})
+            @Override
+            public void setX(int i, double v) { x[i] = v; }
+
+            public void addPropertyChangeListener(PropertyChangeListener l)    {}
+            public void removePropertyChangeListener(PropertyChangeListener l) {}
+        };
+        ok = checkInfo(testSetByIndex.getClass(), "ISetByIndex");
+        System.out.println("OK = " + ok);
+        passed = passed && ok;
+
+        //----------------------------------------------------------------------
+
+        // TODO: please uncomment/update after 8155013 fix
+        /*
+        IGetArray testGetArray = new IGetArray() {
+
+            private final double x[] = {X, X};
+
+            @BeanProperty(
+                description  = DESCRIPTION,
+                bound        = BOUND,
+                expert       = EXPERT,
+                hidden       = HIDDEN,
+                preferred    = PREFERRED,
+                required     = REQUIRED,
+                visualUpdate = UPDATE,
+                enumerationValues = {V_NAME})
+            @Override
+            public double[] getX() { return x; }
+
+            public void addPropertyChangeListener(PropertyChangeListener l)    {}
+            public void removePropertyChangeListener(PropertyChangeListener l) {}
+        };
+        ok = checkInfo(testGetArray.getClass(), "IGetArray");
+        System.out.println("OK = " + ok);
+        passed = passed && ok;
+        */
+
+        //----------------------------------------------------------------------
+
+        // TODO: please uncomment/update after 8155013 fix
+        /*
+        ISetArray testSetArray = new ISetArray() {
+
+            private double x[];
+
+            @BeanProperty(
+                description  = DESCRIPTION,
+                bound        = BOUND,
+                expert       = EXPERT,
+                hidden       = HIDDEN,
+                preferred    = PREFERRED,
+                required     = REQUIRED,
+                visualUpdate = UPDATE,
+                enumerationValues = {V_NAME})
+            @Override
+            public void setX(double a[]) { x = Arrays.copyOf(a, a.length); }
+
+            public void addPropertyChangeListener(PropertyChangeListener l)    {}
+            public void removePropertyChangeListener(PropertyChangeListener l) {}
+        };
+        ok = checkInfo(testSetArray.getClass(), "ISetArray");
+        System.out.println("OK = " + ok);
+        passed = passed && ok;
+        */
+
+        //----------------------------------------------------------------------
+
+        IGetBoth testGetBoth_1 = new IGetBoth() {
+
+            private final double x[] = {X, X};
+
+            @BeanProperty(
+                description  = DESCRIPTION,
+                bound        = BOUND,
+                expert       = EXPERT,
+                hidden       = HIDDEN,
+                preferred    = PREFERRED,
+                required     = REQUIRED,
+                visualUpdate = UPDATE,
+                enumerationValues = {V_NAME})
+            @Override
+            public double getX(int i) { return x[i]; }
+            @Override
+            public double[] getX() { return x; }
+
+            public void addPropertyChangeListener(PropertyChangeListener l)    {}
+            public void removePropertyChangeListener(PropertyChangeListener l) {}
+        };
+        ok = checkInfo(testGetBoth_1.getClass(), "IGetBoth-1");
+        System.out.println("OK = " + ok);
+        passed = passed && ok;
+
+        // TODO: please uncomment/update after 8155013 fix
+        /*
+        IGetBoth testGetBoth_2 = new IGetBoth() {
+
+            private final double x[] = {X, X};
+
+            @Override
+            public double getX(int i) { return x[i]; }
+            @BeanProperty(
+                description  = DESCRIPTION,
+                bound        = BOUND,
+                expert       = EXPERT,
+                hidden       = HIDDEN,
+                preferred    = PREFERRED,
+                required     = REQUIRED,
+                visualUpdate = UPDATE,
+                enumerationValues = {V_NAME})
+            @Override
+            public double[] getX() { return x; }
+
+            public void addPropertyChangeListener(PropertyChangeListener l)    {}
+            public void removePropertyChangeListener(PropertyChangeListener l) {}
+        };
+        ok = checkInfo(testGetBoth_2.getClass(), "IGetBoth-2");
+        System.out.println("OK = " + ok);
+        passed = passed && ok;
+        */
+
+        // TODO: please uncomment/update after 8132732 fix
+        /*
+        IGetBoth testGetBoth_3 = new IGetBoth() {
+
+            private final double x[] = {X, X};
+
+            @BeanProperty(
+                description  = DESCRIPTION,
+                bound        = BOUND,
+                expert       = EXPERT,
+                hidden       = HIDDEN,
+                preferred    = PREFERRED,
+                required     = REQUIRED,
+                visualUpdate = UPDATE,
+                enumerationValues = {V_NAME})
+            @Override
+            public double getX(int i) { return x[i]; }
+            @BeanProperty(
+                description  = DESCRIPTION_2,
+                bound        = !BOUND,
+                expert       = !EXPERT,
+                hidden       = !HIDDEN,
+                preferred    = !PREFERRED,
+                required     = !REQUIRED,
+                visualUpdate = !UPDATE)
+            @Override
+            public double[] getX() { return x; }
+
+            public void addPropertyChangeListener(PropertyChangeListener l)    {}
+            public void removePropertyChangeListener(PropertyChangeListener l) {}
+        };
+        ok = checkInfo(testGetBoth_3.getClass(), "IGetBoth-3");
+        System.out.println("OK = " + ok);
+        ok2 = checkAlternativeInfo(testGetBoth_3.getClass(), "IGetBoth-3");
+        System.out.println("OK = " + ok2);
+        passed = passed && ok && ok2;
+        */
+
+        //----------------------------------------------------------------------
+
+        ISetBoth testSetBoth_1 = new ISetBoth() {
+
+            private double x[] = new double[3];
+
+            @BeanProperty(
+                description  = DESCRIPTION,
+                bound        = BOUND,
+                expert       = EXPERT,
+                hidden       = HIDDEN,
+                preferred    = PREFERRED,
+                required     = REQUIRED,
+                visualUpdate = UPDATE,
+                enumerationValues = {V_NAME})
+            @Override
+            public void setX(int i, double v) { x[i] = v; }
+            @Override
+            public void setX(double[] a) { x = Arrays.copyOf(a, a.length); }
+
+            public void addPropertyChangeListener(PropertyChangeListener l)    {}
+            public void removePropertyChangeListener(PropertyChangeListener l) {}
+        };
+        ok = checkInfo(testSetBoth_1.getClass(), "ISetBoth-1");
+        System.out.println("OK = " + ok);
+        passed = passed && ok;
+
+        // TODO: please uncomment/update after 8155013 fix
+        /*
+        ISetBoth testSetBoth_2 = new ISetBoth() {
+
+            private double x[] = new double[3];
+
+            @Override
+            public void setX(int i, double v) { x[i] = v; }
+            @BeanProperty(
+                description  = DESCRIPTION,
+                bound        = BOUND,
+                expert       = EXPERT,
+                hidden       = HIDDEN,
+                preferred    = PREFERRED,
+                required     = REQUIRED,
+                visualUpdate = UPDATE,
+                enumerationValues = {V_NAME})
+            @Override
+            public void setX(double[] a) { x = Arrays.copyOf(a, a.length); }
+
+            public void addPropertyChangeListener(PropertyChangeListener l)    {}
+            public void removePropertyChangeListener(PropertyChangeListener l) {}
+        };
+        ok = checkInfo(testSetBoth_2.getClass(), "ISetBoth-2");
+        System.out.println("OK = " + ok);
+        passed = passed && ok;
+        */
+
+        // TODO: please uncomment/update after 8132732 fix
+        /*
+        ISetBoth testSetBoth_3 = new ISetBoth() {
+
+            private double x[] = {X, X};
+
+            @BeanProperty(
+                description  = DESCRIPTION,
+                bound        = BOUND,
+                expert       = EXPERT,
+                hidden       = HIDDEN,
+                preferred    = PREFERRED,
+                required     = REQUIRED,
+                visualUpdate = UPDATE,
+                enumerationValues = {V_NAME})
+            @Override
+            public void setX(int i, double v) { x[i] = v; }
+            @BeanProperty(
+                description  = DESCRIPTION_2,
+                bound        = !BOUND,
+                expert       = !EXPERT,
+                hidden       = !HIDDEN,
+                preferred    = !PREFERRED,
+                required     = !REQUIRED,
+                visualUpdate = !UPDATE)
+            @Override
+            public void setX(double[] a) { x = Arrays.copyOf(a, a.length); }
+
+            public void addPropertyChangeListener(PropertyChangeListener l)    {}
+            public void removePropertyChangeListener(PropertyChangeListener l) {}
+        };
+        ok = checkInfo(testSetBoth_3.getClass(), "ISetBoth-3");
+        System.out.println("OK = " + ok);
+        ok2 = checkAlternativeInfo(testSetBoth_3.getClass(), "ISetBoth-3");
+        System.out.println("OK = " + ok2);
+        passed = passed && ok && ok2;
+        */
+
+        //----------------------------------------------------------------------
+
+        IGetSet testGetSet_1 = new IGetSet() {
+
+            private double x;
+
+            @BeanProperty(
+                description  = DESCRIPTION,
+                bound        = BOUND,
+                expert       = EXPERT,
+                hidden       = HIDDEN,
+                preferred    = PREFERRED,
+                required     = REQUIRED,
+                visualUpdate = UPDATE,
+                enumerationValues = {V_NAME})
+            @Override
+            public double getX() { return x; }
+            @Override
+            public void setX(double v) { x = v; }
+
+            public void addPropertyChangeListener(PropertyChangeListener l)    {}
+            public void removePropertyChangeListener(PropertyChangeListener l) {}
+        };
+        ok = checkInfo(testGetSet_1.getClass(), "IGetSet-1");
+        System.out.println("OK = " + ok);
+        passed = passed && ok;
+
+
+        IGetSet testGetSet_2 = new IGetSet() {
+
+            private double x;
+
+            @Override
+            public double getX() { return x; }
+            @BeanProperty(
+                description  = DESCRIPTION,
+                bound        = BOUND,
+                expert       = EXPERT,
+                hidden       = HIDDEN,
+                preferred    = PREFERRED,
+                required     = REQUIRED,
+                visualUpdate = UPDATE,
+                enumerationValues = {V_NAME})
+            @Override
+            public void setX(double v) { x = v; }
+
+            public void addPropertyChangeListener(PropertyChangeListener l)    {}
+            public void removePropertyChangeListener(PropertyChangeListener l) {}
+        };
+        ok = checkInfo(testGetSet_2.getClass(), "IGetSet-2");
+        System.out.println("OK = " + ok);
+        passed = passed && ok;
+
+        // TODO: please uncomment/update after 8132973 fix
+        /*
+        IGetSet testGetSet_3 = new IGetSet() {
+
+            private double x;
+
+            @Override
+            @BeanProperty(
+                description  = DESCRIPTION,
+                bound        = BOUND,
+                expert       = EXPERT,
+                hidden       = HIDDEN,
+                preferred    = PREFERRED,
+                required     = REQUIRED,
+                visualUpdate = UPDATE,
+                enumerationValues = {V_NAME})
+            public double getX() { return x; }
+            @BeanProperty(
+                description  = DESCRIPTION_2,
+                bound        = !BOUND,
+                expert       = !EXPERT,
+                hidden       = !HIDDEN,
+                preferred    = !PREFERRED,
+                required     = !REQUIRED,
+                visualUpdate = !UPDATE)
+            @Override
+            public void setX(double v) { x = v; }
+
+            public void addPropertyChangeListener(PropertyChangeListener l)    {}
+            public void removePropertyChangeListener(PropertyChangeListener l) {}
+        };
+        ok = checkInfo(testGetSet_3.getClass(), "IGetSet-3");
+        System.out.println("OK = " + ok);
+        ok2 = checkAlternativeInfo(testGetSet_3.getClass(), "IGetSet-3");
+        System.out.println("OK = " + ok2);
+        passed = passed && ok && ok2;
+        */
+
+        //----------------------------------------------------------------------
+
+        IGetSetByIndex testGetSetByIndex_1 = new IGetSetByIndex() {
+
+            private final double x[] = {X, X};
+
+            @BeanProperty(
+                description  = DESCRIPTION,
+                bound        = BOUND,
+                expert       = EXPERT,
+                hidden       = HIDDEN,
+                preferred    = PREFERRED,
+                required     = REQUIRED,
+                visualUpdate = UPDATE,
+                enumerationValues = {V_NAME})
+            @Override
+            public double getX(int i) { return x[i]; }
+            @Override
+            public void setX(int i, double v) { x[i] = v; }
+
+            public void addPropertyChangeListener(PropertyChangeListener l)    {}
+            public void removePropertyChangeListener(PropertyChangeListener l) {}
+        };
+        ok = checkInfo(testGetSetByIndex_1.getClass(), "IGetSetByIndex-1");
+        System.out.println("OK = " + ok);
+        passed = passed && ok;
+
+
+        IGetSetByIndex testGetSetByIndex_2 = new IGetSetByIndex() {
+
+            private final double x[] = {X, X};
+
+            @Override
+            public double getX(int i) { return x[i]; }
+            @BeanProperty(
+                description  = DESCRIPTION,
+                bound        = BOUND,
+                expert       = EXPERT,
+                hidden       = HIDDEN,
+                preferred    = PREFERRED,
+                required     = REQUIRED,
+                visualUpdate = UPDATE,
+                enumerationValues = {V_NAME})
+            @Override
+            public void setX(int i, double v) { x[i] = v; }
+
+            public void addPropertyChangeListener(PropertyChangeListener l)    {}
+            public void removePropertyChangeListener(PropertyChangeListener l) {}
+        };
+        ok = checkInfo(testGetSetByIndex_2.getClass(), "IGetSetByIndex-2");
+        System.out.println("OK = " + ok);
+        passed = passed && ok;
+
+        // TODO: please uncomment/update after 8132973 fix
+        /*
+        IGetSetByIndex testGetSetByIndex_3 = new IGetSetByIndex() {
+
+            private double x[] = {X, X};
+
+            @BeanProperty(
+                description  = DESCRIPTION,
+                bound        = BOUND,
+                expert       = EXPERT,
+                hidden       = HIDDEN,
+                preferred    = PREFERRED,
+                required     = REQUIRED,
+                visualUpdate = UPDATE,
+                enumerationValues = {V_NAME})
+            @Override
+            public double getX(int i) {
+                return x[i];
+            }
+            @BeanProperty(
+                description  = DESCRIPTION_2,
+                bound        = !BOUND,
+                expert       = !EXPERT,
+                hidden       = !HIDDEN,
+                preferred    = !PREFERRED,
+                required     = !REQUIRED,
+                visualUpdate = !UPDATE)
+            @Override
+            public void setX(int i, double v) {
+                x[i] = v;
+            }
+
+            public void addPropertyChangeListener(PropertyChangeListener l)    {}
+            public void removePropertyChangeListener(PropertyChangeListener l) {}
+        };
+        ok = checkInfo(testGetSetByIndex_3.getClass(), "IGetSetByIndex-3");
+        System.out.println("OK = " + ok);
+        ok2 = checkAlternativeInfo(
+            testGetSetByIndex_3.getClass(), "IGetSetByIndex-3");
+        System.out.println("OK = " + ok2);
+        passed = passed && ok && ok2;
+        */
+
+        //----------------------------------------------------------------------
+
+        // TODO: please uncomment/update after 8155013 fix
+        /*
+        IGetSetBoth testGetSetBoth_1 = new IGetSetBoth() {
+
+            private double x[] = {X, X};
+
+            @Override
+            public double getX(int i) { return x[i]; }
+            @BeanProperty(
+                description  = DESCRIPTION,
+                bound        = BOUND,
+                expert       = EXPERT,
+                hidden       = HIDDEN,
+                preferred    = PREFERRED,
+                required     = REQUIRED,
+                visualUpdate = UPDATE,
+                enumerationValues = {V_NAME})
+            @Override
+            public double[] getX() { return x; }
+            @Override
+            public void setX(int i, double v) { x[i] = v; }
+            @Override
+            public void setX(double[] a) { x = Arrays.copyOf(a, a.length); }
+
+            public void addPropertyChangeListener(PropertyChangeListener l)    {}
+            public void removePropertyChangeListener(PropertyChangeListener l) {}
+        };
+        ok = checkInfo(testGetSetBoth_1.getClass(), "IGetSetBoth-1");
+        System.out.println("OK = " + ok);
+        passed = passed && ok;
+        */
+
+        // TODO: please uncomment/update after 8155013 fix
+        /*
+        IGetSetBoth testGetSetBoth_2 = new IGetSetBoth() {
+
+            private double x[] = {X, X};
+
+            @Override
+            public double getX(int i) { return x[i]; }
+            @Override
+            public double[] getX() { return x; }
+            @Override
+            public void setX(int i, double v) { x[i] = v; }
+            @BeanProperty(
+                description  = DESCRIPTION,
+                bound        = BOUND,
+                expert       = EXPERT,
+                hidden       = HIDDEN,
+                preferred    = PREFERRED,
+                required     = REQUIRED,
+                visualUpdate = UPDATE,
+                enumerationValues = {V_NAME})
+            @Override
+            public void setX(double[] a) { x = Arrays.copyOf(a, a.length); }
+
+            public void addPropertyChangeListener(PropertyChangeListener l)    {}
+            public void removePropertyChangeListener(PropertyChangeListener l) {}
+        };
+        ok = checkInfo(testGetSetBoth_2.getClass(), "IGetSetBoth-2");
+        System.out.println("OK = " + ok);
+        passed = passed && ok;
+        */
+
+        // TODO: please uncomment/update after 8132973 fix
+        /*
+        IGetSetBoth testGetSetBoth_3 = new IGetSetBoth() {
+
+            private double x[] = {X, X};
+
+            @BeanProperty(
+                description  = DESCRIPTION,
+                bound        = BOUND,
+                expert       = EXPERT,
+                hidden       = HIDDEN,
+                preferred    = PREFERRED,
+                required     = REQUIRED,
+                visualUpdate = UPDATE,
+                enumerationValues = {V_NAME})
+            @Override
+            public double getX(int i) { return x[i]; }
+            @Override
+            public double[] getX() { return x; }
+            @Override
+            public void setX(int i, double v) { x[i] = v; }
+            @BeanProperty(
+                description  = DESCRIPTION_2,
+                bound        = !BOUND,
+                expert       = !EXPERT,
+                hidden       = !HIDDEN,
+                preferred    = !PREFERRED,
+                required     = !REQUIRED,
+                visualUpdate = !UPDATE)
+            @Override
+            public void setX(double[] a) { x = Arrays.copyOf(a, a.length); }
+
+            public void addPropertyChangeListener(PropertyChangeListener l)    {}
+            public void removePropertyChangeListener(PropertyChangeListener l) {}
+        };
+        ok = checkInfo(testGetSetBoth_3.getClass(), "IGetSetBoth-3");
+        System.out.println("OK = " + ok);
+        ok2 = checkAlternativeInfo(
+            testGetSetBoth_3.getClass(), "IGetSetBoth-3");
+        System.out.println("OK = " + ok2);
+        passed = passed && ok && ok2;
+        */
+
+        if (!passed) { throw new RuntimeException("test failed"); }
+        System.out.println("\ntest passed");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/Introspector/BeanPropertyTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,1009 @@
+/*
+ * Copyright (c) 2016, 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.beans.BeanInfo;
+import java.beans.BeanProperty;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyDescriptor;
+
+import java.util.Arrays;
+
+
+/**
+ * @test
+ * @bug 8132703 8132163 8132732 8132973 8154756 8132888
+ * @summary Some check for BeanProperty annotation
+ * @author a.stepanov
+ * @run main BeanPropertyTest
+ */
+
+
+public class BeanPropertyTest {
+
+    private final static String  DESCRIPTION = "TEST";
+    private final static boolean BOUND       = true;
+    private final static boolean EXPERT      = false;
+    private final static boolean HIDDEN      = true;
+    private final static boolean PREFERRED   = false;
+    private final static boolean REQUIRED    = true;
+    private final static boolean UPDATE      = false;
+    private final static String
+        V_NAME  = "javax.swing.SwingConstants.TOP",
+        V_SHORT = "TOP",
+        V = Integer.toString(javax.swing.SwingConstants.TOP);
+    private final static int X = javax.swing.SwingConstants.TOP;
+
+    private final static String DESCRIPTION_2 = "XYZ";
+
+
+    // ---------- test cases ----------
+
+    public static class G01 {
+
+        private final static String TESTCASE = "arbitrary getter name";
+
+        private final int x = X;
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public int get1() { return x; }
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    public static class S01 {
+
+        private final static String TESTCASE = "arbitrary setter name";
+
+        private int x;
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public void setXXXXX(int v) { x = v; }
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    // JDK-8132703
+    public static class G02 {
+
+        private final static String TESTCASE = "arbitrary getter name";
+
+        private final int x = X;
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public int get() { return x; }
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    // JDK-8132703
+    public static class S02 {
+
+        private final static String TESTCASE = "arbitrary setter name";
+
+        private int x;
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public void set(int v) { x = v; }
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    // JDK-8132703
+    public static class G03 {
+
+        private final static String TESTCASE = "arbitrary getter name";
+
+        private final int x = X;
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public int GetX() { return x; }
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    // JDK-8132703
+    public static class S03 {
+
+        private final static String TESTCASE = "arbitrary setter name";
+
+        private int x;
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public void SetX(int v) { x = v; }
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    // JDK-8132163
+    public static class G04 {
+
+        private final static String TESTCASE = "arbitrary getter return type";
+
+        private final int x = X;
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public Object getX() { return x; }
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    // JDK-8132163
+    public static class S04 {
+
+        private final static String TESTCASE = "arbitrary setter argument type";
+
+        private int x;
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public void setX(short v) { x = v; }
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    public static class G05 {
+
+        private final static String TESTCASE =
+            "annotated getter + arbitrary setter argument type";
+
+        private int x;
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public int getX() { return x; }
+        public void setX(short v) { x = v; }
+
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    // JDK-8132163
+    public static class S05 {
+
+        private final static String TESTCASE =
+            "annotated setter + arbitrary getter return type";
+
+        private int x;
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public void setX(int v) { x = v; }
+        public Object getX() { return x; }
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    public static class G06 {
+
+        private final static String TESTCASE = "indexed getter";
+
+        private final int x[] = {X, X, X};
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public int getX(int i) { return x[i]; }
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    public static class S06 {
+
+        private final static String TESTCASE = "indexed setter";
+
+        private final int x[] = {X, X, X};
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public void setX(int i, int v) { x[i] = v; }
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    public static class G07 {
+
+        private final static String TESTCASE =
+            "indexed (annotated) + non-indexed getters";
+
+        private final int x[] = {X, X, X};
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public int getX(int i) { return x[i]; }
+
+        public int[] getX() { return x; }
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    public static class S07 {
+
+        private final static String TESTCASE =
+            "indexed (annotated) + non-indexed setters";
+
+        private int x[] = new int[3];
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public void setX(int i, int v) { x[i] = v; }
+
+        public void setX(int a[]) { x = Arrays.copyOf(a, a.length); }
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    // JDK-8132732
+    public static class G08 {
+
+        private final static String TESTCASE =
+            "non-indexed (annotated) + indexed getters";
+
+        private final int x[] = {X, X, X};
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public int[] getX() { return x; }
+
+        public int getX(int i) { return x[i]; }
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    // JDK-8132732
+    public static class S08 {
+
+        private final static String TESTCASE =
+            "non-indexed (annotated) + indexed setters";
+
+        private int x[] = new int[3];
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public void setX(int a[]) { x = Arrays.copyOf(a, a.length); }
+
+        public void setX(int i, int v) { x[i] = v; }
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    // JDK-8132732
+    public static class G09 {
+
+        private final static String TESTCASE = "two annotated getters";
+
+        private final int x[] = {X, X, X};
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public int[] getX() { return x; }
+
+        @BeanProperty(
+            description  = DESCRIPTION_2,
+            bound        = !BOUND,
+            expert       = !EXPERT,
+            hidden       = !HIDDEN,
+            preferred    = !PREFERRED,
+            required     = !REQUIRED,
+            visualUpdate = !UPDATE)
+        public int getX(int i) { return x[i]; }
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    // JDK-8132732
+    public static class S09 {
+
+        private final static String TESTCASE = "two annotated setters";
+
+        private int x[] = new int[3];
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public void setX(int a[]) { x = Arrays.copyOf(a, a.length); }
+
+        @BeanProperty(
+            description  = DESCRIPTION_2,
+            bound        = !BOUND,
+            expert       = !EXPERT,
+            hidden       = !HIDDEN,
+            preferred    = !PREFERRED,
+            required     = !REQUIRED,
+            visualUpdate = !UPDATE)
+        public void setX(int i, int v) { x[i] = v; }
+
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    public static class G10 {
+
+        private final static String TESTCASE =
+            "getter + similarly named field";
+
+        public int prop, Prop, setProp, getProp;
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public int getProp() { return X; }
+        public void setProp(int v) { prop = Prop = setProp = getProp = v; }
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    public static class S10 {
+
+        private final static String TESTCASE =
+            "setter + similarly named field";
+
+        public int prop, Prop, setProp, getProp;
+
+        private int x;
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public int getProp() { return x; }
+        public void setProp(int v) { x = v; }
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    public static class G11 {
+
+        private final static String TESTCASE =
+            "getter + similarly named field of other type";
+
+        public Object prop, Prop, setProp, getProp;
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public int getProp() { return X; }
+        public void setProp(int v) { prop = Prop = setProp = getProp = v; }
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    public static class S11 {
+
+        private final static String TESTCASE =
+            "setter + similarly named field of other type";
+
+        public String prop, Prop, setProp, getProp;
+
+        private int x;
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public int getProp() { return x; }
+        public void setProp(int v) { x = v; }
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    // JDK-8132163
+    public static class G12 {
+
+        private final static String TESTCASE =
+            "getter having wrapper class return type";
+
+        private final int x = X;
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public Integer getProp() { return x; }
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    // JDK-8132163
+    public static class S12 {
+
+        private final static String TESTCASE =
+            "setter with wrapper class argument type";
+
+        private int x;
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public void setX(Integer v) { x = v; }
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    public static class G13 {
+
+        private final static String TESTCASE =
+            "getter + overloading methods";
+
+        private final int x = X;
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public int getX() { return x; }
+        public int getX(boolean arg) { return (arg ? x : 0); }
+        public int getX(int ... dummy) { return 0; }
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    // JDK-8154756
+    public static class S13 {
+
+        private final static String TESTCASE =
+            "setter + overloading methods";
+
+        private int x;
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public void setX(int v) { x = v; }
+        public int  setX() { return (x = X); }
+        public void setX(int ... dummy) {}
+        private void setX(Object ... dummy) {}
+
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+
+    // JDK-8132888
+    public static class G14 {
+
+        private final static String TESTCASE = "non-public getter";
+
+        private final int x = X;
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        int getX() { return x; } // getter is not public
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    // JDK-8132888
+    public static class S14 {
+
+        private final static String TESTCASE = "non-public setter";
+
+        private int x;
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        void setX(int v) { x = v; } // setter is not public
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    public static class getX {
+
+        private final static String TESTCASE =
+            "class name coincides with getter name";
+
+        private int x;
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public int  getX() { return x; }
+        public void setX(int v) { x = v; }
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    public static class setX {
+
+        private final static String TESTCASE =
+            "class name coincides with setter name";
+
+        private int x;
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public void setX(int v) { x = v; }
+        public int  getX() { return x; }
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    // JDK-8132973
+    public static class GS {
+
+        private final static String TESTCASE =
+            "both getter and setter are annotated";
+
+        private int x;
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE,
+            enumerationValues = {V_NAME})
+        public int getX() { return x; }
+
+        @BeanProperty(
+            description  = DESCRIPTION_2,
+            bound        = !BOUND,
+            expert       = !EXPERT,
+            hidden       = !HIDDEN,
+            preferred    = !PREFERRED,
+            required     = !REQUIRED,
+            visualUpdate = !UPDATE)
+        public void setX(int v) { x = v; }
+
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    public static class Self {
+
+        private final static String TESTCASE = "trivial singleton";
+
+        private static Self instance = null;
+        private Self() {}
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE)
+        public Self getSelf() {
+            if (instance == null) { instance = new Self(); }
+            return instance;
+        }
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+    public static class SelfArr {
+
+        private final static String TESTCASE = "trivial singleton + array";
+
+        private static SelfArr arr[] = null;
+        private SelfArr() {}
+
+        @BeanProperty(
+            description  = DESCRIPTION,
+            bound        = BOUND,
+            expert       = EXPERT,
+            hidden       = HIDDEN,
+            preferred    = PREFERRED,
+            required     = REQUIRED,
+            visualUpdate = UPDATE)
+        public SelfArr[] getSelfArr() {
+            if (arr == null) { arr = new SelfArr[]{new SelfArr(), new SelfArr()}; }
+            return arr;
+        }
+
+        public void addPropertyChangeListener(PropertyChangeListener l)    {}
+        public void removePropertyChangeListener(PropertyChangeListener l) {}
+    }
+
+
+    // ---------- checks ----------
+
+    private static boolean check(String what, boolean v, boolean ref) {
+
+        boolean ok = (v == ref);
+        if (!ok) { System.out.println(
+            "invalid " + what + ": " + v + ", expected: " + ref); }
+        return ok;
+    }
+
+    private static boolean checkInfo(BeanInfo i, boolean checkVals) {
+
+        System.out.println("checking info...");
+
+        PropertyDescriptor descriptors[] = i.getPropertyDescriptors();
+        int nd = descriptors.length;
+        if (nd != 1) {
+            System.out.println("invalid number of descriptors: " + nd);
+            return false;
+        }
+
+        PropertyDescriptor d = descriptors[0];
+
+        String descr = d.getShortDescription();
+        boolean ok = descr.equals(DESCRIPTION);
+        if (!ok) { System.out.println("invalid description: " + descr +
+                ", expected: " + DESCRIPTION); }
+
+        ok &= check("isBound",  d.isBound(),  BOUND);
+        ok &= check("isExpert", d.isExpert(), EXPERT);
+        ok &= check("isHidden", d.isHidden(), HIDDEN);
+        ok &= check("isPreferred", d.isPreferred(), PREFERRED);
+        ok &= check("required", (boolean) d.getValue("required"), REQUIRED);
+        ok &= check("visualUpdate",
+            (boolean) d.getValue("visualUpdate"), UPDATE);
+
+        if (!checkVals) { return ok; }
+
+        Object vals[] = (Object[]) d.getValue("enumerationValues");
+        if (vals == null) {
+            System.out.println("null enumerationValues");
+            return false;
+        }
+
+        boolean okVals = (
+            (vals.length == 3) &&
+             vals[0].toString().equals(V_SHORT) &&
+             vals[1].toString().equals(V)       &&
+             vals[2].toString().equals(V_NAME));
+
+        if (!okVals) { System.out.println("invalid enumerationValues"); }
+
+        return (ok && okVals);
+    }
+
+    private static boolean checkAlternativeInfo(BeanInfo i) {
+
+        System.out.println("checking alternative info...");
+
+        PropertyDescriptor descriptors[] = i.getPropertyDescriptors();
+        int nd = descriptors.length;
+        if (nd != 1) {
+            System.out.println("invalid number of descriptors: " + nd);
+            return false;
+        }
+
+        PropertyDescriptor d = descriptors[0];
+
+        String descr = d.getShortDescription();
+        boolean ok = descr.equals(DESCRIPTION_2);
+        if (!ok) { System.out.println("invalid alternative description: " +
+            descr + ", expected: " + DESCRIPTION_2); }
+
+        ok &= check("isBound",  d.isBound(),  !BOUND);
+        ok &= check("isExpert", d.isExpert(), !EXPERT);
+        ok &= check("isHidden", d.isHidden(), !HIDDEN);
+        ok &= check("isPreferred", d.isPreferred(), !PREFERRED);
+        ok &= check("required", (boolean) d.getValue("required"), !REQUIRED);
+        ok &= check("visualUpdate",
+            (boolean) d.getValue("visualUpdate"), !UPDATE);
+
+        Object vals[] = (Object[]) d.getValue("enumerationValues");
+        if (vals != null || vals.length > 0) {
+            System.out.println("non-null enumerationValues");
+            return false;
+        }
+
+        return ok;
+    }
+
+
+    private static boolean checkAlternative(Class<?> c) {
+        return (
+            c.equals(G09.class) ||
+            c.equals(S09.class) ||
+            c.equals(GS.class));
+    }
+
+    private static boolean ignoreVals(Class<?> c) {
+        return (c.equals(Self.class) || c.equals(SelfArr.class));
+    }
+
+
+    // ---------- run test ----------
+
+    public static void main(String[] args) throws Exception {
+
+        Class<?> cases[] = {
+
+            G01.class, S01.class,
+            // G02.class, S02.class, // TODO: please update after 8132703 fix
+            // G03.class, S03.class, // TODO: please update after 8132703 fix
+            // G04.class, S04.class, // TODO: please update after 8132163 fix
+            G05.class, // S05.class, // TODO: please update after 8132163 fix
+            G06.class, S06.class,
+            G07.class, S07.class,
+            // G08.class, S08.class, // TODO: please update after 8132732 fix
+            // G09.class, S09.class, // TODO: please update after 8132732 fix
+            G10.class, S10.class,
+            G11.class, S11.class,
+            // G12.class, S12.class, // TODO: please update after 8132163 fix
+            G13.class, // S13.class, // TODO: please update after 8154756 fix
+            // G14.class, S14.class, // TODO: please update after 8132888 fix or
+                                     // remove these cases if it is not an issue
+            // GS.class, // TODO: please update after 8132973 fix
+            getX.class, setX.class,
+            Self.class, SelfArr.class
+        };
+
+        boolean passed = true;
+
+        for (Class<?> c: cases) {
+
+            java.lang.reflect.Field f = c.getDeclaredField("TESTCASE");
+            f.setAccessible(true);
+            String descr = f.get(c).toString();
+
+            System.out.println("\n" + c.getSimpleName() + " (" + descr + "):");
+            BeanInfo i;
+            try { i = Introspector.getBeanInfo(c, Object.class); }
+            catch (IntrospectionException e) { throw new RuntimeException(e); }
+            boolean ok = checkInfo(i, !ignoreVals(c));
+            if (checkAlternative(c)) {
+                ok |= checkAlternativeInfo(i);
+            }
+            System.out.println(ok ? "OK" : "NOK");
+            passed = passed && ok;
+        }
+
+        if (!passed) { throw new RuntimeException("test failed"); }
+        System.out.println("\ntest passed");
+    }
+}
--- a/jdk/test/java/lang/Class/GetPackageTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/Class/GetPackageTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, 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
@@ -52,7 +52,7 @@
         assertEquals(fooClass.getClassLoader(), loader);
     }
 
-    @DataProvider(name = "testclasses")
+    @DataProvider(name = "testClasses")
     public Object[][] testClasses() {
         return new Object[][] {
                 // primitive type, void, array types
--- a/jdk/test/java/lang/StackWalker/DumpStackTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/StackWalker/DumpStackTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -28,9 +28,6 @@
  *          This test should also been run against jdk9 successfully except of
  *          VM option MemberNameInStackFrame.
  * @run main/othervm DumpStackTest
- * @run main/othervm -Dstackwalk.newThrowable=false DumpStackTest
- * @run main/othervm -Dstackwalk.newThrowable=true -XX:-MemberNameInStackFrame DumpStackTest
- * @run main/othervm -Dstackwalk.newThrowable=true -XX:+MemberNameInStackFrame DumpStackTest
  */
 
 import java.lang.invoke.MethodHandle;
--- a/jdk/test/java/lang/StackWalker/GetCallerClassTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/StackWalker/GetCallerClassTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,8 +25,7 @@
  * @test
  * @bug 8140450
  * @summary Basic test for StackWalker.getCallerClass()
- * @run main/othervm -XX:-MemberNameInStackFrame GetCallerClassTest
- * @run main/othervm -XX:+MemberNameInStackFrame GetCallerClassTest
+ * @run main/othervm GetCallerClassTest
  * @run main/othervm GetCallerClassTest sm
  */
 
--- a/jdk/test/java/lang/StackWalker/StackWalkTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/StackWalker/StackWalkTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -44,10 +44,6 @@
  * @run main/othervm/java.security.policy=stackwalktest.policy StackWalkTest
  * @run main/othervm StackWalkTest -random:50
  * @run main/othervm/java.security.policy=stackwalktest.policy StackWalkTest -random:50
- * @run main/othervm -XX:-MemberNameInStackFrame -Dstackwalk.newThrowable=false StackWalkTest -random:50
- * @run main/othervm -XX:-MemberNameInStackFrame -Dstackwalk.newThrowable=true  StackWalkTest -random:50
- * @run main/othervm -XX:+MemberNameInStackFrame -Dstackwalk.newThrowable=false StackWalkTest -random:50
- * @run main/othervm -XX:+MemberNameInStackFrame -Dstackwalk.newThrowable=true  StackWalkTest -random:50
  * @author danielfuchs, bchristi
  * @key randomness
  */
--- a/jdk/test/java/lang/StackWalker/VerifyStackTrace.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/StackWalker/VerifyStackTrace.java	Thu Apr 28 23:08:16 2016 -0700
@@ -40,8 +40,7 @@
  * @summary Verify stack trace information obtained with respect to StackWalker
  *          options, when the stack contains lambdas, method handle invoke
  *          virtual calls, and reflection.
- * @run main/othervm -XX:-MemberNameInStackFrame VerifyStackTrace
- * @run main/othervm -XX:+MemberNameInStackFrame VerifyStackTrace
+ * @run main/othervm VerifyStackTrace
  * @run main/othervm/java.security.policy=stackwalk.policy VerifyStackTrace
  * @author danielfuchs
  */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/concat/WithSecurityManager.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016, 2016, 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.security.Permission;
+
+/**
+ * @test
+ * @summary String concatenation fails with a custom SecurityManager that uses concatenation
+ * @bug 8155090
+ *
+ * @compile WithSecurityManager.java
+ *
+ * @run main/othervm -Xverify:all WithSecurityManager
+ * @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=BC_SB                  WithSecurityManager
+ * @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=BC_SB_SIZED            WithSecurityManager
+ * @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=MH_SB_SIZED            WithSecurityManager
+ * @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      WithSecurityManager
+ * @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      WithSecurityManager
+ * @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  WithSecurityManager
+*/
+public class WithSecurityManager {
+    public static void main(String[] args) throws Throwable {
+        SecurityManager sm = new SecurityManager() {
+            @Override
+            public void checkPermission(Permission perm) {
+                String abc = "abc";
+                String full = abc + "def";
+            }
+        };
+        System.setSecurityManager(sm);
+        ClassLoader cl = new ClassLoader() {};
+    }
+}
--- a/jdk/test/java/lang/System/Logger/custom/CustomLoggerTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/System/Logger/custom/CustomLoggerTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -46,6 +46,8 @@
 import java.lang.System.Logger;
 import java.lang.System.Logger.Level;
 import java.util.stream.Stream;
+import java.lang.reflect.Module;
+import java.security.AllPermission;
 
 /**
  * @test
@@ -70,6 +72,12 @@
             return  new AtomicBoolean(false);
         }
     };
+    static final ThreadLocal<AtomicBoolean> allowAll = new ThreadLocal<AtomicBoolean>() {
+        @Override
+        protected AtomicBoolean initialValue() {
+            return  new AtomicBoolean(false);
+        }
+    };
 
     public static class MyBundle extends ResourceBundle {
 
@@ -241,7 +249,7 @@
         }
 
         @Override
-        public Logger getLogger(String name, Class<?> caller) {
+        public Logger getLogger(String name, Module caller) {
             // We should check the permission to obey the API contract, but
             // what happens if we don't?
             // This is the main difference compared with what we test in
@@ -251,8 +259,13 @@
                 sm.checkPermission(SimplePolicy.LOGGERFINDER_PERMISSION);
             }
 
-            PrivilegedAction<ClassLoader> pa = () -> caller.getClassLoader();
-            ClassLoader callerLoader = AccessController.doPrivileged(pa);
+            final boolean before = allowAll.get().getAndSet(true);
+            final ClassLoader callerLoader;
+            try {
+                callerLoader = caller.getClassLoader();
+            } finally {
+                allowAll.get().set(before);
+            }
             if (callerLoader == null) {
                 return system.computeIfAbsent(name, (n) -> new LoggerImpl(n));
             } else {
@@ -267,7 +280,7 @@
 
     static void setSecurityManager() {
         if (System.getSecurityManager() == null) {
-            Policy.setPolicy(new SimplePolicy(allowControl));
+            Policy.setPolicy(new SimplePolicy(allowControl, allowAll));
             System.setSecurityManager(new SecurityManager());
         }
     }
@@ -284,9 +297,9 @@
         BaseLoggerFinder provider =
                 BaseLoggerFinder.class.cast(LoggerFinder.getLoggerFinder());
         BaseLoggerFinder.LoggerImpl appSink =
-                BaseLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", CustomLoggerTest.class));
+                BaseLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", CustomLoggerTest.class.getModule()));
         BaseLoggerFinder.LoggerImpl sysSink =
-                BaseLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", Thread.class));
+                BaseLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", Thread.class.getModule()));
 
 
         Stream.of(args).map(TestCases::valueOf).forEach((testCase) -> {
@@ -695,34 +708,46 @@
         static final RuntimePermission LOGGERFINDER_PERMISSION =
                 new RuntimePermission("loggerFinder");
         final Permissions permissions;
+        final Permissions controlPermissions;
         final Permissions allPermissions;
         final ThreadLocal<AtomicBoolean> allowControl;
-        public SimplePolicy(ThreadLocal<AtomicBoolean> allowControl) {
+        final ThreadLocal<AtomicBoolean> allowAll;
+        public SimplePolicy(ThreadLocal<AtomicBoolean> allowControl, ThreadLocal<AtomicBoolean> allowAll) {
             this.allowControl = allowControl;
+            this.allowAll = allowAll;
             permissions = new Permissions();
 
             // these are used for configuring the test itself...
+            controlPermissions = new Permissions();
+            controlPermissions.add(LOGGERFINDER_PERMISSION);
+
+            // these are used for simulating a doPrivileged call from
+            // a class in the BCL
             allPermissions = new Permissions();
-            allPermissions.add(LOGGERFINDER_PERMISSION);
+            allPermissions.add(new AllPermission());
+
+        }
+
+        Permissions permissions() {
+            if (allowAll.get().get()) return allPermissions;
+            if (allowControl.get().get()) return controlPermissions;
+            return permissions;
 
         }
 
         @Override
         public boolean implies(ProtectionDomain domain, Permission permission) {
-            if (allowControl.get().get()) return allPermissions.implies(permission);
-            return permissions.implies(permission);
+            return permissions().implies(permission);
         }
 
         @Override
         public PermissionCollection getPermissions(CodeSource codesource) {
-            return new PermissionsBuilder().addAll(allowControl.get().get()
-                    ? allPermissions : permissions).toPermissions();
+            return new PermissionsBuilder().addAll(permissions()).toPermissions();
         }
 
         @Override
         public PermissionCollection getPermissions(ProtectionDomain domain) {
-            return new PermissionsBuilder().addAll(allowControl.get().get()
-                    ? allPermissions : permissions).toPermissions();
+            return new PermissionsBuilder().addAll(permissions()).toPermissions();
         }
     }
 }
--- a/jdk/test/java/lang/System/LoggerFinder/BaseLoggerFinderTest/BaseLoggerFinder.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/System/LoggerFinder/BaseLoggerFinderTest/BaseLoggerFinder.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,13 +25,14 @@
 import java.security.PrivilegedAction;
 import java.lang.System.LoggerFinder;
 import java.lang.System.Logger;
+import java.lang.reflect.Module;
 
 public  class BaseLoggerFinder extends LoggerFinder implements TestLoggerFinder {
 
     static final RuntimePermission LOGGERFINDER_PERMISSION =
                 new RuntimePermission("loggerFinder");
     @Override
-    public Logger getLogger(String name, Class<?> caller) {
+    public Logger getLogger(String name, Module caller) {
         SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
             sm.checkPermission(LOGGERFINDER_PERMISSION);
--- a/jdk/test/java/lang/System/LoggerFinder/BaseLoggerFinderTest/BaseLoggerFinderTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/System/LoggerFinder/BaseLoggerFinderTest/BaseLoggerFinderTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -182,8 +182,8 @@
         TestLoggerFinder.LoggerImpl appLogger1 = null;
         try {
             appLogger1 =
-                TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", BaseLoggerFinderTest.class));
-            loggerDescMap.put(appLogger1, "provider.getLogger(\"foo\", BaseLoggerFinderTest.class)");
+                TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", BaseLoggerFinderTest.class.getModule()));
+            loggerDescMap.put(appLogger1, "provider.getLogger(\"foo\", BaseLoggerFinderTest.class.getModule())");
             if (!hasRequiredPermissions) {
                 throw new RuntimeException("Managed to obtain a logger without permission");
             }
@@ -199,8 +199,8 @@
             allowControl.get().set(true);
             try {
                 appLogger1 =
-                    TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", BaseLoggerFinderTest.class));
-                    loggerDescMap.put(appLogger1, "provider.getLogger(\"foo\", BaseLoggerFinderTest.class)");
+                    TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", BaseLoggerFinderTest.class.getModule()));
+                    loggerDescMap.put(appLogger1, "provider.getLogger(\"foo\", BaseLoggerFinderTest.class.getModule())");
             } finally {
                 allowControl.get().set(old);
             }
@@ -208,8 +208,8 @@
 
         TestLoggerFinder.LoggerImpl sysLogger1 = null;
         try {
-            sysLogger1 = TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", Thread.class));
-            loggerDescMap.put(sysLogger1, "provider.getLogger(\"foo\", Thread.class)");
+            sysLogger1 = TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", Thread.class.getModule()));
+            loggerDescMap.put(sysLogger1, "provider.getLogger(\"foo\", Thread.class.getModule())");
             if (!hasRequiredPermissions) {
                 throw new RuntimeException("Managed to obtain a system logger without permission");
             }
@@ -224,8 +224,8 @@
             final boolean old = allowControl.get().get();
             allowControl.get().set(true);
             try {
-                sysLogger1 = TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", Thread.class));
-                loggerDescMap.put(sysLogger1, "provider.getLogger(\"foo\", Thread.class)");
+                sysLogger1 = TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", Thread.class.getModule()));
+                loggerDescMap.put(sysLogger1, "provider.getLogger(\"foo\", Thread.class.getModule())");
             } finally {
                 allowControl.get().set(old);
             }
@@ -254,8 +254,8 @@
         //   callers and non system callers
         Logger appLogger2 = null;
         try {
-            appLogger2 = provider.getLocalizedLogger("foo", loggerBundle, BaseLoggerFinderTest.class);
-            loggerDescMap.put(appLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, BaseLoggerFinderTest.class)");
+            appLogger2 = provider.getLocalizedLogger("foo", loggerBundle, BaseLoggerFinderTest.class.getModule());
+            loggerDescMap.put(appLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, BaseLoggerFinderTest.class.getModule())");
             if (!hasRequiredPermissions) {
                 throw new RuntimeException("Managed to obtain a logger without permission");
             }
@@ -270,8 +270,8 @@
             final boolean old = allowControl.get().get();
             allowControl.get().set(true);
             try {
-                appLogger2 = provider.getLocalizedLogger("foo", loggerBundle, BaseLoggerFinderTest.class);
-                loggerDescMap.put(appLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, BaseLoggerFinderTest.class)");
+                appLogger2 = provider.getLocalizedLogger("foo", loggerBundle, BaseLoggerFinderTest.class.getModule());
+                loggerDescMap.put(appLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, BaseLoggerFinderTest.class.getModule())");
             } finally {
                 allowControl.get().set(old);
             }
@@ -279,8 +279,8 @@
 
         Logger sysLogger2 = null;
         try {
-            sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class);
-            loggerDescMap.put(sysLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, Thread.class)");
+            sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class.getModule());
+            loggerDescMap.put(sysLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, Thread.class.getModule())");
             if (!hasRequiredPermissions) {
                 throw new RuntimeException("Managed to obtain a system logger without permission");
             }
@@ -295,8 +295,8 @@
             final boolean old = allowControl.get().get();
             allowControl.get().set(true);
             try {
-                sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class);
-                loggerDescMap.put(sysLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, Thread.class))");
+                sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class.getModule());
+                loggerDescMap.put(sysLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, Thread.class.getModule()))");
             } finally {
                 allowControl.get().set(old);
             }
--- a/jdk/test/java/lang/System/LoggerFinder/BaseLoggerFinderTest/TestLoggerFinder.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/System/LoggerFinder/BaseLoggerFinderTest/TestLoggerFinder.java	Thu Apr 28 23:08:16 2016 -0700
@@ -30,6 +30,7 @@
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.function.Supplier;
 import java.lang.System.Logger;
+import java.lang.reflect.Module;
 
 /**
  * What our test provider needs to implement.
@@ -176,6 +177,6 @@
         }
     }
 
-    public Logger getLogger(String name, Class<?> caller);
-    public Logger getLocalizedLogger(String name, ResourceBundle bundle, Class<?> caller);
+    public Logger getLogger(String name, Module caller);
+    public Logger getLocalizedLogger(String name, ResourceBundle bundle, Module caller);
 }
--- a/jdk/test/java/lang/System/LoggerFinder/DefaultLoggerFinderTest/DefaultLoggerFinderTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/System/LoggerFinder/DefaultLoggerFinderTest/DefaultLoggerFinderTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -364,8 +364,8 @@
 
         Logger appLogger1 = null;
         try {
-            appLogger1 = provider.getLogger("foo", DefaultLoggerFinderTest.class);
-            loggerDescMap.put(appLogger1, "provider.getApplicationLogger(\"foo\")");
+            appLogger1 = provider.getLogger("foo", DefaultLoggerFinderTest.class.getModule());
+            loggerDescMap.put(appLogger1, "provider.getLogger(\"foo\", DefaultLoggerFinderTest.class.getModule())");
             if (!hasRequiredPermissions) {
                 throw new RuntimeException("Managed to obtain a logger without permission");
             }
@@ -380,8 +380,8 @@
             boolean old = allowControl.get().get();
             allowControl.get().set(true);
             try {
-                appLogger1 =provider.getLogger("foo", DefaultLoggerFinderTest.class);
-                loggerDescMap.put(appLogger1, "provider.getApplicationLogger(\"foo\")");
+                appLogger1 =provider.getLogger("foo", DefaultLoggerFinderTest.class.getModule());
+                loggerDescMap.put(appLogger1, "provider.getLogger(\"foo\", DefaultLoggerFinderTest.class.getModule())");
             } finally {
                 allowControl.get().set(old);
             }
@@ -389,8 +389,8 @@
 
         Logger sysLogger1 = null;
         try {
-            sysLogger1 = provider.getLogger("foo", Thread.class);
-            loggerDescMap.put(sysLogger1, "provider.getSystemLogger(\"foo\")");
+            sysLogger1 = provider.getLogger("foo", Thread.class.getModule());
+            loggerDescMap.put(sysLogger1, "provider.getLogger(\"foo\", Thread.class.getModule())");
             if (!hasRequiredPermissions) {
                 throw new RuntimeException("Managed to obtain a system logger without permission");
             }
@@ -405,8 +405,8 @@
             boolean old = allowControl.get().get();
             allowControl.get().set(true);
             try {
-                sysLogger1 = provider.getLogger("foo", Thread.class);
-                loggerDescMap.put(sysLogger1, "provider.getSystemLogger(\"foo\")");
+                sysLogger1 = provider.getLogger("foo", Thread.class.getModule());
+                loggerDescMap.put(sysLogger1, "provider.getLogger(\"foo\", Thread.class.getModule())");
             } finally {
                 allowControl.get().set(old);
             }
@@ -417,8 +417,8 @@
 
         Logger appLogger2 = null;
         try {
-            appLogger2 = provider.getLocalizedLogger("foo", loggerBundle, DefaultLoggerFinderTest.class);
-            loggerDescMap.put(appLogger2, "provider.getLocalizedApplicationLogger(\"foo\", loggerBundle)");
+            appLogger2 = provider.getLocalizedLogger("foo", loggerBundle, DefaultLoggerFinderTest.class.getModule());
+            loggerDescMap.put(appLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, DefaultLoggerFinderTest.class.getModule())");
             if (!hasRequiredPermissions) {
                 throw new RuntimeException("Managed to obtain a logger without permission");
             }
@@ -433,8 +433,8 @@
             boolean old = allowControl.get().get();
             allowControl.get().set(true);
             try {
-                appLogger2 = provider.getLocalizedLogger("foo", loggerBundle, DefaultLoggerFinderTest.class);
-                loggerDescMap.put(appLogger2, "provider.getLocalizedApplicationLogger(\"foo\", loggerBundle)");
+                appLogger2 = provider.getLocalizedLogger("foo", loggerBundle, DefaultLoggerFinderTest.class.getModule());
+                loggerDescMap.put(appLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, DefaultLoggerFinderTest.class.getModule())");
             } finally {
                 allowControl.get().set(old);
             }
@@ -442,8 +442,8 @@
 
         Logger sysLogger2 = null;
         try {
-            sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class);
-            loggerDescMap.put(sysLogger2, "provider.getLocalizedSystemLogger(\"foo\", loggerBundle)");
+            sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class.getModule());
+            loggerDescMap.put(sysLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, Thread.class.getModule())");
             if (!hasRequiredPermissions) {
                 throw new RuntimeException("Managed to obtain a system logger without permission");
             }
@@ -458,8 +458,8 @@
             boolean old = allowControl.get().get();
             allowControl.get().set(true);
             try {
-                sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class);
-                loggerDescMap.put(sysLogger2, "provider.getLocalizedSystemLogger(\"foo\", loggerBundle)");
+                sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class.getModule());
+                loggerDescMap.put(sysLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, Thread.class.getModule())");
             } finally {
                 allowControl.get().set(old);
             }
--- a/jdk/test/java/lang/System/LoggerFinder/internal/BaseDefaultLoggerFinderTest/BaseDefaultLoggerFinderTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/System/LoggerFinder/internal/BaseDefaultLoggerFinderTest/BaseDefaultLoggerFinderTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -55,6 +55,7 @@
 import jdk.internal.logger.DefaultLoggerFinder;
 import jdk.internal.logger.SimpleConsoleLogger;
 import sun.util.logging.PlatformLogger;
+import java.lang.reflect.Module;
 
 /**
  * @test
@@ -112,10 +113,10 @@
         public final static AtomicLong sequencer = new AtomicLong();
 
 
-        public Logger getLogger(String name, Class<?> caller);
-        public Logger getLocalizedLogger(String name, ResourceBundle bundle, Class<?> caller);
-        void setLevel(Logger logger, Level level, Class<?> caller);
-        void setLevel(Logger logger, PlatformLogger.Level level, Class<?> caller);
+        public Logger getLogger(String name, Module caller);
+        public Logger getLocalizedLogger(String name, ResourceBundle bundle, Module caller);
+        void setLevel(Logger logger, Level level, Module caller);
+        void setLevel(Logger logger, PlatformLogger.Level level, Module caller);
         PlatformLogger.Bridge asPlatformLoggerBridge(Logger logger);
     }
 
@@ -130,7 +131,7 @@
         }
 
         @Override
-        public void setLevel(Logger logger, Level level, Class<?> caller) {
+        public void setLevel(Logger logger, Level level, Module caller) {
             PrivilegedAction<Void> pa = () -> {
                 setLevel(logger, PlatformLogger.toPlatformLevel(level), caller);
                 return null;
@@ -139,7 +140,7 @@
         }
 
         @Override
-        public void setLevel(Logger logger, PlatformLogger.Level level, Class<?> caller) {
+        public void setLevel(Logger logger, PlatformLogger.Level level, Module caller) {
             PrivilegedAction<Logger> pa = () -> demandLoggerFor(logger.getName(), caller);
             Logger impl = AccessController.doPrivileged(pa);
             SimpleConsoleLogger.class.cast(impl)
@@ -606,11 +607,12 @@
             String name,
             ResourceBundle loggerBundle,
             Logger logger,
-            Class<?> caller) {
+            Class<?> callerClass) {
 
         System.out.println("Testing " + loggerDescMap.get(logger) + " [" + logger +"]");
         AtomicLong sequencer = TestLoggerFinder.sequencer;
 
+        Module caller = callerClass.getModule();
         Foo foo = new Foo();
         String fooMsg = foo.toString();
         for (Level loggerLevel : Level.values()) {
--- a/jdk/test/java/lang/System/LoggerFinder/internal/BaseLoggerBridgeTest/BaseLoggerBridgeTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/System/LoggerFinder/internal/BaseLoggerBridgeTest/BaseLoggerBridgeTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -47,6 +47,7 @@
 import java.lang.System.Logger;
 import java.lang.System.Logger.Level;
 import java.util.stream.Stream;
+import java.lang.reflect.Module;
 
 /**
  * @test
@@ -209,8 +210,6 @@
                 return Arrays.deepToString(toArray(false));
             }
 
-
-
             @Override
             public boolean equals(Object obj) {
                 return obj instanceof LogEvent
@@ -342,15 +341,15 @@
 
         }
 
-        public Logger getLogger(String name, Class<?> caller);
-        public Logger getLocalizedLogger(String name, ResourceBundle bundle, Class<?> caller);
+        public Logger getLogger(String name, Module caller);
+        public Logger getLocalizedLogger(String name, ResourceBundle bundle, Module caller);
     }
 
     public static class BaseLoggerFinder extends LoggerFinder implements TestLoggerFinder {
         static final RuntimePermission LOGGERFINDER_PERMISSION =
                 new RuntimePermission("loggerFinder");
         @Override
-        public Logger getLogger(String name, Class<?> caller) {
+        public Logger getLogger(String name, Module caller) {
             SecurityManager sm = System.getSecurityManager();
             if (sm != null) {
                 sm.checkPermission(LOGGERFINDER_PERMISSION);
@@ -375,7 +374,7 @@
         }
     }
 
-    static Logger getLogger(String name, Class<?> caller) {
+    static Logger getLogger(String name, Module caller) {
         boolean old = allowAll.get().get();
         allowAccess.get().set(true);
         try {
@@ -465,7 +464,7 @@
 
         TestLoggerFinder.LoggerImpl appSink = null;
         try {
-            appSink = TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", BaseLoggerBridgeTest.class));
+            appSink = TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", BaseLoggerBridgeTest.class.getModule()));
             if (!hasRequiredPermissions) {
                 throw new RuntimeException("Managed to obtain a system logger without permission");
             }
@@ -480,7 +479,7 @@
             boolean old = allowControl.get().get();
             allowControl.get().set(true);
             try {
-                appSink = TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", BaseLoggerBridgeTest.class));
+                appSink = TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", BaseLoggerBridgeTest.class.getModule()));
             } finally {
                 allowControl.get().set(old);
             }
@@ -489,7 +488,7 @@
 
         TestLoggerFinder.LoggerImpl sysSink = null;
         try {
-            sysSink = TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", Thread.class));
+            sysSink = TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", Thread.class.getModule()));
             if (!hasRequiredPermissions) {
                 throw new RuntimeException("Managed to obtain a system logger without permission");
             }
@@ -527,13 +526,13 @@
 
         Logger sysLogger1 = null;
         try {
-            sysLogger1 = getLogger("foo", Thread.class);
+            sysLogger1 = getLogger("foo", Thread.class.getModule());
             loggerDescMap.put(sysLogger1,
-                    "jdk.internal.logger.LazyLoggers.getLogger(\"foo\", Thread.class)");
+                    "jdk.internal.logger.LazyLoggers.getLogger(\"foo\", Thread.class.getModule())");
 
             if (!hasRequiredPermissions) {
                 // check that the provider would have thrown an exception
-                provider.getLogger("foo", Thread.class);
+                provider.getLogger("foo", Thread.class.getModule());
                 throw new RuntimeException("Managed to obtain a system logger without permission");
             }
         } catch (AccessControlException acx) {
@@ -572,8 +571,8 @@
 
         Logger sysLogger2 = null;
         try {
-            sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class);
-            loggerDescMap.put(sysLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, Thread.class)");
+            sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class.getModule());
+            loggerDescMap.put(sysLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, Thread.class.getModule())");
             if (!hasRequiredPermissions) {
                 throw new RuntimeException("Managed to obtain a system logger without permission");
             }
--- a/jdk/test/java/lang/System/LoggerFinder/internal/BasePlatformLoggerTest/BasePlatformLoggerTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/System/LoggerFinder/internal/BasePlatformLoggerTest/BasePlatformLoggerTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -47,6 +47,7 @@
 import java.security.AccessControlException;
 import java.util.stream.Stream;
 import sun.util.logging.PlatformLogger;
+import java.lang.reflect.Module;
 
 /**
  * @test
@@ -327,12 +328,12 @@
             }
         }
 
-        public Logger getLogger(String name, Class<?> caller);
+        public Logger getLogger(String name, Module caller);
     }
 
     public static class BaseLoggerFinder extends LoggerFinder implements TestLoggerFinder {
         @Override
-        public Logger getLogger(String name, Class<?> caller) {
+        public Logger getLogger(String name, Module caller) {
             SecurityManager sm = System.getSecurityManager();
             if (sm != null) {
                 sm.checkPermission(LOGGERFINDER_PERMISSION);
@@ -433,7 +434,7 @@
         try {
             allowControl.get().set(true);
             appSink = TestLoggerFinder.LoggerImpl.class.cast(
-                        provider.getLogger("foo", BasePlatformLoggerTest.class));
+                        provider.getLogger("foo", BasePlatformLoggerTest.class.getModule()));
         } finally {
             allowControl.get().set(before);
         }
@@ -442,7 +443,8 @@
         before = allowControl.get().get();
         try {
             allowControl.get().set(true);
-            sysSink = TestLoggerFinder.LoggerImpl.class.cast(provider.getLogger("foo", Thread.class));
+            sysSink = TestLoggerFinder.LoggerImpl.class.cast(
+                        provider.getLogger("foo", Thread.class.getModule()));
         } finally {
             allowControl.get().set(before);
         }
--- a/jdk/test/java/lang/System/LoggerFinder/internal/BootstrapLogger/BootstrapLoggerAPIsTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/System/LoggerFinder/internal/BootstrapLogger/BootstrapLoggerAPIsTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -30,7 +30,7 @@
 import java.util.List;
 import java.util.ResourceBundle;
 import java.util.Set;
-
+import java.lang.reflect.Module;
 import jdk.internal.logger.BootstrapLogger;
 import jdk.internal.logger.LazyLoggers;
 
@@ -69,7 +69,7 @@
         }
 
         final Logger LOGGER =
-                LazyLoggers.getLogger("foo.bar", Thread.class);
+                LazyLoggers.getLogger("foo.bar", Thread.class.getModule());
         final sun.util.logging.PlatformLogger.Level PLATFORM_LEVEL =
                 sun.util.logging.PlatformLogger.Level.SEVERE;
         final MyResources BUNDLE = new MyResources();
--- a/jdk/test/java/lang/System/LoggerFinder/internal/BootstrapLogger/BootstrapLoggerTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/System/LoggerFinder/internal/BootstrapLogger/BootstrapLoggerTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -43,6 +43,7 @@
 import java.util.stream.Stream;
 import jdk.internal.logger.BootstrapLogger;
 import jdk.internal.logger.LazyLoggers;
+import java.lang.reflect.Module;
 
 /*
  * @test
@@ -105,7 +106,7 @@
         if (BootstrapLogger.isBooted()) {
             throw new RuntimeException("VM should not be booted!");
         }
-        Logger logger = LazyLoggers.getLogger("foo.bar", Thread.class);
+        Logger logger = LazyLoggers.getLogger("foo.bar", Thread.class.getModule());
 
         if (test != TestCase.NO_SECURITY) {
             LogStream.err.println("Setting security manager");
@@ -261,7 +262,7 @@
         SimplePolicy.allowAll.set(Boolean.TRUE);
         try {
             bazbaz = java.lang.System.LoggerFinder
-                    .getLoggerFinder().getLogger("foo.bar.baz.baz", BootstrapLoggerTest.class);
+                    .getLoggerFinder().getLogger("foo.bar.baz.baz", BootstrapLoggerTest.class.getModule());
         } finally {
             SimplePolicy.allowAll.set(Boolean.FALSE);
         }
--- a/jdk/test/java/lang/System/LoggerFinder/internal/LoggerBridgeTest/LoggerBridgeTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/System/LoggerFinder/internal/LoggerBridgeTest/LoggerBridgeTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -51,6 +51,7 @@
 import java.lang.System.Logger.Level;
 import java.util.stream.Stream;
 import sun.util.logging.PlatformLogger;
+import java.lang.reflect.Module;
 
 /**
  * @test
@@ -164,6 +165,7 @@
                     null, null, level, bundle, key,
                     thrown, params);
         }
+
         public static LogEvent of(long sequenceNumber,
                 boolean isLoggable, String name,
                 sun.util.logging.PlatformLogger.Level level, ResourceBundle bundle,
@@ -231,7 +233,7 @@
         try {
             // Preload classes before the security manager is on.
             providerClass = ClassLoader.getSystemClassLoader().loadClass("LoggerBridgeTest$LogProducerFinder");
-            ((LoggerFinder)providerClass.newInstance()).getLogger("foo", providerClass);
+            ((LoggerFinder)providerClass.newInstance()).getLogger("foo", providerClass.getModule());
         } catch (Exception ex) {
             throw new ExceptionInInitializerError(ex);
         }
@@ -415,7 +417,7 @@
         }
 
         @Override
-        public Logger getLogger(String name, Class<?> caller) {
+        public Logger getLogger(String name, Module caller) {
             SecurityManager sm = System.getSecurityManager();
             if (sm != null) {
                 sm.checkPermission(LOGGERFINDER_PERMISSION);
@@ -430,6 +432,15 @@
         }
     }
 
+    static ClassLoader getClassLoader(Module m) {
+        final boolean before = allowAll.get().getAndSet(true);
+        try {
+            return m.getClassLoader();
+        } finally {
+            allowAll.get().set(before);
+        }
+    }
+
     static final sun.util.logging.PlatformLogger.Level[] julLevels = {
         sun.util.logging.PlatformLogger.Level.ALL,
         sun.util.logging.PlatformLogger.Level.FINEST,
@@ -497,14 +508,14 @@
         try {
             Class<?> bridgeClass = Class.forName("jdk.internal.logger.LazyLoggers");
             lazyGetLogger = bridgeClass.getDeclaredMethod("getLogger",
-                    String.class, Class.class);
+                    String.class, Module.class);
             lazyGetLogger.setAccessible(true);
         } catch (Throwable ex) {
             throw new ExceptionInInitializerError(ex);
         }
     }
 
-    static Logger getLogger(LoggerFinder provider, String name, Class<?> caller) {
+    static Logger getLogger(LoggerFinder provider, String name, Module caller) {
         Logger logger;
         try {
             logger = Logger.class.cast(lazyGetLogger.invoke(null, name, caller));
@@ -522,14 +533,14 @@
         // The method above does not throw exception...
         // call the provider here to verify that an exception would have
         // been thrown by the provider.
-        if (logger != null && caller == Thread.class) {
+        if (logger != null && caller == Thread.class.getModule()) {
             Logger log = provider.getLogger(name, caller);
         }
         return logger;
     }
 
-    static Logger getLogger(LoggerFinder provider, String name, ResourceBundle bundle, Class<?> caller) {
-        if (caller.getClassLoader() != null) {
+    static Logger getLogger(LoggerFinder provider, String name, ResourceBundle bundle, Module caller) {
+        if (getClassLoader(caller) != null) {
             return System.getLogger(name,bundle);
         } else {
             return provider.getLocalizedLogger(name, bundle, caller);
@@ -614,12 +625,12 @@
 
 
         Logger appLogger1 = System.getLogger("foo");
-        loggerDescMap.put(appLogger1, "LogProducer.getApplicationLogger(\"foo\")");
+        loggerDescMap.put(appLogger1, "System.getLogger(\"foo\")");
 
         Logger sysLogger1 = null;
         try {
-            sysLogger1 = getLogger(provider, "foo", Thread.class);
-            loggerDescMap.put(sysLogger1, "LogProducer.getSystemLogger(\"foo\")");
+            sysLogger1 = getLogger(provider, "foo", Thread.class.getModule());
+            loggerDescMap.put(sysLogger1, "provider.getLogger(\"foo\", Thread.class.getModule())");
             if (!hasRequiredPermissions) {
                 throw new RuntimeException("Managed to obtain a system logger without permission");
             }
@@ -636,12 +647,12 @@
 
         Logger appLogger2 =
                 System.getLogger("foo", loggerBundle);
-        loggerDescMap.put(appLogger2, "LogProducer.getApplicationLogger(\"foo\", loggerBundle)");
+        loggerDescMap.put(appLogger2, "System.getLogger(\"foo\", loggerBundle)");
 
         Logger sysLogger2 = null;
         try {
-            sysLogger2 = getLogger(provider, "foo", loggerBundle, Thread.class);
-            loggerDescMap.put(sysLogger2, "provider.getSystemLogger(\"foo\", loggerBundle)");
+            sysLogger2 = getLogger(provider, "foo", loggerBundle, Thread.class.getModule());
+            loggerDescMap.put(sysLogger2, "provider.getLogger(\"foo\", loggerBundle, Thread.class.getModule())");
             if (!hasRequiredPermissions) {
                 throw new RuntimeException("Managed to obtain a system logger without permission");
             }
@@ -671,9 +682,9 @@
         allowControl.get().set(true);
         try {
            appSink = LogProducerFinder.LoggerImpl.class.cast(
-                   provider.getLogger("foo",  LoggerBridgeTest.class));
+                   provider.getLogger("foo",  LoggerBridgeTest.class.getModule()));
            sysSink = LogProducerFinder.LoggerImpl.class.cast(
-                        provider.getLogger("foo", Thread.class));
+                        provider.getLogger("foo", Thread.class.getModule()));
         } finally {
             allowControl.get().set(old);
         }
--- a/jdk/test/java/lang/System/LoggerFinder/internal/LoggerFinderLoaderTest/LoggerFinderLoaderTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/System/LoggerFinder/internal/LoggerFinderLoaderTest/LoggerFinderLoaderTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -53,6 +53,7 @@
 import java.util.ServiceLoader;
 import java.util.concurrent.atomic.AtomicReference;
 import jdk.internal.logger.SimpleConsoleLogger;
+import java.lang.reflect.Module;
 
 /**
  * @test
@@ -166,8 +167,8 @@
 
         }
 
-        public Logger getLogger(String name, Class<?> caller);
-        public Logger getLocalizedLogger(String name, ResourceBundle bundle, Class<?> caller);
+        public Logger getLogger(String name, Module caller);
+        public Logger getLocalizedLogger(String name, ResourceBundle bundle, Module caller);
     }
 
     public static class BaseLoggerFinder extends LoggerFinder implements TestLoggerFinder {
@@ -187,7 +188,7 @@
 
 
         @Override
-        public Logger getLogger(String name, Class<?> caller) {
+        public Logger getLogger(String name, Module caller) {
             SecurityManager sm = System.getSecurityManager();
             if (sm != null) {
                 sm.checkPermission(LOGGERFINDER_PERMISSION);
@@ -210,7 +211,7 @@
             throw new ServiceConfigurationError("Should not come here");
         }
         @Override
-        public Logger getLogger(String name, Class<?> caller) {
+        public Logger getLogger(String name, Module caller) {
             throw new ServiceConfigurationError("Should not come here");
         }
     }
--- a/jdk/test/java/lang/System/LoggerFinder/internal/PlatformLoggerBridgeTest/PlatformLoggerBridgeTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/System/LoggerFinder/internal/PlatformLoggerBridgeTest/PlatformLoggerBridgeTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -49,6 +49,7 @@
 import java.lang.System.Logger.Level;
 import java.util.stream.Stream;
 import sun.util.logging.PlatformLogger;
+import java.lang.reflect.Module;
 
 /**
  * @test
@@ -94,7 +95,7 @@
         try {
             // Preload classes before the security manager is on.
             providerClass = ClassLoader.getSystemClassLoader().loadClass("PlatformLoggerBridgeTest$LogProducerFinder");
-            ((LoggerFinder)providerClass.newInstance()).getLogger("foo", providerClass);
+            ((LoggerFinder)providerClass.newInstance()).getLogger("foo", providerClass.getModule());
         } catch (Exception ex) {
             throw new ExceptionInInitializerError(ex);
         }
@@ -415,7 +416,7 @@
         }
 
         @Override
-        public Logger getLogger(String name, Class<?> caller) {
+        public Logger getLogger(String name, Module caller) {
             SecurityManager sm = System.getSecurityManager();
             if (sm != null) {
                 sm.checkPermission(LOGGERFINDER_PERMISSION);
@@ -598,7 +599,7 @@
         allowControl.get().set(true);
         try {
            sysSink = LogProducerFinder.LoggerImpl.class.cast(
-                        provider.getLogger("foo", Thread.class));
+                        provider.getLogger("foo", Thread.class.getModule()));
         } finally {
             allowControl.get().set(old);
         }
--- a/jdk/test/java/lang/System/LoggerFinder/internal/api/LoggerFinderAPITest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/System/LoggerFinder/internal/api/LoggerFinderAPITest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -469,12 +469,12 @@
         errors.append(test.testGetLoggerOverriddenOnSpi());
         java.lang.System.Logger julLogger =
                 java.lang.System.LoggerFinder.getLoggerFinder()
-                        .getLogger("foo", LoggerFinderAPITest.class);
+                        .getLogger("foo", LoggerFinderAPITest.class.getModule());
         errors.append(test.testDefaultJULLogger(julLogger));
         if (errors.length() > 0) throw new RuntimeException(errors.toString());
         java.lang.System.Logger julSystemLogger =
                 java.lang.System.LoggerFinder.getLoggerFinder()
-                        .getLogger("bar", Thread.class);
+                        .getLogger("bar", Thread.class.getModule());
         errors.append(test.testDefaultJULLogger(julSystemLogger));
         if (errors.length() > 0) throw new RuntimeException(errors.toString());
         java.lang.System.Logger julLocalizedLogger =
@@ -482,7 +482,7 @@
                 System.getLogger("baz", bundleLocalized);
         java.lang.System.Logger julLocalizedSystemLogger =
                 java.lang.System.LoggerFinder.getLoggerFinder()
-                        .getLocalizedLogger("oof", bundleLocalized, Thread.class);
+                        .getLocalizedLogger("oof", bundleLocalized, Thread.class.getModule());
         final String error = errors.toString();
         if (!error.isEmpty()) throw new RuntimeException(error);
         for (java.lang.System.Logger logger : new java.lang.System.Logger[] {
--- a/jdk/test/java/lang/System/LoggerFinder/internal/backend/LoggerFinderBackendTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/System/LoggerFinder/internal/backend/LoggerFinderBackendTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -77,6 +77,7 @@
 import java.util.logging.LogRecord;
 import java.util.logging.Logger;
 import sun.util.logging.internal.LoggingProviderImpl;
+import java.lang.reflect.Module;
 
 /**
  * @author danielfuchs
@@ -1506,7 +1507,7 @@
         Logger getBackendLogger(String name) {
             if (isSystem) {
                 return LoggingProviderImpl.getLogManagerAccess().demandLoggerFor(
-                        LogManager.getLogManager(), name, Thread.class);
+                        LogManager.getLogManager(), name, Thread.class.getModule());
             } else {
                 return Logger.getLogger(name);
             }
@@ -1699,7 +1700,7 @@
                 Collections.synchronizedMap(new HashMap<>());
 
         @Override
-        public java.lang.System.Logger getLogger(String name, Class<?> caller) {
+        public java.lang.System.Logger getLogger(String name, Module caller) {
             ClassLoader callerLoader = caller.getClassLoader();
             if (callerLoader == null) {
                 systemLoggers.putIfAbsent(name, new CustomLogger(name));
@@ -1827,8 +1828,8 @@
             public void setLevel(java.lang.System.Logger logger, Level level) {
                 final CustomLoggerFinder.CustomLogger l =
                         (CustomLoggerFinder.CustomLogger)
-                        (isSystem ? provider.getLogger(logger.getName(), Thread.class) :
-                        provider.getLogger(logger.getName(), LoggerFinderBackendTest.class));
+                        (isSystem ? provider.getLogger(logger.getName(), Thread.class.getModule()) :
+                        provider.getLogger(logger.getName(), LoggerFinderBackendTest.class.getModule()));
                 l.setLevel(provider.fromJul(level));
             }
             @Override
@@ -1840,8 +1841,8 @@
             CustomLoggerFinder.CustomLevel getLevel(java.lang.System.Logger logger) {
                 final CustomLoggerFinder.CustomLogger l =
                         (CustomLoggerFinder.CustomLogger)
-                        (isSystem ? provider.getLogger(logger.getName(), Thread.class) :
-                        provider.getLogger(logger.getName(), LoggerFinderBackendTest.class));
+                        (isSystem ? provider.getLogger(logger.getName(), Thread.class.getModule()) :
+                        provider.getLogger(logger.getName(), LoggerFinderBackendTest.class.getModule()));
                 return l.level;
             }
 
@@ -1962,7 +1963,7 @@
         try {
             Class<?> lazyLoggers = jdk.internal.logger.LazyLoggers.class;
             getLazyLogger = lazyLoggers.getMethod("getLazyLogger",
-                    String.class, Class.class);
+                    String.class, Module.class);
             getLazyLogger.setAccessible(true);
             Class<?> loggerFinderLoader =
                     Class.forName("java.lang.System$LoggerFinder");
@@ -1973,7 +1974,7 @@
         }
     }
 
-    static java.lang.System.Logger getSystemLogger(String name, Class<?> caller) throws Exception {
+    static java.lang.System.Logger getSystemLogger(String name, Module caller) throws Exception {
         try {
             return java.lang.System.Logger.class.cast(getLazyLogger.invoke(null, name, caller));
         } catch (InvocationTargetException x) {
@@ -1986,7 +1987,7 @@
         }
     }
     static java.lang.System.Logger getSystemLogger(String name,
-            ResourceBundle bundle, Class<?> caller) throws Exception {
+            ResourceBundle bundle, Module caller) throws Exception {
         try {
             LoggerFinder provider = LoggerFinder.class.cast(accessLoggerFinder.invoke(null));
             return provider.getLocalizedLogger(name, bundle, caller);
@@ -2047,14 +2048,14 @@
         final BackendTester tester = factory.createBackendTester(false);
         final java.lang.System.Logger logger =
                 java.lang.System.LoggerFinder.getLoggerFinder()
-                        .getLogger("foo", LoggerFinderBackendTest.class);
+                        .getLogger("foo", LoggerFinderBackendTest.class.getModule());
 
         testLogger(tester, logger, nb);
 
         // Test a simple system logger with JUL backend
         final java.lang.System.Logger system =
                 java.lang.System.LoggerFinder.getLoggerFinder()
-                        .getLogger("bar", Thread.class);
+                        .getLogger("bar", Thread.class.getModule());
         final BackendTester systemTester = factory.createBackendTester(true);
         testLogger(systemTester, system, nb);
 
@@ -2062,7 +2063,7 @@
         // JUL backend
         final java.lang.System.Logger noBundleLogger =
                 java.lang.System.LoggerFinder.getLoggerFinder()
-                        .getLocalizedLogger("baz", null, LoggerFinderBackendTest.class);
+                        .getLocalizedLogger("baz", null, LoggerFinderBackendTest.class.getModule());
         final BackendTester noBundleTester =
                 factory.createBackendTester(false, spiLoggerClass);
         testLogger(noBundleTester, noBundleLogger, nb);
@@ -2071,7 +2072,7 @@
         // backend
         final java.lang.System.Logger noBundleSysLogger =
                 java.lang.System.LoggerFinder.getLoggerFinder()
-                        .getLocalizedLogger("oof", null, Thread.class);
+                        .getLocalizedLogger("oof", null, Thread.class.getModule());
         final BackendTester noBundleSysTester =
                 factory.createBackendTester(true, spiLoggerClass);
         testLogger(noBundleSysTester, noBundleSysLogger, nb);
@@ -2085,14 +2086,14 @@
             System.out.println("System.Loggers.getLogger(\"baz\", null): got expected " + x);
         }
         final java.lang.System.Logger noBundleExtensionLogger =
-                getSystemLogger("baz", null, LoggerFinderBackendTest.class);
+                getSystemLogger("baz", null, LoggerFinderBackendTest.class.getModule());
         final BackendTester noBundleExtensionTester =
                 factory.createBackendTester(false, jdkLoggerClass);
         testLogger(noBundleExtensionTester, noBundleExtensionLogger, nb);
 
         // Test a simple system logger with JUL backend
         final java.lang.System.Logger sysExtensionLogger =
-                getSystemLogger("oof", Thread.class);
+                getSystemLogger("oof", Thread.class.getModule());
         final BackendTester sysExtensionTester =
                 factory.createBackendTester(true, jdkLoggerClass);
         testLogger(sysExtensionTester, sysExtensionLogger, nb);
@@ -2100,7 +2101,7 @@
         // Test a localized system logger with null resource bundle and JUL
         // backend
         final java.lang.System.Logger noBundleSysExtensionLogger =
-                getSystemLogger("oof", null, Thread.class);
+                getSystemLogger("oof", null, Thread.class.getModule());
         final BackendTester noBundleSysExtensionTester =
                 factory.createBackendTester(true, jdkLoggerClass);
         testLogger(noBundleSysExtensionTester, noBundleSysExtensionLogger, nb);
@@ -2127,7 +2128,7 @@
                 ResourceBundle.getBundle(ResourceBundeLocalized.class.getName());
         final java.lang.System.Logger bundleLogger =
                 java.lang.System.LoggerFinder.getLoggerFinder()
-                        .getLocalizedLogger("toto", bundle, LoggerFinderBackendTest.class);
+                        .getLocalizedLogger("toto", bundle, LoggerFinderBackendTest.class.getModule());
         final BackendTester bundleTester =
                 factory.createBackendTester(false, spiLoggerClass, bundle);
         testLogger(bundleTester, bundleLogger, nb);
@@ -2135,7 +2136,7 @@
         // Test a localized system logger with resource bundle and JUL backend
         final java.lang.System.Logger bundleSysLogger =
                 java.lang.System.LoggerFinder.getLoggerFinder()
-                        .getLocalizedLogger("titi", bundle, Thread.class);
+                        .getLocalizedLogger("titi", bundle, Thread.class.getModule());
         final BackendTester bundleSysTester =
                 factory.createBackendTester(true, spiLoggerClass, bundle);
         testLogger(bundleSysTester, bundleSysLogger, nb);
@@ -2151,7 +2152,7 @@
         // Test a localized Jdk system logger with resource bundle and JUL
         // backend
         final java.lang.System.Logger bundleExtensionSysLogger =
-                getSystemLogger("titu", bundle, Thread.class);
+                getSystemLogger("titu", bundle, Thread.class.getModule());
         final BackendTester bundleExtensionSysTester =
                 factory.createBackendTester(true, jdkLoggerClass, bundle);
         testLogger(bundleExtensionSysTester, bundleExtensionSysLogger, nb);
--- a/jdk/test/java/lang/System/LoggerFinder/jdk/DefaultLoggerBridgeTest/DefaultLoggerBridgeTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/System/LoggerFinder/jdk/DefaultLoggerBridgeTest/DefaultLoggerBridgeTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -48,6 +48,7 @@
 import java.lang.System.Logger;
 import java.util.stream.Stream;
 import sun.util.logging.internal.LoggingProviderImpl;
+import java.lang.reflect.Module;
 
 /**
  * @test
@@ -246,7 +247,7 @@
         }
     }
 
-    static Logger getLogger(String name, Class<?> caller) {
+    static Logger getLogger(String name, Module caller) {
         boolean old = allowAccess.get().get();
         allowAccess.get().set(true);
         try {
@@ -311,8 +312,8 @@
                 ResourceBundle.getBundle(MyLoggerBundle.class.getName());
         final Map<Object, String> loggerDescMap = new HashMap<>();
 
-        Logger sysLogger1a = getLogger("foo", Thread.class);
-        loggerDescMap.put(sysLogger1a, "jdk.internal.logger.LazyLoggers.getLogger(\"foo\", Thread.class)");
+        Logger sysLogger1a = getLogger("foo", Thread.class.getModule());
+        loggerDescMap.put(sysLogger1a, "jdk.internal.logger.LazyLoggers.getLogger(\"foo\", Thread.class.getModule())");
 
         Logger appLogger1 = System.getLogger("foo");
         loggerDescMap.put(appLogger1, "System.getLogger(\"foo\")");
@@ -341,9 +342,9 @@
 
         Logger sysLogger1b = null;
         try {
-            sysLogger1b = provider.getLogger("foo", Thread.class);
+            sysLogger1b = provider.getLogger("foo", Thread.class.getModule());
             if (sysLogger1b != sysLogger1a) {
-                loggerDescMap.put(sysLogger1b, "provider.getLogger(\"foo\", Thread.class)");
+                loggerDescMap.put(sysLogger1b, "provider.getLogger(\"foo\", Thread.class.getModule())");
             }
             if (!hasRequiredPermissions) {
                 throw new RuntimeException("Managed to obtain a system logger without permission");
@@ -367,8 +368,8 @@
 
         Logger sysLogger2 = null;
         try {
-            sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class);
-            loggerDescMap.put(sysLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, Thread.class)");
+            sysLogger2 = provider.getLocalizedLogger("foo", loggerBundle, Thread.class.getModule());
+            loggerDescMap.put(sysLogger2, "provider.getLocalizedLogger(\"foo\", loggerBundle, Thread.class.getModule())");
             if (!hasRequiredPermissions) {
                 throw new RuntimeException("Managed to obtain a system logger without permission");
             }
@@ -396,9 +397,9 @@
         allowAll.get().set(true);
         try {
             sysSink = LoggingProviderImpl.getLogManagerAccess().demandLoggerFor(
-                    LogManager.getLogManager(), "foo", Thread.class);
+                    LogManager.getLogManager(), "foo", Thread.class.getModule());
             appSink = LoggingProviderImpl.getLogManagerAccess().demandLoggerFor(
-                    LogManager.getLogManager(), "foo", DefaultLoggerBridgeTest.class);
+                    LogManager.getLogManager(), "foo", DefaultLoggerBridgeTest.class.getModule());
             if (appSink == sysSink) {
                 throw new RuntimeException("identical backend loggers");
             }
--- a/jdk/test/java/lang/System/LoggerFinder/jdk/DefaultPlatformLoggerTest/DefaultPlatformLoggerTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/System/LoggerFinder/jdk/DefaultPlatformLoggerTest/DefaultPlatformLoggerTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -44,6 +44,7 @@
 import java.lang.System.LoggerFinder;
 import sun.util.logging.PlatformLogger;
 import sun.util.logging.internal.LoggingProviderImpl;
+import java.lang.reflect.Module;
 
 /**
  * @test
@@ -244,9 +245,9 @@
         LoggerFinder provider = LoggerFinder.getLoggerFinder();
         java.util.logging.Logger appSink = LoggingProviderImpl.getLogManagerAccess()
                 .demandLoggerFor(LogManager.getLogManager(), "foo",
-                        DefaultPlatformLoggerTest.class);
+                        DefaultPlatformLoggerTest.class.getModule());
         java.util.logging.Logger sysSink = LoggingProviderImpl.getLogManagerAccess()
-                .demandLoggerFor(LogManager.getLogManager(),"foo", Thread.class);
+                .demandLoggerFor(LogManager.getLogManager(),"foo", Thread.class.getModule());
         appSink.addHandler(new MyHandler());
         sysSink.addHandler(new MyHandler());
         appSink.setUseParentHandlers(VERBOSE);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/ArrayConstructorTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 8155106
+ * @run testng/othervm -ea -esa test.java.lang.invoke.ArrayConstructorTest
+ */
+package test.java.lang.invoke;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+
+import static java.lang.invoke.MethodType.methodType;
+
+import static org.testng.AssertJUnit.*;
+
+import org.testng.annotations.*;
+
+
+public class ArrayConstructorTest {
+
+    static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
+
+    @Test
+    public static void testFindConstructorArray() {
+        boolean caught = false;
+        try {
+            MethodHandle h = LOOKUP.findConstructor(Object[].class, methodType(void.class));
+        } catch (NoSuchMethodException nsme) {
+            assertEquals("no constructor for array class: [Ljava.lang.Object;", nsme.getMessage());
+            caught = true;
+        } catch (Exception e) {
+            throw new AssertionError("unexpected exception: " + e);
+        }
+        assertTrue(caught);
+    }
+
+    @DataProvider
+    static Object[][] arrayConstructorNegative() {
+        return new Object[][]{
+                {String.class, IllegalArgumentException.class, "not an array class: java.lang.String"},
+                {null, NullPointerException.class, null}
+        };
+    }
+
+    @Test(dataProvider = "arrayConstructorNegative")
+    public static void testArrayConstructorNegative(Class<?> clazz, Class<?> exceptionClass, String message) {
+        boolean caught = false;
+        try {
+            MethodHandle h = MethodHandles.arrayConstructor(clazz);
+        } catch (Exception e) {
+            assertEquals(exceptionClass, e.getClass());
+            if (message != null) {
+                assertEquals(message, e.getMessage());
+            }
+            caught = true;
+        }
+        assertTrue(caught);
+    }
+
+    @Test
+    public static void testArrayConstructor() throws Throwable {
+        MethodHandle h = MethodHandles.arrayConstructor(String[].class);
+        assertEquals(methodType(String[].class, int.class), h.type());
+        String[] a = (String[]) h.invoke(17);
+        assertEquals(17, a.length);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/JavaUtilConcurrentLookupTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016, 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
+ * @summary Tests that Lookup can be produced from classes under java.util.concurrent
+ * @bug 8154447
+ * @compile/module=java.base java/util/concurrent/LookupTester.java
+ * @run testng/othervm JavaUtilConcurrentLookupTest
+ */
+
+import org.testng.annotations.Test;
+
+import java.util.concurrent.LookupTester;
+
+public class JavaUtilConcurrentLookupTest {
+
+    @Test
+    public void testLookup() {
+        LookupTester.getLookup();
+    }
+
+    @Test
+    public void testLookupIn() {
+        LookupTester.getLookupIn();
+    }
+}
--- a/jdk/test/java/lang/invoke/LoopCombinatorTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/LoopCombinatorTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -26,8 +26,12 @@
 /* @test
  * @bug 8139885
  * @bug 8150635
+ * @bug 8150956
  * @bug 8150957
+ * @bug 8152667
  * @bug 8153637
+ * @bug 8154751
+ * @bug 8154754
  * @run testng/othervm -ea -esa test.java.lang.invoke.LoopCombinatorTest
  */
 
@@ -266,6 +270,28 @@
     }
 
     @Test
+    public static void testWhileVoidInit() throws Throwable {
+        While w = new While();
+        int v = 5;
+        MethodHandle loop = MethodHandles.whileLoop(While.MH_voidInit.bindTo(w), While.MH_voidPred.bindTo(w),
+                While.MH_voidBody.bindTo(w));
+        assertEquals(While.MT_void, loop.type());
+        loop.invoke(v);
+        assertEquals(v, w.i);
+    }
+
+    @Test
+    public static void testDoWhileVoidInit() throws Throwable {
+        While w = new While();
+        int v = 5;
+        MethodHandle loop = MethodHandles.doWhileLoop(While.MH_voidInit.bindTo(w), While.MH_voidBody.bindTo(w),
+                While.MH_voidPred.bindTo(w));
+        assertEquals(While.MT_void, loop.type());
+        loop.invoke(v);
+        assertEquals(v, w.i);
+    }
+
+    @Test
     public static void testCountedLoop() throws Throwable {
         // String s = "Lambdaman!"; for (int i = 0; i < 13; ++i) { s = "na " + s; } return s; => a variation on a well known theme
         MethodHandle fit13 = MethodHandles.constant(int.class, 13);
@@ -275,6 +301,14 @@
     }
 
     @Test
+    public static void testCountedLoopVoidInit() throws Throwable {
+        MethodHandle fit5 = MethodHandles.constant(int.class, 5);
+        MethodHandle loop = MethodHandles.countedLoop(fit5, MethodHandles.zero(void.class), Counted.MH_printHello);
+        assertEquals(Counted.MT_countedPrinting, loop.type());
+        loop.invoke();
+    }
+
+    @Test
     public static void testCountedArrayLoop() throws Throwable {
         // int[] a = new int[]{0}; for (int i = 0; i < 13; ++i) { ++a[0]; } => a[0] == 13
         MethodHandle fit13 = MethodHandles.dropArguments(MethodHandles.constant(int.class, 13), 0, int[].class);
@@ -294,6 +328,74 @@
     }
 
     @Test
+    public static void testCountedLoopNullBody() throws Throwable {
+        MethodHandle h5 = MethodHandles.constant(int.class, 5);
+        MethodHandle h13 = MethodHandles.constant(int.class, 13);
+        MethodHandle loop = MethodHandles.countedLoop(h5, h13, null);
+        assertEquals(methodType(int.class), loop.type());
+        assertEquals(13, loop.invoke());
+    }
+
+    @Test
+    public static void testCountedLoopNullIterations() throws Throwable {
+        MethodHandle loop = MethodHandles.countedLoop(null, null, null);
+        assertEquals(methodType(void.class), loop.type());
+        loop.invoke();
+    }
+
+    @Test
+    public static void testCountedLoopNullInitAndBody() throws Throwable {
+        MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, 5), null, null);
+        assertEquals(methodType(void.class), loop.type());
+        loop.invoke();
+    }
+
+    @DataProvider
+    static Object[][] countedLoopBodyParameters() {
+        return new Object[][] {
+                {methodType(String.class), methodType(String.class, int.class)},
+                {methodType(String.class, List.class), methodType(String.class, int.class)},
+                {methodType(String.class, List.class), methodType(String.class, int.class, String.class)}
+        };
+    }
+
+    @Test(dataProvider = "countedLoopBodyParameters")
+    public static void testCountedLoopBodyParameters(MethodType initType, MethodType bodyType) throws Throwable {
+        MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, 5),
+                MethodHandles.empty(initType), MethodHandles.empty(bodyType));
+        assertEquals(initType, loop.type());
+    }
+
+    @DataProvider
+    static Object[][] countedLoopTypes() {
+        return new Object[][]{{void.class}, {int.class}, {Object.class}, {String.class}, {List.class}};
+    }
+
+    @Test(dataProvider = "countedLoopTypes")
+    public static void testCountedLoopBodyParametersNullInit(Class<?> t) throws Throwable {
+        MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, 5), null,
+                MethodHandles.empty(methodType(t, int.class)));
+        assertEquals(methodType(t), loop.type());
+        loop.invoke();
+    }
+
+    @Test
+    public static void testCountedLoopStateDefinedByBody() throws Throwable {
+        MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, 5), null, Counted.MH_stateBody);
+        assertEquals(Counted.MT_bodyDeterminesState, loop.type());
+        assertEquals("sssssnull01234", loop.invoke());
+    }
+
+    @Test
+    public static void testCountedLoopArgsDefinedByIterations() throws Throwable {
+        MethodHandle loop = MethodHandles.countedLoop(
+                MethodHandles.dropArguments(MethodHandles.constant(int.class, 3), 0, String.class),
+                null, Counted.MH_append);
+        assertEquals(Counted.MT_iterationsDefineArgs, loop.type());
+        assertEquals("hello012", loop.invoke("hello"));
+    }
+
+    @Test
     public static void testCountedRangeLoop() throws Throwable {
         // String s = "Lambdaman!"; for (int i = -5; i < 8; ++i) { s = "na " + s; } return s; => a well known theme
         MethodHandle fitm5 = MethodHandles.dropArguments(Counted.MH_m5, 0, String.class);
@@ -316,6 +418,23 @@
     }
 
     @Test
+    public static void testCountedLoopEmpty() throws Throwable {
+        // for (int i = 0; i < 5; ++i) { /* empty */ }
+        MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, 5), null, null);
+        assertEquals(methodType(void.class), loop.type());
+        loop.invoke();
+    }
+
+    @Test
+    public static void testCountedRangeLoopEmpty() throws Throwable {
+        // for (int i = -5; i < 5; ++i) { /* empty */ }
+        MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, -5),
+                MethodHandles.constant(int.class, 5), null, null);
+        assertEquals(methodType(void.class), loop.type());
+        loop.invoke();
+    }
+
+    @Test
     public static void testIterateSum() throws Throwable {
         // Integer[] a = new Integer[]{1,2,3,4,5,6}; int sum = 0; for (int e : a) { sum += e; } return sum; => 21
         MethodHandle loop = MethodHandles.iteratedLoop(Iterate.MH_sumIterator, Iterate.MH_sumInit, Iterate.MH_sumStep);
@@ -360,7 +479,8 @@
     public static void testIterateNullBody() {
         boolean caught = false;
         try {
-            MethodHandles.iteratedLoop(MethodHandles.identity(int.class), MethodHandles.identity(int.class), null);
+            MethodHandles.iteratedLoop(MethodHandles.empty(methodType(Iterator.class, int.class)),
+                    MethodHandles.identity(int.class), null);
         } catch (IllegalArgumentException iae) {
             assertEquals("iterated loop body must not be null", iae.getMessage());
             caught = true;
@@ -368,6 +488,102 @@
         assertTrue(caught);
     }
 
+    @DataProvider
+    static Object[][] wrongIteratorTypes() {
+        return new Object[][]{{void.class}, {Object.class}, {Iterable.class}};
+    }
+
+    @Test(dataProvider = "wrongIteratorTypes")
+    public static void testIterateVoidIterator(Class<?> it) {
+        boolean caught = false;
+        MethodType v = methodType(it);
+        try {
+            MethodHandles.iteratedLoop(MethodHandles.empty(v), null, MethodHandles.empty(v));
+        } catch(IllegalArgumentException iae) {
+            assertEquals("iteratedLoop first argument must have Iterator return type", iae.getMessage());
+            caught = true;
+        }
+        assertTrue(caught);
+    }
+
+    @Test
+    public static void testIterateVoidInit() throws Throwable {
+        MethodHandle loop = MethodHandles.iteratedLoop(null, Iterate.MH_voidInit, Iterate.MH_printStep);
+        assertEquals(Iterate.MT_print, loop.type());
+        loop.invoke(Arrays.asList("hello", "world"));
+    }
+
+    @DataProvider
+    static Object[][] iterateParameters() {
+        MethodType i = methodType(int.class);
+        MethodType sil_i = methodType(int.class, String.class, int.class, List.class);
+        MethodType sl_v = methodType(void.class, String.class, List.class);
+        MethodType l_it = methodType(Iterator.class, List.class);
+        MethodType li_it = methodType(Iterator.class, List.class, int.class);
+        MethodType l_i = methodType(int.class, List.class);
+        MethodType _it = methodType(Iterator.class);
+        MethodType si_i = methodType(int.class, String.class, int.class);
+        MethodType s_i = methodType(int.class, String.class);
+        return new Object[][]{
+                {null, null, sl_v},
+                {null, i, sil_i},
+                {null, l_i, sil_i},
+                {l_it, null, sl_v},
+                {l_it, i, sil_i},
+                {li_it, l_i, sil_i},
+                {l_it, null, sil_i},
+                {li_it, null, sl_v},
+                {_it, l_i, si_i},
+                {_it, l_i, s_i}
+        };
+    }
+
+    @Test(dataProvider = "iterateParameters")
+    public static void testIterateParameters(MethodType it, MethodType in, MethodType bo) throws Throwable {
+        MethodHandle iterator = it == null ? null : MethodHandles.empty(it);
+        MethodHandle init = in == null ? null : MethodHandles.empty(in);
+        MethodHandle loop = MethodHandles.iteratedLoop(iterator, init, MethodHandles.empty(bo));
+        MethodType lt = loop.type();
+        if (it == null && in == null) {
+            assertEquals(bo.dropParameterTypes(0, 1), lt);
+        } else if (it == null) {
+            if (in.parameterCount() == 0) {
+                assertEquals(bo.dropParameterTypes(0, in.returnType() == void.class ? 1 : 2), lt);
+            } else {
+                assertEquals(methodType(bo.returnType(), in.parameterArray()), lt);
+            }
+        } else if (in == null) {
+            assertEquals(methodType(bo.returnType(), it.parameterArray()), lt);
+        } else if (it.parameterCount() > in.parameterCount()) {
+            assertEquals(methodType(bo.returnType(), it.parameterArray()), lt);
+        } else if (it.parameterCount() < in.parameterCount()) {
+            assertEquals(methodType(bo.returnType(), in.parameterArray()), lt);
+        } else {
+            // both it, in present; with equal parameter list lengths
+            assertEquals(it.parameterList(), lt.parameterList());
+            assertEquals(in.parameterList(), lt.parameterList());
+            assertEquals(bo.returnType(), lt.returnType());
+        }
+    }
+
+    @Test
+    public static void testIteratorSubclass() throws Throwable {
+        MethodHandle loop = MethodHandles.iteratedLoop(MethodHandles.empty(methodType(BogusIterator.class, List.class)),
+                null, MethodHandles.empty(methodType(void.class, String.class)));
+        assertEquals(methodType(void.class, List.class), loop.type());
+    }
+
+    static class BogusIterator implements Iterator {
+        @Override
+        public boolean hasNext() {
+            return false;
+        }
+        @Override
+        public Object next() {
+            return null;
+        }
+    }
+
     static class Empty {
 
         static void f() { }
@@ -604,6 +820,10 @@
 
         private int i = 0;
 
+        void voidInit(int k) {
+            // empty
+        }
+
         void voidBody(int k) {
             ++i;
         }
@@ -623,6 +843,7 @@
         static final MethodType MT_zipInitZip = methodType(List.class, Iterator.class, Iterator.class);
         static final MethodType MT_zipPred = methodType(boolean.class, List.class, Iterator.class, Iterator.class);
         static final MethodType MT_zipStep = methodType(List.class, List.class, Iterator.class, Iterator.class);
+        static final MethodType MT_voidInit = methodType(void.class, int.class);
         static final MethodType MT_voidBody = methodType(void.class, int.class);
         static final MethodType MT_voidPred = methodType(boolean.class, int.class);
 
@@ -635,6 +856,7 @@
         static final MethodHandle MH_zipInitZip;
         static final MethodHandle MH_zipPred;
         static final MethodHandle MH_zipStep;
+        static final MethodHandle MH_voidInit;
         static final MethodHandle MH_voidBody;
         static final MethodHandle MH_voidPred;
 
@@ -654,6 +876,7 @@
                 MH_zipInitZip = LOOKUP.findStatic(WHILE, "zipInitZip", MT_zipInitZip);
                 MH_zipPred = LOOKUP.findStatic(WHILE, "zipPred", MT_zipPred);
                 MH_zipStep = LOOKUP.findStatic(WHILE, "zipStep", MT_zipStep);
+                MH_voidInit = LOOKUP.findVirtual(WHILE, "voidInit", MT_voidInit);
                 MH_voidBody = LOOKUP.findVirtual(WHILE, "voidBody", MT_voidBody);
                 MH_voidPred = LOOKUP.findVirtual(WHILE, "voidPred", MT_voidPred);
             } catch (Exception e) {
@@ -685,6 +908,17 @@
             return x + counter;
         }
 
+        static String stateBody(int counter, String s) {
+            return "s" + s + counter;
+        }
+
+        static String append(int counter, String localState, String loopArg) {
+            if (null == localState) {
+                return loopArg + counter;
+            }
+            return localState + counter;
+        }
+
         static final Class<Counted> COUNTED = Counted.class;
 
         static final MethodType MT_start = methodType(String.class, String.class);
@@ -692,6 +926,8 @@
         static final MethodType MT_stepUpdateArray = methodType(void.class, int.class, int[].class);
         static final MethodType MT_printHello = methodType(void.class, int.class);
         static final MethodType MT_addCounter = methodType(int.class, int.class, int.class);
+        static final MethodType MT_stateBody = methodType(String.class, int.class, String.class);
+        static final MethodType MT_append = methodType(String.class, int.class, String.class, String.class);
 
         static final MethodHandle MH_13;
         static final MethodHandle MH_m5;
@@ -701,11 +937,15 @@
         static final MethodHandle MH_stepUpdateArray;
         static final MethodHandle MH_printHello;
         static final MethodHandle MH_addCounter;
+        static final MethodHandle MH_stateBody;
+        static final MethodHandle MH_append;
 
         static final MethodType MT_counted = methodType(String.class, String.class);
         static final MethodType MT_arrayCounted = methodType(void.class, int[].class);
         static final MethodType MT_countedPrinting = methodType(void.class);
         static final MethodType MT_counterInit = methodType(int.class);
+        static final MethodType MT_bodyDeterminesState = methodType(String.class);
+        static final MethodType MT_iterationsDefineArgs = methodType(String.class, String.class);
 
         static {
             try {
@@ -717,6 +957,8 @@
                 MH_stepUpdateArray = LOOKUP.findStatic(COUNTED, "stepUpdateArray", MT_stepUpdateArray);
                 MH_printHello = LOOKUP.findStatic(COUNTED, "printHello", MT_printHello);
                 MH_addCounter = LOOKUP.findStatic(COUNTED, "addCounter", MT_addCounter);
+                MH_stateBody = LOOKUP.findStatic(COUNTED, "stateBody", MT_stateBody);
+                MH_append = LOOKUP.findStatic(COUNTED, "append", MT_append);
             } catch (Exception e) {
                 throw new ExceptionInInitializerError(e);
             }
@@ -768,6 +1010,10 @@
             System.out.print(s);
         }
 
+        static void voidInit() {
+            // empty
+        }
+
         static final Class<Iterate> ITERATE = Iterate.class;
 
         static final MethodType MT_sumIterator = methodType(Iterator.class, Integer[].class);
@@ -783,6 +1029,8 @@
         static final MethodType MT_mapStep = methodType(List.class, String.class, List.class, List.class);
         static final MethodType MT_printStep = methodType(void.class, String.class, List.class);
 
+        static final MethodType MT_voidInit = methodType(void.class);
+
         static final MethodHandle MH_sumIterator;
         static final MethodHandle MH_sumInit;
         static final MethodHandle MH_sumStep;
@@ -797,6 +1045,8 @@
         static final MethodHandle MH_mapInit;
         static final MethodHandle MH_mapStep;
 
+        static final MethodHandle MH_voidInit;
+
         static final MethodType MT_sum = methodType(int.class, Integer[].class);
         static final MethodType MT_reverse = methodType(List.class, List.class);
         static final MethodType MT_length = methodType(int.class, List.class);
@@ -815,6 +1065,7 @@
                 MH_mapInit = LOOKUP.findStatic(ITERATE, "mapInit", MT_mapInit);
                 MH_mapStep = LOOKUP.findStatic(ITERATE, "mapStep", MT_mapStep);
                 MH_printStep = LOOKUP.findStatic(ITERATE, "printStep", MT_printStep);
+                MH_voidInit = LOOKUP.findStatic(ITERATE, "voidInit", MT_voidInit);
             } catch (Exception e) {
                 throw new ExceptionInInitializerError(e);
             }
--- a/jdk/test/java/lang/invoke/PermuteArgsTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/PermuteArgsTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -23,6 +23,7 @@
 
 /* @test
  * @summary unit tests for method handles which permute their arguments
+ * @library /lib/testlibrary/jsr292 /lib/testlibrary
  * @run testng/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyDependencies -ea -esa -DPermuteArgsTest.MAX_ARITY=8 test.java.lang.invoke.PermuteArgsTest
  */
 /* Examples of manual runs:
@@ -36,6 +37,8 @@
 import org.testng.*;
 import org.testng.annotations.*;
 
+import com.oracle.testlibrary.jsr292.CodeCacheOverflowProcessor;
+
 import java.util.*;
 import java.lang.reflect.*;
 
@@ -122,9 +125,15 @@
         }
         new PermuteArgsTest().test();
     }
+
     static int testCases;
+
     @Test
     public void test() throws Throwable {
+        CodeCacheOverflowProcessor.runMHTest(this::test0);
+    }
+
+    public void test0() throws Throwable {
         testCases = 0;
         Lookup lookup = lookup();
         for (Method m : lookup.lookupClass().getDeclaredMethods()) {
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleBaseTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleBaseTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -148,6 +148,7 @@
         COMPARE_AND_EXCHANGE_ACQUIRE(TestAccessType.COMPARE_AND_EXCHANGE),
         COMPARE_AND_EXCHANGE_RELEASE(TestAccessType.COMPARE_AND_EXCHANGE),
         WEAK_COMPARE_AND_SET(TestAccessType.COMPARE_AND_SET),
+        WEAK_COMPARE_AND_SET_VOLATILE(TestAccessType.COMPARE_AND_SET),
         WEAK_COMPARE_AND_SET_ACQUIRE(TestAccessType.COMPARE_AND_SET),
         WEAK_COMPARE_AND_SET_RELEASE(TestAccessType.COMPARE_AND_SET),
         GET_AND_SET(TestAccessType.GET_AND_SET),
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java	Thu Apr 28 23:08:16 2016 -0700
@@ -104,9 +104,9 @@
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
-        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
 
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
@@ -281,6 +281,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, true, false);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, true, false);
         });
 
@@ -363,6 +367,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(true, false);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(true, false);
         });
 
@@ -435,6 +443,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, true, false);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, true, false);
         });
 
@@ -507,6 +519,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(true, false);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(true, false);
         });
 
@@ -586,6 +602,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(array, i, true, false);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(array, i, true, false);
         });
 
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java	Thu Apr 28 23:08:16 2016 -0700
@@ -104,9 +104,9 @@
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
-        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
 
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
@@ -281,6 +281,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, (byte)1, (byte)2);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, (byte)1, (byte)2);
         });
 
@@ -363,6 +367,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile((byte)1, (byte)2);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire((byte)1, (byte)2);
         });
 
@@ -435,6 +443,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, (byte)1, (byte)2);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, (byte)1, (byte)2);
         });
 
@@ -507,6 +519,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile((byte)1, (byte)2);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire((byte)1, (byte)2);
         });
 
@@ -586,6 +602,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(array, i, (byte)1, (byte)2);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(array, i, (byte)1, (byte)2);
         });
 
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java	Thu Apr 28 23:08:16 2016 -0700
@@ -104,9 +104,9 @@
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
-        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
 
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
@@ -281,6 +281,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, 'a', 'b');
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, 'a', 'b');
         });
 
@@ -363,6 +367,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile('a', 'b');
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire('a', 'b');
         });
 
@@ -435,6 +443,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, 'a', 'b');
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, 'a', 'b');
         });
 
@@ -507,6 +519,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile('a', 'b');
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire('a', 'b');
         });
 
@@ -586,6 +602,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(array, i, 'a', 'b');
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(array, i, 'a', 'b');
         });
 
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java	Thu Apr 28 23:08:16 2016 -0700
@@ -104,9 +104,9 @@
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
-        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
 
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
@@ -281,6 +281,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, 1.0d, 2.0d);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, 1.0d, 2.0d);
         });
 
@@ -363,6 +367,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(1.0d, 2.0d);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(1.0d, 2.0d);
         });
 
@@ -435,6 +443,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, 1.0d, 2.0d);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, 1.0d, 2.0d);
         });
 
@@ -507,6 +519,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(1.0d, 2.0d);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(1.0d, 2.0d);
         });
 
@@ -586,6 +602,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(array, i, 1.0d, 2.0d);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(array, i, 1.0d, 2.0d);
         });
 
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java	Thu Apr 28 23:08:16 2016 -0700
@@ -104,9 +104,9 @@
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
-        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
 
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
@@ -281,6 +281,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, 1.0f, 2.0f);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, 1.0f, 2.0f);
         });
 
@@ -363,6 +367,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(1.0f, 2.0f);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(1.0f, 2.0f);
         });
 
@@ -435,6 +443,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, 1.0f, 2.0f);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, 1.0f, 2.0f);
         });
 
@@ -507,6 +519,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(1.0f, 2.0f);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(1.0f, 2.0f);
         });
 
@@ -586,6 +602,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(array, i, 1.0f, 2.0f);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(array, i, 1.0f, 2.0f);
         });
 
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java	Thu Apr 28 23:08:16 2016 -0700
@@ -104,9 +104,9 @@
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
-        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
 
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
@@ -422,12 +422,19 @@
             assertEquals(x, 2, "weakCompareAndSetRelease int");
         }
 
+        {
+            boolean r = vh.weakCompareAndSetVolatile(recv, 2, 1);
+            assertEquals(r, true, "weakCompareAndSetVolatile int");
+            int x = (int) vh.get(recv);
+            assertEquals(x, 1, "weakCompareAndSetVolatile int value");
+        }
+
         // Compare set and get
         {
-            int o = (int) vh.getAndSet(recv, 1);
-            assertEquals(o, 2, "getAndSet int");
+            int o = (int) vh.getAndSet(recv, 2);
+            assertEquals(o, 1, "getAndSet int");
             int x = (int) vh.get(recv);
-            assertEquals(x, 1, "getAndSet int value");
+            assertEquals(x, 2, "getAndSet int value");
         }
 
         vh.set(recv, 1);
@@ -550,18 +557,25 @@
         }
 
         {
-            boolean r = (boolean) vh.weakCompareAndSetRelease( 1, 2);
+            boolean r = (boolean) vh.weakCompareAndSetRelease(1, 2);
             assertEquals(r, true, "weakCompareAndSetRelease int");
             int x = (int) vh.get();
             assertEquals(x, 2, "weakCompareAndSetRelease int");
         }
 
+        {
+            boolean r = (boolean) vh.weakCompareAndSetVolatile(2, 1);
+            assertEquals(r, true, "weakCompareAndSetVolatile int");
+            int x = (int) vh.get();
+            assertEquals(x, 1, "weakCompareAndSetVolatile int value");
+        }
+
         // Compare set and get
         {
-            int o = (int) vh.getAndSet( 1);
-            assertEquals(o, 2, "getAndSet int");
+            int o = (int) vh.getAndSet( 2);
+            assertEquals(o, 1, "getAndSet int");
             int x = (int) vh.get();
-            assertEquals(x, 1, "getAndSet int value");
+            assertEquals(x, 2, "getAndSet int value");
         }
 
         vh.set(1);
@@ -693,12 +707,19 @@
                 assertEquals(x, 2, "weakCompareAndSetRelease int");
             }
 
+            {
+                boolean r = vh.weakCompareAndSetVolatile(array, i, 2, 1);
+                assertEquals(r, true, "weakCompareAndSetVolatile int");
+                int x = (int) vh.get(array, i);
+                assertEquals(x, 1, "weakCompareAndSetVolatile int value");
+            }
+
             // Compare set and get
             {
-                int o = (int) vh.getAndSet(array, i, 1);
-                assertEquals(o, 2, "getAndSet int");
+                int o = (int) vh.getAndSet(array, i, 2);
+                assertEquals(o, 1, "getAndSet int");
                 int x = (int) vh.get(array, i);
-                assertEquals(x, 1, "getAndSet int value");
+                assertEquals(x, 2, "getAndSet int value");
             }
 
             vh.set(array, i, 1);
@@ -779,6 +800,10 @@
             });
 
             checkIOOBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, 1, 2);
+            });
+
+            checkIOOBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, 1, 2);
             });
 
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java	Thu Apr 28 23:08:16 2016 -0700
@@ -104,9 +104,9 @@
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
-        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
 
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
@@ -422,12 +422,19 @@
             assertEquals(x, 2L, "weakCompareAndSetRelease long");
         }
 
+        {
+            boolean r = vh.weakCompareAndSetVolatile(recv, 2L, 1L);
+            assertEquals(r, true, "weakCompareAndSetVolatile long");
+            long x = (long) vh.get(recv);
+            assertEquals(x, 1L, "weakCompareAndSetVolatile long value");
+        }
+
         // Compare set and get
         {
-            long o = (long) vh.getAndSet(recv, 1L);
-            assertEquals(o, 2L, "getAndSet long");
+            long o = (long) vh.getAndSet(recv, 2L);
+            assertEquals(o, 1L, "getAndSet long");
             long x = (long) vh.get(recv);
-            assertEquals(x, 1L, "getAndSet long value");
+            assertEquals(x, 2L, "getAndSet long value");
         }
 
         vh.set(recv, 1L);
@@ -550,18 +557,25 @@
         }
 
         {
-            boolean r = (boolean) vh.weakCompareAndSetRelease( 1L, 2L);
+            boolean r = (boolean) vh.weakCompareAndSetRelease(1L, 2L);
             assertEquals(r, true, "weakCompareAndSetRelease long");
             long x = (long) vh.get();
             assertEquals(x, 2L, "weakCompareAndSetRelease long");
         }
 
+        {
+            boolean r = (boolean) vh.weakCompareAndSetVolatile(2L, 1L);
+            assertEquals(r, true, "weakCompareAndSetVolatile long");
+            long x = (long) vh.get();
+            assertEquals(x, 1L, "weakCompareAndSetVolatile long value");
+        }
+
         // Compare set and get
         {
-            long o = (long) vh.getAndSet( 1L);
-            assertEquals(o, 2L, "getAndSet long");
+            long o = (long) vh.getAndSet( 2L);
+            assertEquals(o, 1L, "getAndSet long");
             long x = (long) vh.get();
-            assertEquals(x, 1L, "getAndSet long value");
+            assertEquals(x, 2L, "getAndSet long value");
         }
 
         vh.set(1L);
@@ -693,12 +707,19 @@
                 assertEquals(x, 2L, "weakCompareAndSetRelease long");
             }
 
+            {
+                boolean r = vh.weakCompareAndSetVolatile(array, i, 2L, 1L);
+                assertEquals(r, true, "weakCompareAndSetVolatile long");
+                long x = (long) vh.get(array, i);
+                assertEquals(x, 1L, "weakCompareAndSetVolatile long value");
+            }
+
             // Compare set and get
             {
-                long o = (long) vh.getAndSet(array, i, 1L);
-                assertEquals(o, 2L, "getAndSet long");
+                long o = (long) vh.getAndSet(array, i, 2L);
+                assertEquals(o, 1L, "getAndSet long");
                 long x = (long) vh.get(array, i);
-                assertEquals(x, 1L, "getAndSet long value");
+                assertEquals(x, 2L, "getAndSet long value");
             }
 
             vh.set(array, i, 1L);
@@ -779,6 +800,10 @@
             });
 
             checkIOOBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, 1L, 2L);
+            });
+
+            checkIOOBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, 1L, 2L);
             });
 
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java	Thu Apr 28 23:08:16 2016 -0700
@@ -104,9 +104,9 @@
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
-        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
 
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
@@ -281,6 +281,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, (short)1, (short)2);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, (short)1, (short)2);
         });
 
@@ -363,6 +367,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile((short)1, (short)2);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire((short)1, (short)2);
         });
 
@@ -435,6 +443,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, (short)1, (short)2);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, (short)1, (short)2);
         });
 
@@ -507,6 +519,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile((short)1, (short)2);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire((short)1, (short)2);
         });
 
@@ -586,6 +602,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(array, i, (short)1, (short)2);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(array, i, (short)1, (short)2);
         });
 
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessString.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessString.java	Thu Apr 28 23:08:16 2016 -0700
@@ -104,9 +104,9 @@
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
-        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
 
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
@@ -436,12 +436,19 @@
             assertEquals(x, "bar", "weakCompareAndSetRelease String");
         }
 
+        {
+            boolean r = vh.weakCompareAndSetVolatile(recv, "bar", "foo");
+            assertEquals(r, true, "weakCompareAndSetVolatile String");
+            String x = (String) vh.get(recv);
+            assertEquals(x, "foo", "weakCompareAndSetVolatile String value");
+        }
+
         // Compare set and get
         {
-            String o = (String) vh.getAndSet(recv, "foo");
-            assertEquals(o, "bar", "getAndSet String");
+            String o = (String) vh.getAndSet(recv, "bar");
+            assertEquals(o, "foo", "getAndSet String");
             String x = (String) vh.get(recv);
-            assertEquals(x, "foo", "getAndSet String value");
+            assertEquals(x, "bar", "getAndSet String value");
         }
 
     }
@@ -562,18 +569,25 @@
         }
 
         {
-            boolean r = (boolean) vh.weakCompareAndSetRelease( "foo", "bar");
+            boolean r = (boolean) vh.weakCompareAndSetRelease("foo", "bar");
             assertEquals(r, true, "weakCompareAndSetRelease String");
             String x = (String) vh.get();
             assertEquals(x, "bar", "weakCompareAndSetRelease String");
         }
 
+        {
+            boolean r = (boolean) vh.weakCompareAndSetVolatile("bar", "foo");
+            assertEquals(r, true, "weakCompareAndSetVolatile String");
+            String x = (String) vh.get();
+            assertEquals(x, "foo", "weakCompareAndSetVolatile String value");
+        }
+
         // Compare set and get
         {
-            String o = (String) vh.getAndSet( "foo");
-            assertEquals(o, "bar", "getAndSet String");
+            String o = (String) vh.getAndSet( "bar");
+            assertEquals(o, "foo", "getAndSet String");
             String x = (String) vh.get();
-            assertEquals(x, "foo", "getAndSet String value");
+            assertEquals(x, "bar", "getAndSet String value");
         }
 
     }
@@ -703,12 +717,19 @@
                 assertEquals(x, "bar", "weakCompareAndSetRelease String");
             }
 
+            {
+                boolean r = vh.weakCompareAndSetVolatile(array, i, "bar", "foo");
+                assertEquals(r, true, "weakCompareAndSetVolatile String");
+                String x = (String) vh.get(array, i);
+                assertEquals(x, "foo", "weakCompareAndSetVolatile String value");
+            }
+
             // Compare set and get
             {
-                String o = (String) vh.getAndSet(array, i, "foo");
-                assertEquals(o, "bar", "getAndSet String");
+                String o = (String) vh.getAndSet(array, i, "bar");
+                assertEquals(o, "foo", "getAndSet String");
                 String x = (String) vh.get(array, i);
-                assertEquals(x, "foo", "getAndSet String value");
+                assertEquals(x, "bar", "getAndSet String value");
             }
 
         }
@@ -787,6 +808,10 @@
             });
 
             checkIOOBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, "foo", "bar");
+            });
+
+            checkIOOBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, "foo", "bar");
             });
 
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java	Thu Apr 28 23:08:16 2016 -0700
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @bug 8154556
  * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsChar
  * @run testng/othervm -Diters=20000                         VarHandleTestByteArrayAsChar
  * @run testng/othervm -Diters=20000 -XX:-TieredCompilation  VarHandleTestByteArrayAsChar
@@ -57,15 +58,16 @@
         // Combinations of VarHandle byte[] or ByteBuffer
         vhss = new ArrayList<>();
         for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+
+            ByteOrder bo = endianess == MemoryMode.BIG_ENDIAN
+                    ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
             VarHandleSource aeh = new VarHandleSource(
-                    MethodHandles.byteArrayViewVarHandle(char[].class,
-                                                         endianess == MemoryMode.BIG_ENDIAN),
+                    MethodHandles.byteArrayViewVarHandle(char[].class, bo),
                     endianess, MemoryMode.READ_WRITE);
             vhss.add(aeh);
 
             VarHandleSource bbh = new VarHandleSource(
-                    MethodHandles.byteBufferViewVarHandle(char[].class,
-                                                          endianess == MemoryMode.BIG_ENDIAN),
+                    MethodHandles.byteBufferViewVarHandle(char[].class, bo),
                     endianess, MemoryMode.READ_WRITE);
             vhss.add(bbh);
         }
@@ -91,9 +93,9 @@
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
-        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
 
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
@@ -203,6 +205,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
         });
 
@@ -264,6 +270,10 @@
             });
 
             checkUOE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkUOE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -305,6 +315,10 @@
             });
 
             checkUOE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkUOE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java	Thu Apr 28 23:08:16 2016 -0700
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @bug 8154556
  * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsDouble
  * @run testng/othervm -Diters=20000                         VarHandleTestByteArrayAsDouble
  * @run testng/othervm -Diters=20000 -XX:-TieredCompilation  VarHandleTestByteArrayAsDouble
@@ -57,15 +58,16 @@
         // Combinations of VarHandle byte[] or ByteBuffer
         vhss = new ArrayList<>();
         for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+
+            ByteOrder bo = endianess == MemoryMode.BIG_ENDIAN
+                    ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
             VarHandleSource aeh = new VarHandleSource(
-                    MethodHandles.byteArrayViewVarHandle(double[].class,
-                                                         endianess == MemoryMode.BIG_ENDIAN),
+                    MethodHandles.byteArrayViewVarHandle(double[].class, bo),
                     endianess, MemoryMode.READ_WRITE);
             vhss.add(aeh);
 
             VarHandleSource bbh = new VarHandleSource(
-                    MethodHandles.byteBufferViewVarHandle(double[].class,
-                                                          endianess == MemoryMode.BIG_ENDIAN),
+                    MethodHandles.byteBufferViewVarHandle(double[].class, bo),
                     endianess, MemoryMode.READ_WRITE);
             vhss.add(bbh);
         }
@@ -91,9 +93,9 @@
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
-        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
 
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
@@ -238,6 +240,10 @@
             });
 
             checkROBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkROBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -333,6 +339,10 @@
             });
 
             checkIOOBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkIOOBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -414,6 +424,10 @@
                 });
 
                 checkIOOBE(() -> {
+                    boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                });
+
+                checkIOOBE(() -> {
                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                 });
 
@@ -486,6 +500,10 @@
                 });
 
                 checkISE(() -> {
+                    boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                });
+
+                checkISE(() -> {
                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                 });
 
@@ -561,6 +579,10 @@
                     });
 
                     checkISE(() -> {
+                        boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                    });
+
+                    checkISE(() -> {
                         boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                     });
 
@@ -698,12 +720,19 @@
                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease double");
                 }
 
+                {
+                    boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1);
+                    assertEquals(r, true, "weakCompareAndSetVolatile double");
+                    double x = (double) vh.get(array, i);
+                    assertEquals(x, VALUE_1, "weakCompareAndSetVolatile double value");
+                }
+
                 // Compare set and get
                 {
-                    double o = (double) vh.getAndSet(array, i, VALUE_1);
-                    assertEquals(o, VALUE_2, "getAndSet double");
+                    double o = (double) vh.getAndSet(array, i, VALUE_2);
+                    assertEquals(o, VALUE_1, "getAndSet double");
                     double x = (double) vh.get(array, i);
-                    assertEquals(x, VALUE_1, "getAndSet double value");
+                    assertEquals(x, VALUE_2, "getAndSet double value");
                 }
 
             }
@@ -831,12 +860,19 @@
                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease double");
                 }
 
+                {
+                    boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1);
+                    assertEquals(r, true, "weakCompareAndSetVolatile double");
+                    double x = (double) vh.get(array, i);
+                    assertEquals(x, VALUE_1, "weakCompareAndSetVolatile double value");
+                }
+
                 // Compare set and get
                 {
-                    double o = (double) vh.getAndSet(array, i, VALUE_1);
-                    assertEquals(o, VALUE_2, "getAndSet double");
+                    double o = (double) vh.getAndSet(array, i, VALUE_2);
+                    assertEquals(o, VALUE_1, "getAndSet double");
                     double x = (double) vh.get(array, i);
-                    assertEquals(x, VALUE_1, "getAndSet double value");
+                    assertEquals(x, VALUE_2, "getAndSet double value");
                 }
 
             }
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java	Thu Apr 28 23:08:16 2016 -0700
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @bug 8154556
  * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsFloat
  * @run testng/othervm -Diters=20000                         VarHandleTestByteArrayAsFloat
  * @run testng/othervm -Diters=20000 -XX:-TieredCompilation  VarHandleTestByteArrayAsFloat
@@ -57,15 +58,16 @@
         // Combinations of VarHandle byte[] or ByteBuffer
         vhss = new ArrayList<>();
         for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+
+            ByteOrder bo = endianess == MemoryMode.BIG_ENDIAN
+                    ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
             VarHandleSource aeh = new VarHandleSource(
-                    MethodHandles.byteArrayViewVarHandle(float[].class,
-                                                         endianess == MemoryMode.BIG_ENDIAN),
+                    MethodHandles.byteArrayViewVarHandle(float[].class, bo),
                     endianess, MemoryMode.READ_WRITE);
             vhss.add(aeh);
 
             VarHandleSource bbh = new VarHandleSource(
-                    MethodHandles.byteBufferViewVarHandle(float[].class,
-                                                          endianess == MemoryMode.BIG_ENDIAN),
+                    MethodHandles.byteBufferViewVarHandle(float[].class, bo),
                     endianess, MemoryMode.READ_WRITE);
             vhss.add(bbh);
         }
@@ -91,9 +93,9 @@
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
-        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
 
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
@@ -238,6 +240,10 @@
             });
 
             checkROBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkROBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -333,6 +339,10 @@
             });
 
             checkIOOBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkIOOBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -414,6 +424,10 @@
                 });
 
                 checkIOOBE(() -> {
+                    boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                });
+
+                checkIOOBE(() -> {
                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                 });
 
@@ -486,6 +500,10 @@
                 });
 
                 checkISE(() -> {
+                    boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                });
+
+                checkISE(() -> {
                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                 });
 
@@ -561,6 +579,10 @@
                     });
 
                     checkISE(() -> {
+                        boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                    });
+
+                    checkISE(() -> {
                         boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                     });
 
@@ -698,12 +720,19 @@
                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease float");
                 }
 
+                {
+                    boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1);
+                    assertEquals(r, true, "weakCompareAndSetVolatile float");
+                    float x = (float) vh.get(array, i);
+                    assertEquals(x, VALUE_1, "weakCompareAndSetVolatile float value");
+                }
+
                 // Compare set and get
                 {
-                    float o = (float) vh.getAndSet(array, i, VALUE_1);
-                    assertEquals(o, VALUE_2, "getAndSet float");
+                    float o = (float) vh.getAndSet(array, i, VALUE_2);
+                    assertEquals(o, VALUE_1, "getAndSet float");
                     float x = (float) vh.get(array, i);
-                    assertEquals(x, VALUE_1, "getAndSet float value");
+                    assertEquals(x, VALUE_2, "getAndSet float value");
                 }
 
             }
@@ -831,12 +860,19 @@
                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease float");
                 }
 
+                {
+                    boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1);
+                    assertEquals(r, true, "weakCompareAndSetVolatile float");
+                    float x = (float) vh.get(array, i);
+                    assertEquals(x, VALUE_1, "weakCompareAndSetVolatile float value");
+                }
+
                 // Compare set and get
                 {
-                    float o = (float) vh.getAndSet(array, i, VALUE_1);
-                    assertEquals(o, VALUE_2, "getAndSet float");
+                    float o = (float) vh.getAndSet(array, i, VALUE_2);
+                    assertEquals(o, VALUE_1, "getAndSet float");
                     float x = (float) vh.get(array, i);
-                    assertEquals(x, VALUE_1, "getAndSet float value");
+                    assertEquals(x, VALUE_2, "getAndSet float value");
                 }
 
             }
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java	Thu Apr 28 23:08:16 2016 -0700
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @bug 8154556
  * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsInt
  * @run testng/othervm -Diters=20000                         VarHandleTestByteArrayAsInt
  * @run testng/othervm -Diters=20000 -XX:-TieredCompilation  VarHandleTestByteArrayAsInt
@@ -57,15 +58,16 @@
         // Combinations of VarHandle byte[] or ByteBuffer
         vhss = new ArrayList<>();
         for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+
+            ByteOrder bo = endianess == MemoryMode.BIG_ENDIAN
+                    ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
             VarHandleSource aeh = new VarHandleSource(
-                    MethodHandles.byteArrayViewVarHandle(int[].class,
-                                                         endianess == MemoryMode.BIG_ENDIAN),
+                    MethodHandles.byteArrayViewVarHandle(int[].class, bo),
                     endianess, MemoryMode.READ_WRITE);
             vhss.add(aeh);
 
             VarHandleSource bbh = new VarHandleSource(
-                    MethodHandles.byteBufferViewVarHandle(int[].class,
-                                                          endianess == MemoryMode.BIG_ENDIAN),
+                    MethodHandles.byteBufferViewVarHandle(int[].class, bo),
                     endianess, MemoryMode.READ_WRITE);
             vhss.add(bbh);
         }
@@ -91,9 +93,9 @@
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
-        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
 
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
@@ -231,6 +233,10 @@
             });
 
             checkROBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkROBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -319,6 +325,10 @@
             });
 
             checkIOOBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkIOOBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -407,6 +417,10 @@
                 });
 
                 checkIOOBE(() -> {
+                    boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                });
+
+                checkIOOBE(() -> {
                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                 });
 
@@ -486,6 +500,10 @@
                 });
 
                 checkISE(() -> {
+                    boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                });
+
+                checkISE(() -> {
                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                 });
 
@@ -568,6 +586,10 @@
                     });
 
                     checkISE(() -> {
+                        boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                    });
+
+                    checkISE(() -> {
                         boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                     });
 
@@ -712,12 +734,19 @@
                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease int");
                 }
 
+                {
+                    boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1);
+                    assertEquals(r, true, "weakCompareAndSetVolatile int");
+                    int x = (int) vh.get(array, i);
+                    assertEquals(x, VALUE_1, "weakCompareAndSetVolatile int value");
+                }
+
                 // Compare set and get
                 {
-                    int o = (int) vh.getAndSet(array, i, VALUE_1);
-                    assertEquals(o, VALUE_2, "getAndSet int");
+                    int o = (int) vh.getAndSet(array, i, VALUE_2);
+                    assertEquals(o, VALUE_1, "getAndSet int");
                     int x = (int) vh.get(array, i);
-                    assertEquals(x, VALUE_1, "getAndSet int value");
+                    assertEquals(x, VALUE_2, "getAndSet int value");
                 }
 
                 vh.set(array, i, VALUE_1);
@@ -854,12 +883,19 @@
                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease int");
                 }
 
+                {
+                    boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1);
+                    assertEquals(r, true, "weakCompareAndSetVolatile int");
+                    int x = (int) vh.get(array, i);
+                    assertEquals(x, VALUE_1, "weakCompareAndSetVolatile int value");
+                }
+
                 // Compare set and get
                 {
-                    int o = (int) vh.getAndSet(array, i, VALUE_1);
-                    assertEquals(o, VALUE_2, "getAndSet int");
+                    int o = (int) vh.getAndSet(array, i, VALUE_2);
+                    assertEquals(o, VALUE_1, "getAndSet int");
                     int x = (int) vh.get(array, i);
-                    assertEquals(x, VALUE_1, "getAndSet int value");
+                    assertEquals(x, VALUE_2, "getAndSet int value");
                 }
 
                 vh.set(array, i, VALUE_1);
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java	Thu Apr 28 23:08:16 2016 -0700
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @bug 8154556
  * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsLong
  * @run testng/othervm -Diters=20000                         VarHandleTestByteArrayAsLong
  * @run testng/othervm -Diters=20000 -XX:-TieredCompilation  VarHandleTestByteArrayAsLong
@@ -57,15 +58,16 @@
         // Combinations of VarHandle byte[] or ByteBuffer
         vhss = new ArrayList<>();
         for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+
+            ByteOrder bo = endianess == MemoryMode.BIG_ENDIAN
+                    ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
             VarHandleSource aeh = new VarHandleSource(
-                    MethodHandles.byteArrayViewVarHandle(long[].class,
-                                                         endianess == MemoryMode.BIG_ENDIAN),
+                    MethodHandles.byteArrayViewVarHandle(long[].class, bo),
                     endianess, MemoryMode.READ_WRITE);
             vhss.add(aeh);
 
             VarHandleSource bbh = new VarHandleSource(
-                    MethodHandles.byteBufferViewVarHandle(long[].class,
-                                                          endianess == MemoryMode.BIG_ENDIAN),
+                    MethodHandles.byteBufferViewVarHandle(long[].class, bo),
                     endianess, MemoryMode.READ_WRITE);
             vhss.add(bbh);
         }
@@ -91,9 +93,9 @@
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
-        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
 
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
@@ -231,6 +233,10 @@
             });
 
             checkROBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkROBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -319,6 +325,10 @@
             });
 
             checkIOOBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkIOOBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -407,6 +417,10 @@
                 });
 
                 checkIOOBE(() -> {
+                    boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                });
+
+                checkIOOBE(() -> {
                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                 });
 
@@ -486,6 +500,10 @@
                 });
 
                 checkISE(() -> {
+                    boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                });
+
+                checkISE(() -> {
                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                 });
 
@@ -568,6 +586,10 @@
                     });
 
                     checkISE(() -> {
+                        boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                    });
+
+                    checkISE(() -> {
                         boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                     });
 
@@ -712,12 +734,19 @@
                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease long");
                 }
 
+                {
+                    boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1);
+                    assertEquals(r, true, "weakCompareAndSetVolatile long");
+                    long x = (long) vh.get(array, i);
+                    assertEquals(x, VALUE_1, "weakCompareAndSetVolatile long value");
+                }
+
                 // Compare set and get
                 {
-                    long o = (long) vh.getAndSet(array, i, VALUE_1);
-                    assertEquals(o, VALUE_2, "getAndSet long");
+                    long o = (long) vh.getAndSet(array, i, VALUE_2);
+                    assertEquals(o, VALUE_1, "getAndSet long");
                     long x = (long) vh.get(array, i);
-                    assertEquals(x, VALUE_1, "getAndSet long value");
+                    assertEquals(x, VALUE_2, "getAndSet long value");
                 }
 
                 vh.set(array, i, VALUE_1);
@@ -854,12 +883,19 @@
                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease long");
                 }
 
+                {
+                    boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1);
+                    assertEquals(r, true, "weakCompareAndSetVolatile long");
+                    long x = (long) vh.get(array, i);
+                    assertEquals(x, VALUE_1, "weakCompareAndSetVolatile long value");
+                }
+
                 // Compare set and get
                 {
-                    long o = (long) vh.getAndSet(array, i, VALUE_1);
-                    assertEquals(o, VALUE_2, "getAndSet long");
+                    long o = (long) vh.getAndSet(array, i, VALUE_2);
+                    assertEquals(o, VALUE_1, "getAndSet long");
                     long x = (long) vh.get(array, i);
-                    assertEquals(x, VALUE_1, "getAndSet long value");
+                    assertEquals(x, VALUE_2, "getAndSet long value");
                 }
 
                 vh.set(array, i, VALUE_1);
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java	Thu Apr 28 23:08:16 2016 -0700
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @bug 8154556
  * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsShort
  * @run testng/othervm -Diters=20000                         VarHandleTestByteArrayAsShort
  * @run testng/othervm -Diters=20000 -XX:-TieredCompilation  VarHandleTestByteArrayAsShort
@@ -57,15 +58,16 @@
         // Combinations of VarHandle byte[] or ByteBuffer
         vhss = new ArrayList<>();
         for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+
+            ByteOrder bo = endianess == MemoryMode.BIG_ENDIAN
+                    ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
             VarHandleSource aeh = new VarHandleSource(
-                    MethodHandles.byteArrayViewVarHandle(short[].class,
-                                                         endianess == MemoryMode.BIG_ENDIAN),
+                    MethodHandles.byteArrayViewVarHandle(short[].class, bo),
                     endianess, MemoryMode.READ_WRITE);
             vhss.add(aeh);
 
             VarHandleSource bbh = new VarHandleSource(
-                    MethodHandles.byteBufferViewVarHandle(short[].class,
-                                                          endianess == MemoryMode.BIG_ENDIAN),
+                    MethodHandles.byteBufferViewVarHandle(short[].class, bo),
                     endianess, MemoryMode.READ_WRITE);
             vhss.add(bbh);
         }
@@ -91,9 +93,9 @@
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
-        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
 
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
@@ -203,6 +205,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
         });
 
@@ -264,6 +270,10 @@
             });
 
             checkUOE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkUOE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -305,6 +315,10 @@
             });
 
             checkUOE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkUOE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessInt.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessInt.java	Thu Apr 28 23:08:16 2016 -0700
@@ -228,12 +228,19 @@
             assertEquals(x, 2, "weakCompareAndSetRelease int");
         }
 
+        {
+            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(recv, 2, 1);
+            assertEquals(r, true, "weakCompareAndSetVolatile int");
+            int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 1, "weakCompareAndSetVolatile int value");
+        }
+
         // Compare set and get
         {
-            int o = (int) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, 1);
-            assertEquals(o, 2, "getAndSet int");
+            int o = (int) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, 2);
+            assertEquals(o, 1, "getAndSet int");
             int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv);
-            assertEquals(x, 1, "getAndSet int value");
+            assertEquals(x, 2, "getAndSet int value");
         }
 
         hs.get(TestAccessMode.SET).invokeExact(recv, 1);
@@ -356,18 +363,25 @@
         }
 
         {
-            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact( 1, 2);
+            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(1, 2);
             assertEquals(r, true, "weakCompareAndSetRelease int");
             int x = (int) hs.get(TestAccessMode.GET).invokeExact();
             assertEquals(x, 2, "weakCompareAndSetRelease int");
         }
 
+        {
+            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(2, 1);
+            assertEquals(r, true, "weakCompareAndSetVolatile int");
+            int x = (int) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 1, "weakCompareAndSetVolatile int value");
+        }
+
         // Compare set and get
         {
-            int o = (int) hs.get(TestAccessMode.GET_AND_SET).invokeExact( 1);
-            assertEquals(o, 2, "getAndSet int");
+            int o = (int) hs.get(TestAccessMode.GET_AND_SET).invokeExact(2);
+            assertEquals(o, 1, "getAndSet int");
             int x = (int) hs.get(TestAccessMode.GET).invokeExact();
-            assertEquals(x, 1, "getAndSet int value");
+            assertEquals(x, 2, "getAndSet int value");
         }
 
         hs.get(TestAccessMode.SET).invokeExact(1);
@@ -499,12 +513,19 @@
                 assertEquals(x, 2, "weakCompareAndSetRelease int");
             }
 
+            {
+                boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(array, i, 2, 1);
+                assertEquals(r, true, "weakCompareAndSetVolatile int");
+                int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 1, "weakCompareAndSetVolatile int value");
+            }
+
             // Compare set and get
             {
-                int o = (int) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, 1);
-                assertEquals(o, 2, "getAndSet int");
+                int o = (int) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, 2);
+                assertEquals(o, 1, "getAndSet int");
                 int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i);
-                assertEquals(x, 1, "getAndSet int value");
+                assertEquals(x, 2, "getAndSet int value");
             }
 
             hs.get(TestAccessMode.SET).invokeExact(array, i, 1);
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessLong.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessLong.java	Thu Apr 28 23:08:16 2016 -0700
@@ -228,12 +228,19 @@
             assertEquals(x, 2L, "weakCompareAndSetRelease long");
         }
 
+        {
+            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(recv, 2L, 1L);
+            assertEquals(r, true, "weakCompareAndSetVolatile long");
+            long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, 1L, "weakCompareAndSetVolatile long value");
+        }
+
         // Compare set and get
         {
-            long o = (long) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, 1L);
-            assertEquals(o, 2L, "getAndSet long");
+            long o = (long) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, 2L);
+            assertEquals(o, 1L, "getAndSet long");
             long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv);
-            assertEquals(x, 1L, "getAndSet long value");
+            assertEquals(x, 2L, "getAndSet long value");
         }
 
         hs.get(TestAccessMode.SET).invokeExact(recv, 1L);
@@ -356,18 +363,25 @@
         }
 
         {
-            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact( 1L, 2L);
+            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(1L, 2L);
             assertEquals(r, true, "weakCompareAndSetRelease long");
             long x = (long) hs.get(TestAccessMode.GET).invokeExact();
             assertEquals(x, 2L, "weakCompareAndSetRelease long");
         }
 
+        {
+            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(2L, 1L);
+            assertEquals(r, true, "weakCompareAndSetVolatile long");
+            long x = (long) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, 1L, "weakCompareAndSetVolatile long value");
+        }
+
         // Compare set and get
         {
-            long o = (long) hs.get(TestAccessMode.GET_AND_SET).invokeExact( 1L);
-            assertEquals(o, 2L, "getAndSet long");
+            long o = (long) hs.get(TestAccessMode.GET_AND_SET).invokeExact(2L);
+            assertEquals(o, 1L, "getAndSet long");
             long x = (long) hs.get(TestAccessMode.GET).invokeExact();
-            assertEquals(x, 1L, "getAndSet long value");
+            assertEquals(x, 2L, "getAndSet long value");
         }
 
         hs.get(TestAccessMode.SET).invokeExact(1L);
@@ -499,12 +513,19 @@
                 assertEquals(x, 2L, "weakCompareAndSetRelease long");
             }
 
+            {
+                boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(array, i, 2L, 1L);
+                assertEquals(r, true, "weakCompareAndSetVolatile long");
+                long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, 1L, "weakCompareAndSetVolatile long value");
+            }
+
             // Compare set and get
             {
-                long o = (long) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, 1L);
-                assertEquals(o, 2L, "getAndSet long");
+                long o = (long) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, 2L);
+                assertEquals(o, 1L, "getAndSet long");
                 long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i);
-                assertEquals(x, 1L, "getAndSet long value");
+                assertEquals(x, 2L, "getAndSet long value");
             }
 
             hs.get(TestAccessMode.SET).invokeExact(array, i, 1L);
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessString.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessString.java	Thu Apr 28 23:08:16 2016 -0700
@@ -228,12 +228,19 @@
             assertEquals(x, "bar", "weakCompareAndSetRelease String");
         }
 
+        {
+            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(recv, "bar", "foo");
+            assertEquals(r, true, "weakCompareAndSetVolatile String");
+            String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, "foo", "weakCompareAndSetVolatile String value");
+        }
+
         // Compare set and get
         {
-            String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, "foo");
-            assertEquals(o, "bar", "getAndSet String");
+            String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, "bar");
+            assertEquals(o, "foo", "getAndSet String");
             String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv);
-            assertEquals(x, "foo", "getAndSet String value");
+            assertEquals(x, "bar", "getAndSet String value");
         }
 
     }
@@ -352,18 +359,25 @@
         }
 
         {
-            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact( "foo", "bar");
+            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact("foo", "bar");
             assertEquals(r, true, "weakCompareAndSetRelease String");
             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
             assertEquals(x, "bar", "weakCompareAndSetRelease String");
         }
 
+        {
+            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact("bar", "foo");
+            assertEquals(r, true, "weakCompareAndSetVolatile String");
+            String x = (String) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, "foo", "weakCompareAndSetVolatile String value");
+        }
+
         // Compare set and get
         {
-            String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact( "foo");
-            assertEquals(o, "bar", "getAndSet String");
+            String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact("bar");
+            assertEquals(o, "foo", "getAndSet String");
             String x = (String) hs.get(TestAccessMode.GET).invokeExact();
-            assertEquals(x, "foo", "getAndSet String value");
+            assertEquals(x, "bar", "getAndSet String value");
         }
 
     }
@@ -491,12 +505,19 @@
                 assertEquals(x, "bar", "weakCompareAndSetRelease String");
             }
 
+            {
+                boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(array, i, "bar", "foo");
+                assertEquals(r, true, "weakCompareAndSetVolatile String");
+                String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, "foo", "weakCompareAndSetVolatile String value");
+            }
+
             // Compare set and get
             {
-                String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, "foo");
-                assertEquals(o, "bar", "getAndSet String");
+                String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, "bar");
+                assertEquals(o, "foo", "getAndSet String");
                 String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i);
-                assertEquals(x, "foo", "getAndSet String value");
+                assertEquals(x, "bar", "getAndSet String value");
             }
 
         }
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeInt.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeInt.java	Thu Apr 28 23:08:16 2016 -0700
@@ -374,6 +374,32 @@
         });
 
 
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetVolatile(null, 1, 1);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, 1, 1);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(recv, Void.class, 1);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile(recv, 1, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetVolatile(0, 1, 1);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile(recv, 1, 1, Void.class);
+        });
+
+
         // WeakCompareAndSetAcquire
         // Incorrect argument types
         checkNPE(() -> { // null receiver
@@ -972,6 +998,23 @@
         });
 
 
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, 1);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile(1, Void.class);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile(1, 1, Void.class);
+        });
+
+
         // WeakCompareAndSetAcquire
         // Incorrect argument types
         checkWMTE(() -> { // expected reference class
@@ -1566,6 +1609,35 @@
         });
 
 
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetVolatile(null, 0, 1, 1);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, 0, 1, 1);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, Void.class, 1);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, 1, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetVolatile(0, 0, 1, 1);
+        });
+        checkWMTE(() -> { // index reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, Void.class, 1, 1);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, 1, 1, Void.class);
+        });
+
+
         // WeakCompareAndSetAcquire
         // Incorrect argument types
         checkNPE(() -> { // null receiver
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeLong.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeLong.java	Thu Apr 28 23:08:16 2016 -0700
@@ -374,6 +374,32 @@
         });
 
 
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetVolatile(null, 1L, 1L);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, 1L, 1L);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(recv, Void.class, 1L);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile(recv, 1L, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetVolatile(0, 1L, 1L);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile(recv, 1L, 1L, Void.class);
+        });
+
+
         // WeakCompareAndSetAcquire
         // Incorrect argument types
         checkNPE(() -> { // null receiver
@@ -972,6 +998,23 @@
         });
 
 
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, 1L);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile(1L, Void.class);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile(1L, 1L, Void.class);
+        });
+
+
         // WeakCompareAndSetAcquire
         // Incorrect argument types
         checkWMTE(() -> { // expected reference class
@@ -1566,6 +1609,35 @@
         });
 
 
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetVolatile(null, 0, 1L, 1L);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, 0, 1L, 1L);
+        });
+        checkWMTE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, Void.class, 1L);
+        });
+        checkWMTE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, 1L, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetVolatile(0, 0, 1L, 1L);
+        });
+        checkWMTE(() -> { // index reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, Void.class, 1L, 1L);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, 1L, 1L, Void.class);
+        });
+
+
         // WeakCompareAndSetAcquire
         // Incorrect argument types
         checkNPE(() -> { // null receiver
--- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeString.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeString.java	Thu Apr 28 23:08:16 2016 -0700
@@ -374,6 +374,32 @@
         });
 
 
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetVolatile(null, "foo", "foo");
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, "foo", "foo");
+        });
+        checkCCE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(recv, Void.class, "foo");
+        });
+        checkCCE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile(recv, "foo", Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetVolatile(0, "foo", "foo");
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile(recv, "foo", "foo", Void.class);
+        });
+
+
         // WeakCompareAndSetAcquire
         // Incorrect argument types
         checkNPE(() -> { // null receiver
@@ -878,6 +904,23 @@
         });
 
 
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkCCE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, "foo");
+        });
+        checkCCE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile("foo", Void.class);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile("foo", "foo", Void.class);
+        });
+
+
         // WeakCompareAndSetAcquire
         // Incorrect argument types
         checkCCE(() -> { // expected reference class
@@ -1407,6 +1450,35 @@
         });
 
 
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetVolatile(null, 0, "foo", "foo");
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, 0, "foo", "foo");
+        });
+        checkCCE(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, Void.class, "foo");
+        });
+        checkCCE(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, "foo", Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetVolatile(0, 0, "foo", "foo");
+        });
+        checkWMTE(() -> { // index reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, Void.class, "foo", "foo");
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, "foo", "foo", Void.class);
+        });
+
+
         // WeakCompareAndSetAcquire
         // Incorrect argument types
         checkNPE(() -> { // null receiver
--- a/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template	Thu Apr 28 23:08:16 2016 -0700
@@ -105,6 +105,7 @@
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
@@ -114,6 +115,7 @@
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
@@ -297,6 +299,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, $value1$, $value2$);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, $value1$, $value2$);
         });
 
@@ -383,6 +389,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile($value1$, $value2$);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire($value1$, $value2$);
         });
 
@@ -514,12 +524,19 @@
             assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
         }
 
+        {
+            boolean r = vh.weakCompareAndSetVolatile(recv, $value2$, $value1$);
+            assertEquals(r, true, "weakCompareAndSetVolatile $type$");
+            $type$ x = ($type$) vh.get(recv);
+            assertEquals(x, $value1$, "weakCompareAndSetVolatile $type$ value");
+        }
+
         // Compare set and get
         {
-            $type$ o = ($type$) vh.getAndSet(recv, $value1$);
-            assertEquals(o, $value2$, "getAndSet $type$");
+            $type$ o = ($type$) vh.getAndSet(recv, $value2$);
+            assertEquals(o, $value1$, "getAndSet $type$");
             $type$ x = ($type$) vh.get(recv);
-            assertEquals(x, $value1$, "getAndSet $type$ value");
+            assertEquals(x, $value2$, "getAndSet $type$ value");
         }
 #end[CAS]
 
@@ -559,6 +576,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(recv, $value1$, $value2$);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(recv, $value1$, $value2$);
         });
 
@@ -684,18 +705,25 @@
         }
 
         {
-            boolean r = (boolean) vh.weakCompareAndSetRelease( $value1$, $value2$);
+            boolean r = (boolean) vh.weakCompareAndSetRelease($value1$, $value2$);
             assertEquals(r, true, "weakCompareAndSetRelease $type$");
             $type$ x = ($type$) vh.get();
             assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
         }
 
+        {
+            boolean r = (boolean) vh.weakCompareAndSetVolatile($value2$, $value1$);
+            assertEquals(r, true, "weakCompareAndSetVolatile $type$");
+            $type$ x = ($type$) vh.get();
+            assertEquals(x, $value1$, "weakCompareAndSetVolatile $type$ value");
+        }
+
         // Compare set and get
         {
-            $type$ o = ($type$) vh.getAndSet( $value1$);
-            assertEquals(o, $value2$, "getAndSet $type$");
+            $type$ o = ($type$) vh.getAndSet( $value2$);
+            assertEquals(o, $value1$, "getAndSet $type$");
             $type$ x = ($type$) vh.get();
-            assertEquals(x, $value1$, "getAndSet $type$ value");
+            assertEquals(x, $value2$, "getAndSet $type$ value");
         }
 #end[CAS]
 
@@ -735,6 +763,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile($value1$, $value2$);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire($value1$, $value2$);
         });
 
@@ -869,12 +901,19 @@
                 assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
             }
 
+            {
+                boolean r = vh.weakCompareAndSetVolatile(array, i, $value2$, $value1$);
+                assertEquals(r, true, "weakCompareAndSetVolatile $type$");
+                $type$ x = ($type$) vh.get(array, i);
+                assertEquals(x, $value1$, "weakCompareAndSetVolatile $type$ value");
+            }
+
             // Compare set and get
             {
-                $type$ o = ($type$) vh.getAndSet(array, i, $value1$);
-                assertEquals(o, $value2$, "getAndSet $type$");
+                $type$ o = ($type$) vh.getAndSet(array, i, $value2$);
+                assertEquals(o, $value1$, "getAndSet $type$");
                 $type$ x = ($type$) vh.get(array, i);
-                assertEquals(x, $value1$, "getAndSet $type$ value");
+                assertEquals(x, $value2$, "getAndSet $type$ value");
             }
 #end[CAS]
 
@@ -918,6 +957,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(array, i, $value1$, $value2$);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(array, i, $value1$, $value2$);
         });
 
@@ -997,6 +1040,10 @@
             });
 
             checkIOOBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, $value1$, $value2$);
+            });
+
+            checkIOOBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, $value1$, $value2$);
             });
 
--- a/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template	Thu Apr 28 23:08:16 2016 -0700
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @bug 8154556
  * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAs$Type$
  * @run testng/othervm -Diters=20000                         VarHandleTestByteArrayAs$Type$
  * @run testng/othervm -Diters=20000 -XX:-TieredCompilation  VarHandleTestByteArrayAs$Type$
@@ -57,15 +58,16 @@
         // Combinations of VarHandle byte[] or ByteBuffer
         vhss = new ArrayList<>();
         for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+
+            ByteOrder bo = endianess == MemoryMode.BIG_ENDIAN
+                    ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
             VarHandleSource aeh = new VarHandleSource(
-                    MethodHandles.byteArrayViewVarHandle($type$[].class,
-                                                         endianess == MemoryMode.BIG_ENDIAN),
+                    MethodHandles.byteArrayViewVarHandle($type$[].class, bo),
                     endianess, MemoryMode.READ_WRITE);
             vhss.add(aeh);
 
             VarHandleSource bbh = new VarHandleSource(
-                    MethodHandles.byteBufferViewVarHandle($type$[].class,
-                                                          endianess == MemoryMode.BIG_ENDIAN),
+                    MethodHandles.byteBufferViewVarHandle($type$[].class, bo),
                     endianess, MemoryMode.READ_WRITE);
             vhss.add(bbh);
         }
@@ -92,6 +94,7 @@
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
@@ -101,6 +104,7 @@
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
+        assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_VOLATILE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
         assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
@@ -219,6 +223,10 @@
         });
 
         checkUOE(() -> {
+            boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+        });
+
+        checkUOE(() -> {
             boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
         });
 
@@ -289,6 +297,10 @@
             });
 
             checkROBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkROBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -320,6 +332,10 @@
             });
 
             checkUOE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkUOE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -373,6 +389,10 @@
             });
 
             checkUOE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkUOE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -459,6 +479,10 @@
             });
 
             checkIOOBE(() -> {
+                boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+            });
+
+            checkIOOBE(() -> {
                 boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
             });
 
@@ -551,6 +575,10 @@
                 });
 
                 checkIOOBE(() -> {
+                    boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                });
+
+                checkIOOBE(() -> {
                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                 });
 
@@ -634,6 +662,10 @@
                 });
 
                 checkISE(() -> {
+                    boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                });
+
+                checkISE(() -> {
                     boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                 });
 
@@ -720,6 +752,10 @@
                     });
 
                     checkISE(() -> {
+                        boolean r = vh.weakCompareAndSetVolatile(array, ci, VALUE_1, VALUE_2);
+                    });
+
+                    checkISE(() -> {
                         boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
                     });
 
@@ -868,12 +904,19 @@
                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$");
                 }
 
+                {
+                    boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1);
+                    assertEquals(r, true, "weakCompareAndSetVolatile $type$");
+                    $type$ x = ($type$) vh.get(array, i);
+                    assertEquals(x, VALUE_1, "weakCompareAndSetVolatile $type$ value");
+                }
+
                 // Compare set and get
                 {
-                    $type$ o = ($type$) vh.getAndSet(array, i, VALUE_1);
-                    assertEquals(o, VALUE_2, "getAndSet $type$");
+                    $type$ o = ($type$) vh.getAndSet(array, i, VALUE_2);
+                    assertEquals(o, VALUE_1, "getAndSet $type$");
                     $type$ x = ($type$) vh.get(array, i);
-                    assertEquals(x, VALUE_1, "getAndSet $type$ value");
+                    assertEquals(x, VALUE_2, "getAndSet $type$ value");
                 }
 #end[CAS]
 
@@ -1014,12 +1057,19 @@
                     assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$");
                 }
 
+                {
+                    boolean r = vh.weakCompareAndSetVolatile(array, i, VALUE_2, VALUE_1);
+                    assertEquals(r, true, "weakCompareAndSetVolatile $type$");
+                    $type$ x = ($type$) vh.get(array, i);
+                    assertEquals(x, VALUE_1, "weakCompareAndSetVolatile $type$ value");
+                }
+
                 // Compare set and get
                 {
-                    $type$ o = ($type$) vh.getAndSet(array, i, VALUE_1);
-                    assertEquals(o, VALUE_2, "getAndSet $type$");
+                    $type$ o = ($type$) vh.getAndSet(array, i, VALUE_2);
+                    assertEquals(o, VALUE_1, "getAndSet $type$");
                     $type$ x = ($type$) vh.get(array, i);
-                    assertEquals(x, VALUE_1, "getAndSet $type$ value");
+                    assertEquals(x, VALUE_2, "getAndSet $type$ value");
                 }
 #end[CAS]
 
--- a/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestMethodHandleAccess.java.template	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestMethodHandleAccess.java.template	Thu Apr 28 23:08:16 2016 -0700
@@ -229,12 +229,19 @@
             assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
         }
 
+        {
+            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(recv, $value2$, $value1$);
+            assertEquals(r, true, "weakCompareAndSetVolatile $type$");
+            $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
+            assertEquals(x, $value1$, "weakCompareAndSetVolatile $type$ value");
+        }
+
         // Compare set and get
         {
-            $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, $value1$);
-            assertEquals(o, $value2$, "getAndSet $type$");
+            $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET).invokeExact(recv, $value2$);
+            assertEquals(o, $value1$, "getAndSet $type$");
             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv);
-            assertEquals(x, $value1$, "getAndSet $type$ value");
+            assertEquals(x, $value2$, "getAndSet $type$ value");
         }
 #end[CAS]
 
@@ -387,18 +394,25 @@
         }
 
         {
-            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact( $value1$, $value2$);
+            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact($value1$, $value2$);
             assertEquals(r, true, "weakCompareAndSetRelease $type$");
             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
             assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
         }
 
+        {
+            boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact($value2$, $value1$);
+            assertEquals(r, true, "weakCompareAndSetVolatile $type$");
+            $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
+            assertEquals(x, $value1$, "weakCompareAndSetVolatile $type$ value");
+        }
+
         // Compare set and get
         {
-            $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET).invokeExact( $value1$);
-            assertEquals(o, $value2$, "getAndSet $type$");
+            $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET).invokeExact($value2$);
+            assertEquals(o, $value1$, "getAndSet $type$");
             $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact();
-            assertEquals(x, $value1$, "getAndSet $type$ value");
+            assertEquals(x, $value2$, "getAndSet $type$ value");
         }
 #end[CAS]
 
@@ -560,12 +574,19 @@
                 assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
             }
 
+            {
+                boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(array, i, $value2$, $value1$);
+                assertEquals(r, true, "weakCompareAndSetVolatile $type$");
+                $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
+                assertEquals(x, $value1$, "weakCompareAndSetVolatile $type$ value");
+            }
+
             // Compare set and get
             {
-                $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, $value1$);
-                assertEquals(o, $value2$, "getAndSet $type$");
+                $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET).invokeExact(array, i, $value2$);
+                assertEquals(o, $value1$, "getAndSet $type$");
                 $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i);
-                assertEquals(x, $value1$, "getAndSet $type$ value");
+                assertEquals(x, $value2$, "getAndSet $type$ value");
             }
 #end[CAS]
 
--- a/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestMethodType.java.template	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestMethodType.java.template	Thu Apr 28 23:08:16 2016 -0700
@@ -375,6 +375,32 @@
         });
 
 
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetVolatile(null, $value1$, $value1$);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, $value1$, $value1$);
+        });
+        check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(recv, Void.class, $value1$);
+        });
+        check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile(recv, $value1$, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetVolatile(0, $value1$, $value1$);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile(recv, $value1$, $value1$, Void.class);
+        });
+
+
         // WeakCompareAndSetAcquire
         // Incorrect argument types
         checkNPE(() -> { // null receiver
@@ -981,6 +1007,23 @@
         });
 
 
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, $value1$);
+        });
+        check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile($value1$, Void.class);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile($value1$, $value1$, Void.class);
+        });
+
+
         // WeakCompareAndSetAcquire
         // Incorrect argument types
         check{#if[String]?CCE:WMTE}(() -> { // expected reference class
@@ -1583,6 +1626,35 @@
         });
 
 
+        // WeakCompareAndSetVolatile
+        // Incorrect argument types
+        checkNPE(() -> { // null receiver
+            boolean r = vh.weakCompareAndSetVolatile(null, 0, $value1$, $value1$);
+        });
+        checkCCE(() -> { // receiver reference class
+            boolean r = vh.weakCompareAndSetVolatile(Void.class, 0, $value1$, $value1$);
+        });
+        check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, Void.class, $value1$);
+        });
+        check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, $value1$, Void.class);
+        });
+        checkWMTE(() -> { // receiver primitive class
+            boolean r = vh.weakCompareAndSetVolatile(0, 0, $value1$, $value1$);
+        });
+        checkWMTE(() -> { // index reference class
+            boolean r = vh.weakCompareAndSetVolatile(array, Void.class, $value1$, $value1$);
+        });
+        // Incorrect arity
+        checkWMTE(() -> { // 0
+            boolean r = vh.weakCompareAndSetVolatile();
+        });
+        checkWMTE(() -> { // >
+            boolean r = vh.weakCompareAndSetVolatile(array, 0, $value1$, $value1$, Void.class);
+        });
+
+
         // WeakCompareAndSetAcquire
         // Incorrect argument types
         checkNPE(() -> { // null receiver
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/java.base/java/util/concurrent/LookupTester.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016, 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 java.util.concurrent;
+
+import java.lang.invoke.MethodHandles;
+
+public class LookupTester {
+    public static MethodHandles.Lookup getLookup() {
+        return MethodHandles.lookup();
+    }
+
+
+    public static MethodHandles.Lookup getLookupIn() {
+        return MethodHandles.lookup().in(ConcurrentHashMap.class);
+    }
+}
--- a/jdk/test/java/net/NetworkInterface/NetworkInterfaceStreamTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/net/NetworkInterface/NetworkInterfaceStreamTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -28,7 +28,6 @@
  * @build java.base/java.util.stream.OpTestCase
  * @run testng/othervm NetworkInterfaceStreamTest
  * @run testng/othervm -Djava.net.preferIPv4Stack=true NetworkInterfaceStreamTest
- * @key intermittent
  */
 
 import org.testng.annotations.Test;
@@ -52,21 +51,27 @@
     public void testNetworkInterfaces() throws SocketException {
         Supplier<Stream<NetworkInterface>> ss = () -> {
             try {
-                return NetworkInterface.networkInterfaces();
+                return NetworkInterface.networkInterfaces()
+                        .filter(ni -> isIncluded(ni));
             }
             catch (SocketException e) {
                 throw new RuntimeException(e);
             }
         };
 
-        Collection<NetworkInterface> expected = Collections.list(NetworkInterface.getNetworkInterfaces());
+        Collection<NetworkInterface> enums = Collections.list(NetworkInterface.getNetworkInterfaces());
+        Collection<NetworkInterface> expected = new ArrayList<>();
+        enums.forEach(ni -> {
+            if (isIncluded(ni)) {
+                expected.add(ni);
+            }
+        });
         withData(TestData.Factory.ofSupplier("Top-level network interfaces", ss))
                 .stream(s -> s)
                 .expectedResult(expected)
                 .exercise();
     }
 
-
     private Collection<NetworkInterface> getAllNetworkInterfaces() throws SocketException {
         Collection<NetworkInterface> anis = new ArrayList<>();
         for (NetworkInterface ni : Collections.list(NetworkInterface.getNetworkInterfaces())) {
--- a/jdk/test/java/net/SocketOption/OptionsTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/net/SocketOption/OptionsTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -23,11 +23,13 @@
 
 /*
  * @test
- * @bug 8036979 8072384
+ * @bug 8036979 8072384 8044773
  * @run main/othervm -Xcheck:jni OptionsTest
  * @run main/othervm -Xcheck:jni -Djava.net.preferIPv4Stack=true OptionsTest
+ * @run main/othervm -Djdk.launcher.limitmods=java.base OptionsTest
  */
 
+import java.lang.reflect.Method;
 import java.net.*;
 import java.util.*;
 
@@ -43,7 +45,7 @@
         }
         Object option;
         Object testValue;
-    };
+    }
 
     // The tests set the option using the new API, read back the set value
     // which could be diferent, and then use the legacy get API to check
@@ -223,8 +225,7 @@
             } else if (option.equals(StandardSocketOptions.SO_REUSEPORT) && reuseport) {
                 return Boolean.valueOf(socket.getOption(StandardSocketOptions.SO_REUSEPORT));
             } else if (option.equals(StandardSocketOptions.IP_TOS)) {
-                return Integer.valueOf(jdk.net.Sockets.getOption(
-                    socket, StandardSocketOptions.IP_TOS));
+                return getServerSocketTrafficClass(socket);
             } else {
                 throw new RuntimeException("unexecpted socket option");
             }
@@ -281,4 +282,20 @@
         doDgSocketTests();
         doMcSocketTests();
     }
+
+    // Reflectively access jdk.net.Sockets.getOption so that the test can run
+    // without the jdk.net module.
+    static Object getServerSocketTrafficClass(ServerSocket ss) throws Exception {
+        try {
+            Class<?> c = Class.forName("jdk.net.Sockets");
+            Method m = c.getDeclaredMethod("getOption", ServerSocket.class, SocketOption.class);
+            return m.invoke(null, ss, StandardSocketOptions.IP_TOS);
+        } catch (ClassNotFoundException e) {
+            // Ok, jdk.net module not present, just fall back
+            System.out.println("jdk.net module not present, falling back.");
+            return Integer.valueOf(ss.getOption(StandardSocketOptions.IP_TOS));
+        } catch (ReflectiveOperationException e) {
+            throw new AssertionError(e);
+        }
+    }
 }
--- a/jdk/test/java/net/SocketOption/UnsupportedOptionsTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/net/SocketOption/UnsupportedOptionsTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -21,34 +21,48 @@
  * questions.
  */
 
-import jdk.net.ExtendedSocketOptions;
-
 import java.io.IOException;
+import java.lang.reflect.Field;
 import java.net.*;
+import java.util.ArrayList;
+import java.util.List;
 
 /*
  * @test
- * @bug 8143554
- * @run main UnsupportedOptionsTest
+ * @bug 8143554 8044773
  * @summary Test checks that UnsupportedOperationException for unsupported
  * SOCKET_OPTIONS is thrown by both getOption() and setOption() methods.
+ * @run main UnsupportedOptionsTest
+ * @run main/othervm -Djdk.launcher.limitmods=java.base UnsupportedOptionsTest
  */
+
 public class UnsupportedOptionsTest {
 
-    private static final SocketOption[] SOCKET_OPTIONS = {
-            StandardSocketOptions.IP_MULTICAST_IF,
-            StandardSocketOptions.IP_MULTICAST_LOOP,
-            StandardSocketOptions.IP_MULTICAST_TTL,
-            StandardSocketOptions.IP_TOS,
-            StandardSocketOptions.SO_BROADCAST,
-            StandardSocketOptions.SO_KEEPALIVE,
-            StandardSocketOptions.SO_LINGER,
-            StandardSocketOptions.SO_RCVBUF,
-            StandardSocketOptions.SO_REUSEADDR,
-            StandardSocketOptions.SO_SNDBUF,
-            StandardSocketOptions.TCP_NODELAY,
-            ExtendedSocketOptions.SO_FLOW_SLA
-    };
+    private static final List<SocketOption<?>> socketOptions = new ArrayList<>();
+
+    static {
+        socketOptions.add(StandardSocketOptions.IP_MULTICAST_IF);
+        socketOptions.add(StandardSocketOptions.IP_MULTICAST_LOOP);
+        socketOptions.add(StandardSocketOptions.IP_MULTICAST_TTL);
+        socketOptions.add(StandardSocketOptions.IP_TOS);
+        socketOptions.add(StandardSocketOptions.SO_BROADCAST);
+        socketOptions.add(StandardSocketOptions.SO_KEEPALIVE);
+        socketOptions.add(StandardSocketOptions.SO_LINGER);
+        socketOptions.add(StandardSocketOptions.SO_RCVBUF);
+        socketOptions.add(StandardSocketOptions.SO_REUSEADDR);
+        socketOptions.add(StandardSocketOptions.SO_SNDBUF);
+        socketOptions.add(StandardSocketOptions.TCP_NODELAY);
+
+        try {
+            Class<?> c = Class.forName("jdk.net.ExtendedSocketOptions");
+            Field field = c.getField("SO_FLOW_SLA");
+            socketOptions.add((SocketOption<?>)field.get(null));
+        } catch (ClassNotFoundException e) {
+            // ignore, jdk.net module not present
+        } catch (ReflectiveOperationException e) {
+            throw new AssertionError(e);
+        }
+    }
 
     public static void main(String[] args) throws IOException {
         Socket s = new Socket();
@@ -56,7 +70,7 @@
         DatagramSocket ds = new DatagramSocket();
         MulticastSocket ms = new MulticastSocket();
 
-        for (SocketOption option : SOCKET_OPTIONS) {
+        for (SocketOption option : socketOptions) {
             if (!s.supportedOptions().contains(option)) {
                 testUnsupportedSocketOption(s, option);
             }
--- a/jdk/test/java/net/httpclient/APIErrors.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/net/httpclient/APIErrors.java	Thu Apr 28 23:08:16 2016 -0700
@@ -26,6 +26,7 @@
  * @bug 8087112
  * @library /lib/testlibrary/
  * @build jdk.testlibrary.SimpleSSLContext ProxyServer
+ * @build TestKit
  * @compile ../../../com/sun/net/httpserver/LogFilter.java
  * @compile ../../../com/sun/net/httpserver/FileServerHandler.java
  * @run main/othervm APIErrors
@@ -73,26 +74,6 @@
         }
     }
 
-    static void reject(Runnable r, Class<? extends Exception> extype) {
-        try {
-            r.run();
-            throw new RuntimeException("Expected: " + extype);
-        } catch (Throwable t) {
-            if (!extype.isAssignableFrom(t.getClass())) {
-                throw new RuntimeException("Wrong exception type: " + extype + " / "
-                    +t.getClass());
-            }
-        }
-    }
-
-    static void accept(Runnable r) {
-        try {
-            r.run();
-        } catch (Throwable t) {
-            throw new RuntimeException("Unexpected exception: " + t);
-        }
-    }
-
     static void checkNonNull(Supplier<?> r) {
         if (r.get() == null)
             throw new RuntimeException("Unexpected null return:");
@@ -108,12 +89,14 @@
         System.out.println("Test 1");
         HttpClient.Builder cb = HttpClient.create();
         InetSocketAddress addr = new InetSocketAddress("127.0.0.1", 5000);
-        reject(() -> { cb.priority(-1);}, IllegalArgumentException.class);
-        reject(() -> { cb.priority(500);}, IllegalArgumentException.class);
-        accept(() -> { cb.priority(1);});
-        accept(() -> { cb.priority(255);});
-
-        accept(() -> {clients.add(cb.build()); clients.add(cb.build());});
+        TestKit.assertThrows(IllegalArgumentException.class, () -> cb.priority(-1));
+        TestKit.assertThrows(IllegalArgumentException.class, () -> cb.priority(500));
+        TestKit.assertNotThrows(() -> cb.priority(1));
+        TestKit.assertNotThrows(() -> cb.priority(255));
+        TestKit.assertNotThrows(() -> {
+            clients.add(cb.build());
+            clients.add(cb.build());
+        });
     }
 
     static void test2() throws Exception {
@@ -139,7 +122,7 @@
 
     static void test3() throws Exception {
         System.out.println("Test 3");
-        reject(()-> {
+        TestKit.assertThrows(IllegalStateException.class, ()-> {
             try {
                 HttpRequest r1 = request();
                 HttpResponse resp = r1.response();
@@ -147,9 +130,9 @@
             } catch (IOException |InterruptedException e) {
                 throw new RuntimeException(e);
             }
-        }, IllegalStateException.class);
+        });
 
-        reject(()-> {
+        TestKit.assertThrows(IllegalStateException.class, ()-> {
             try {
                 HttpRequest r1 = request();
                 HttpResponse resp = r1.response();
@@ -157,8 +140,8 @@
             } catch (IOException |InterruptedException | ExecutionException e) {
                 throw new RuntimeException(e);
             }
-        }, IllegalStateException.class);
-        reject(()-> {
+        });
+        TestKit.assertThrows(IllegalStateException.class, ()-> {
             try {
                 HttpRequest r1 = request();
                 HttpResponse resp1 = r1.responseAsync().get();
@@ -166,7 +149,7 @@
             } catch (IOException |InterruptedException | ExecutionException e) {
                 throw new RuntimeException(e);
             }
-        }, IllegalStateException.class);
+        });
     }
 
     static class Auth extends java.net.Authenticator {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/EchoHandler.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.sun.net.httpserver.*;
+import java.net.*;
+import java.net.http.*;
+import java.io.*;
+import java.util.concurrent.*;
+import javax.net.ssl.*;
+import java.nio.file.*;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+import jdk.testlibrary.SimpleSSLContext;
+import static java.net.http.HttpRequest.*;
+import static java.net.http.HttpResponse.*;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class EchoHandler implements HttpHandler {
+    public EchoHandler() {}
+
+    @Override
+    public void handle(HttpExchange t)
+            throws IOException {
+        try {
+            System.err.println("EchoHandler received request to " + t.getRequestURI());
+            InputStream is = t.getRequestBody();
+            Headers map = t.getRequestHeaders();
+            Headers map1 = t.getResponseHeaders();
+            map1.add("X-Hello", "world");
+            map1.add("X-Bye", "universe");
+            String fixedrequest = map.getFirst("XFixed");
+            File outfile = File.createTempFile("foo", "bar");
+            FileOutputStream fos = new FileOutputStream(outfile);
+            int count = (int) is.transferTo(fos);
+            is.close();
+            fos.close();
+            InputStream is1 = new FileInputStream(outfile);
+            OutputStream os = null;
+            // return the number of bytes received (no echo)
+            String summary = map.getFirst("XSummary");
+            if (fixedrequest != null && summary == null) {
+                t.sendResponseHeaders(200, count);
+                os = t.getResponseBody();
+                is1.transferTo(os);
+            } else {
+                t.sendResponseHeaders(200, 0);
+                os = t.getResponseBody();
+                is1.transferTo(os);
+
+                if (summary != null) {
+                    String s = Integer.toString(count);
+                    os.write(s.getBytes());
+                }
+            }
+            outfile.delete();
+            os.close();
+            is1.close();
+        } catch (Throwable e) {
+            e.printStackTrace();
+            throw new IOException(e);
+        }
+    }
+}
--- a/jdk/test/java/net/httpclient/LightWeightHttpServer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/net/httpclient/LightWeightHttpServer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -22,10 +22,10 @@
  */
 
 /**
- * @library /lib/testlibrary/
- * @build jdk.testlibrary.SimpleSSLContext ProxyServer
- * @compile ../../../com/sun/net/httpserver/LogFilter.java
- * @compile ../../../com/sun/net/httpserver/FileServerHandler.java
+ * library /lib/testlibrary/ /
+ * build jdk.testlibrary.SimpleSSLContext ProxyServer EchoHandler
+ * compile ../../../com/sun/net/httpserver/LogFilter.java
+ * compile ../../../com/sun/net/httpserver/FileServerHandler.java
  */
 import com.sun.net.httpserver.Headers;
 import com.sun.net.httpserver.HttpContext;
--- a/jdk/test/java/net/httpclient/ManyRequests.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/net/httpclient/ManyRequests.java	Thu Apr 28 23:08:16 2016 -0700
@@ -24,18 +24,17 @@
 /**
  * @test
  * @bug 8087112
- * @library /lib/testlibrary/
- * @build jdk.testlibrary.SimpleSSLContext
+ * @library /lib/testlibrary/ /
+ * @build jdk.testlibrary.SimpleSSLContext EchoHandler
  * @compile ../../../com/sun/net/httpserver/LogFilter.java
  * @compile ../../../com/sun/net/httpserver/FileServerHandler.java
- * @run main/othervm ManyRequests
+ * @run main/othervm/timeout=40 -Djava.net.http.HttpClient.log=ssl ManyRequests
  * @summary Send a large number of requests asynchronously
  */
 
 //package javaapplication16;
 
-import com.sun.net.httpserver.HttpsConfigurator;
-import com.sun.net.httpserver.HttpsServer;
+import com.sun.net.httpserver.*;
 import java.io.IOException;
 import java.io.UncheckedIOException;
 import java.net.http.HttpClient;
@@ -47,18 +46,25 @@
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.Random;
+import java.util.logging.*;
 import java.util.concurrent.CompletableFuture;
-import javax.net.ssl.SSLContext;
+import javax.net.ssl.*;
 import jdk.testlibrary.SimpleSSLContext;
 
 public class ManyRequests {
 
+    volatile static int counter = 0;
+
     public static void main(String[] args) throws Exception {
+        Logger logger = Logger.getLogger("com.sun.net.httpserver");
+        logger.setLevel(Level.ALL);
+        logger.info("TEST");
+
         SSLContext ctx = new SimpleSSLContext().get();
 
         InetSocketAddress addr = new InetSocketAddress(0);
         HttpsServer server = HttpsServer.create(addr, 0);
-        server.setHttpsConfigurator(new HttpsConfigurator(ctx));
+        server.setHttpsConfigurator(new Configurator(ctx));
 
         HttpClient client = HttpClient.create()
                                       .sslContext(ctx)
@@ -72,7 +78,8 @@
         }
     }
 
-    static final int REQUESTS = 1000;
+    //static final int REQUESTS = 1000;
+    static final int REQUESTS = 20;
 
     static void test(HttpsServer server, HttpClient client) throws Exception {
         int port = server.getAddress().getPort();
@@ -102,6 +109,9 @@
                                resp.bodyAsync(HttpResponse.ignoreBody());
                                String s = "Expected 200, got: " + resp.statusCode();
                                return completedWithIOException(s);
+                           } else {
+                               counter++;
+                               System.out.println("Result from " + counter);
                            }
                            return resp.bodyAsync(HttpResponse.asByteArray())
                                       .thenApply((b) -> new Pair<>(resp, b));
@@ -114,14 +124,18 @@
 
                       });
         }
+
         // wait for them all to complete and throw exception in case of error
-        CompletableFuture.allOf(results).join();
+        //try {
+            CompletableFuture.allOf(results).join();
+        //} catch (Exception  e) {
+            //e.printStackTrace();
+            //throw e;
+        //}
     }
 
     static <T> CompletableFuture<T> completedWithIOException(String message) {
-        CompletableFuture<T> cf = new CompletableFuture<>();
-        cf.completeExceptionally(new IOException(message));
-        return cf;
+        return CompletableFuture.failedFuture(new IOException(message));
     }
 
     static final class Pair<T,U> {
@@ -192,3 +206,14 @@
         throw new RuntimeException(sb.toString());
     }
 }
+
+class Configurator extends HttpsConfigurator {
+    public Configurator(SSLContext ctx) {
+        super(ctx);
+    }
+
+    public void configure (HttpsParameters params) {
+        params.setSSLParameters (getSSLContext().getSupportedSSLParameters());
+    }
+}
+
--- a/jdk/test/java/net/httpclient/RequestBodyTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/net/httpclient/RequestBodyTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -23,10 +23,11 @@
 
 /**
  * @test @bug 8087112
- * @library /lib/testlibrary/
- * @build jdk.testlibrary.SimpleSSLContext ProxyServer
+ * @library /lib/testlibrary/ /
  * @compile ../../../com/sun/net/httpserver/LogFilter.java
  * @compile ../../../com/sun/net/httpserver/FileServerHandler.java
+ * @build LightWeightHttpServer
+ * @build jdk.testlibrary.SimpleSSLContext ProxyServer
  * @run main/othervm RequestBodyTest
  */
 
--- a/jdk/test/java/net/httpclient/SmokeTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/net/httpclient/SmokeTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -24,15 +24,13 @@
 /**
  * @test
  * @bug 8087112
- * @library /lib/testlibrary/
- * @build jdk.testlibrary.SimpleSSLContext ProxyServer
+ * @library /lib/testlibrary/ /
+ * @build jdk.testlibrary.SimpleSSLContext ProxyServer EchoHandler
  * @compile ../../../com/sun/net/httpserver/LogFilter.java
  * @compile ../../../com/sun/net/httpserver/FileServerHandler.java
  * @run main/othervm SmokeTest
  */
 
-//package javaapplication16;
-
 import com.sun.net.httpserver.*;
 import java.net.*;
 import java.net.http.*;
@@ -69,6 +67,7 @@
  */
 public class SmokeTest {
     static SSLContext ctx;
+    static SSLParameters sslparams;
     static HttpServer s1 ;
     static HttpsServer s2;
     static ExecutorService executor;
@@ -107,6 +106,7 @@
 
         client = HttpClient.create()
                            .sslContext(ctx)
+                           .sslParameters(sslparams)
                            .followRedirects(HttpClient.Redirect.ALWAYS)
                            .executorService(Executors.newCachedThreadPool())
                            .build();
@@ -285,6 +285,7 @@
         HttpClient cl = HttpClient.create()
                                   .proxy(ProxySelector.of(proxyAddr))
                                   .sslContext(ctx)
+                                  .sslParameters(sslparams)
                                   .build();
 
         CompletableFuture<String> fut = cl.request(uri)
@@ -672,7 +673,8 @@
         s1.setExecutor(executor);
         s2.setExecutor(executor);
         ctx = new SimpleSSLContext().get();
-        s2.setHttpsConfigurator(new HttpsConfigurator(ctx));
+        sslparams = ctx.getSupportedSSLParameters();
+        s2.setHttpsConfigurator(new Configurator(ctx));
         s1.start();
         s2.start();
 
@@ -689,6 +691,16 @@
     }
 }
 
+class Configurator extends HttpsConfigurator {
+    public Configurator(SSLContext ctx) {
+        super(ctx);
+    }
+
+    public void configure (HttpsParameters params) {
+        params.setSSLParameters (getSSLContext().getSupportedSSLParameters());
+    }
+}
+
 class UploadServer extends Thread {
     int statusCode;
     ServerSocket ss;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/TestKit.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2016, 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.regex.Pattern;
+
+import static java.util.Objects.requireNonNull;
+
+//
+// A set of testing utility functions
+//
+public final class TestKit {
+
+    private TestKit() { }
+
+    public static void assertNotThrows(ThrowingProcedure code) {
+        requireNonNull(code, "code");
+        assertNotThrows(() -> {
+            code.run();
+            return null;
+        });
+    }
+
+    public static <V> V assertNotThrows(ThrowingFunction<V> code) {
+        requireNonNull(code, "code");
+        try {
+            return code.run();
+        } catch (Throwable t) {
+            throw new RuntimeException("Expected to run normally, but threw "
+                    + t.getClass().getCanonicalName(), t);
+        }
+    }
+
+    public static <T extends Throwable> T assertThrows(Class<? extends T> clazz,
+                                                       ThrowingProcedure code) {
+        requireNonNull(clazz, "clazz");
+        requireNonNull(code, "code");
+        try {
+            code.run();
+        } catch (Throwable t) {
+            if (clazz.isInstance(t)) {
+                return clazz.cast(t);
+            }
+            throw new RuntimeException("Expected to catch an exception of type "
+                    + clazz.getCanonicalName() + ", but caught "
+                    + t.getClass().getCanonicalName(), t);
+
+        }
+        throw new RuntimeException("Expected to catch an exception of type "
+                + clazz.getCanonicalName() + ", but caught nothing");
+    }
+
+    public interface ThrowingProcedure {
+        void run() throws Throwable;
+    }
+
+    public interface ThrowingFunction<V> {
+        V run() throws Throwable;
+    }
+
+    // The rationale behind asking for a regex is to not pollute variable names
+    // space in the scope of assertion: if it's something as simple as checking
+    // a message, we can do it inside
+    public static <T extends Throwable> T assertThrows(Class<? extends T> clazz,
+                                                       String messageRegex,
+                                                       ThrowingProcedure code) {
+        requireNonNull(messageRegex, "messagePattern");
+        T t = assertThrows(clazz, code);
+        String m = t.getMessage();
+        if (m == null) {
+            throw new RuntimeException(String.format(
+                    "Expected exception message to match the regex '%s', " +
+                            "but the message was null", messageRegex), t);
+        }
+        if (!Pattern.matches(messageRegex, m)) {
+            throw new RuntimeException(String.format(
+                    "Expected exception message to match the regex '%s', " +
+                            "actual message: %s", messageRegex, m), t);
+        }
+        return t;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/TestKitTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2016, 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.IOException;
+import java.util.IllegalFormatException;
+import java.util.Set;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+/*
+ * @test
+ * @compile TestKit.java
+ * @run testng TestKitTest
+ */
+public final class TestKitTest {
+
+    public static void main(String[] args) {
+        testAssertNotThrows();
+        testAssertThrows();
+    }
+
+    private static void testAssertNotThrows() {
+        Integer integer = TestKit.assertNotThrows(
+                () -> TestKit.assertNotThrows(() -> 1)
+        );
+        assertEquals(integer, Integer.valueOf(1));
+
+        RuntimeException re = TestKit.assertThrows(
+                RuntimeException.class,
+                () -> TestKit.assertNotThrows(() -> { throw new IOException(); })
+        );
+        assertEquals(re.getMessage(),
+                "Expected to run normally, but threw "
+                        + "java.io.IOException");
+
+        TestKit.assertNotThrows(
+                () -> TestKit.assertNotThrows(() -> { })
+        );
+
+        re = TestKit.assertThrows(
+                RuntimeException.class,
+                () ->  TestKit.assertNotThrows((TestKit.ThrowingProcedure) () -> { throw new IOException(); })
+        );
+        assertEquals(re.getMessage(),
+                "Expected to run normally, but threw "
+                        + "java.io.IOException");
+    }
+
+    private static void testAssertThrows() {
+        NullPointerException npe = TestKit.assertThrows(
+                NullPointerException.class,
+                () -> TestKit.assertThrows(null, null)
+        );
+        assertNotNull(npe);
+        assertTrue(Set.of("clazz", "code").contains(npe.getMessage()), npe.getMessage());
+
+        npe = TestKit.assertThrows(
+                NullPointerException.class,
+                () -> TestKit.assertThrows(IOException.class, null)
+        );
+        assertNotNull(npe);
+        assertEquals(npe.getMessage(), "code");
+
+        npe = TestKit.assertThrows(
+                NullPointerException.class,
+                () -> TestKit.assertThrows(null, () -> { })
+        );
+        assertEquals(npe.getMessage(), "clazz");
+
+        npe = TestKit.assertThrows(
+                NullPointerException.class,
+                () -> { throw new NullPointerException(); }
+        );
+        assertNotNull(npe);
+        assertNull(npe.getMessage());
+        assertEquals(npe.getClass(), NullPointerException.class);
+
+        RuntimeException re = TestKit.assertThrows(
+                RuntimeException.class,
+                () -> TestKit.assertThrows(NullPointerException.class, () -> { })
+        );
+        assertEquals(re.getClass(), RuntimeException.class);
+        assertEquals(re.getMessage(),
+                "Expected to catch an exception of type "
+                        + "java.lang.NullPointerException, but caught nothing");
+
+        re = TestKit.assertThrows(
+                RuntimeException.class,
+                () -> { throw new NullPointerException(); }
+        );
+        assertNotNull(re);
+        assertNull(re.getMessage());
+        assertEquals(re.getClass(), NullPointerException.class);
+
+        re = TestKit.assertThrows(
+                RuntimeException.class,
+                () -> TestKit.assertThrows(
+                        IllegalFormatException.class,
+                        () -> { throw new IndexOutOfBoundsException(); }
+                ));
+        assertNotNull(re);
+        assertEquals(re.getClass(), RuntimeException.class);
+        assertEquals(re.getMessage(),
+                "Expected to catch an exception of type java.util.IllegalFormatException"
+                        + ", but caught java.lang.IndexOutOfBoundsException");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/BasicTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2015, 2016, 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 8087112
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.SimpleSSLContext
+ * @modules java.httpclient
+ * @compile/module=java.httpclient java/net/http/BodyOutputStream.java
+ * @compile/module=java.httpclient java/net/http/BodyInputStream.java
+ * @compile/module=java.httpclient java/net/http/EchoHandler.java
+ * @compile/module=java.httpclient java/net/http/Http2Handler.java
+ * @compile/module=java.httpclient java/net/http/Http2TestExchange.java
+ * @compile/module=java.httpclient java/net/http/Http2TestServerConnection.java
+ * @compile/module=java.httpclient java/net/http/Http2TestServer.java
+ * @compile/module=java.httpclient java/net/http/OutgoingPushPromise.java
+ * @compile/module=java.httpclient java/net/http/TestUtil.java
+ * @run testng/othervm -Djava.net.http.HttpClient.log=ssl,requests,responses,errors BasicTest
+ */
+
+import java.io.*;
+import java.net.*;
+import java.net.http.*;
+import static java.net.http.HttpClient.Version.HTTP_2;
+import javax.net.ssl.*;
+import java.nio.file.*;
+import java.util.concurrent.*;
+import jdk.testlibrary.SimpleSSLContext;
+
+
+import org.testng.annotations.Test;
+import org.testng.annotations.Parameters;
+
+@Test
+public class BasicTest {
+    static int httpPort, httpsPort;
+    static Http2TestServer httpServer, httpsServer;
+    static HttpClient client = null;
+    static ExecutorService exec;
+    static SSLContext sslContext;
+
+    static String httpURIString, httpsURIString;
+
+    static void initialize() throws Exception {
+        try {
+            SimpleSSLContext sslct = new SimpleSSLContext();
+            sslContext = sslct.get();
+            client = getClient();
+            exec = client.executorService();
+            httpServer = new Http2TestServer(false, 0, new EchoHandler(),
+                    exec, sslContext);
+            httpPort = httpServer.getAddress().getPort();
+
+            httpsServer = new Http2TestServer(true, 0, new EchoHandler(),
+                    exec, sslContext);
+
+            httpsPort = httpsServer.getAddress().getPort();
+            httpURIString = "http://127.0.0.1:" + Integer.toString(httpPort) +
+                    "/foo/";
+            httpsURIString = "https://127.0.0.1:" + Integer.toString(httpsPort) +
+                    "/bar/";
+
+            httpServer.start();
+            httpsServer.start();
+        } catch (Throwable e) {
+            System.err.println("Throwing now");
+            e.printStackTrace();
+            throw e;
+        }
+    }
+
+    @Test(timeOut=30000)
+    public static void test() throws Exception {
+        try {
+            initialize();
+            simpleTest(false);
+            simpleTest(true);
+            streamTest(false);
+            streamTest(true);
+            Thread.sleep(1000 * 4);
+        } finally {
+            httpServer.stop();
+            httpsServer.stop();
+            exec.shutdownNow();
+        }
+    }
+
+    static HttpClient getClient() {
+        if (client == null) {
+            client = HttpClient.create()
+                .sslContext(sslContext)
+                .version(HTTP_2)
+                .build();
+        }
+        return client;
+    }
+
+    static URI getURI(boolean secure) {
+        if (secure)
+            return URI.create(httpsURIString);
+        else
+            return URI.create(httpURIString);
+    }
+
+    static void checkStatus(int expected, int found) throws Exception {
+        if (expected != found) {
+            System.err.printf ("Test failed: wrong status code %d/%d\n",
+                expected, found);
+            throw new RuntimeException("Test failed");
+        }
+    }
+
+    static void checkStrings(String expected, String found) throws Exception {
+        if (!expected.equals(found)) {
+            System.err.printf ("Test failed: wrong string %s/%s\n",
+                expected, found);
+            throw new RuntimeException("Test failed");
+        }
+    }
+
+    static Void compareFiles(Path path1, Path path2) {
+        return java.net.http.TestUtil.compareFiles(path1, path2);
+    }
+
+    static Path tempFile() {
+        return java.net.http.TestUtil.tempFile();
+    }
+
+    static final String SIMPLE_STRING = "Hello world Goodbye world";
+
+    static final int LOOPS = 13;
+    static final int FILESIZE = 64 * 1024;
+
+    static void streamTest(boolean secure) throws Exception {
+        URI uri = getURI(secure);
+        System.err.printf("streamTest %b to %s\n" , secure, uri);
+
+        HttpClient client = getClient();
+        Path src = java.net.http.TestUtil.getAFile(FILESIZE * 4);
+        HttpRequest req = client.request(uri)
+                .body(HttpRequest.fromFile(src))
+                .POST();
+
+        CompletableFuture<InputStream> response = req.responseAsync()
+                .thenCompose(resp -> {
+                    if (resp.statusCode() != 200)
+                        throw new RuntimeException();
+                    return resp.bodyAsync(HttpResponse.asInputStream());
+                });
+        InputStream is = response.join();
+        File dest = File.createTempFile("foo","bar");
+        dest.deleteOnExit();
+        FileOutputStream os = new FileOutputStream(dest);
+        is.transferTo(os);
+        is.close();
+        os.close();
+        int count = 0;
+        compareFiles(src, dest.toPath());
+        System.err.println("DONE");
+    }
+
+
+    static void simpleTest(boolean secure) throws Exception {
+        URI uri = getURI(secure);
+        System.err.println("Request to " + uri);
+
+        // Do a simple warmup request
+
+        HttpClient client = getClient();
+        HttpRequest req = client.request(uri)
+                .body(HttpRequest.fromString(SIMPLE_STRING))
+                .POST();
+        HttpResponse response = req.response();
+        HttpHeaders h = response.headers();
+
+        checkStatus(200, response.statusCode());
+
+        String responseBody = response.body(HttpResponse.asString());
+        checkStrings(SIMPLE_STRING, responseBody);
+
+        checkStrings(h.firstValue("x-hello").get(), "world");
+        checkStrings(h.firstValue("x-bye").get(), "universe");
+
+        // Do loops asynchronously
+
+        CompletableFuture[] responses = new CompletableFuture[LOOPS];
+        final Path source = java.net.http.TestUtil.getAFile(FILESIZE);
+        for (int i = 0; i < LOOPS; i++) {
+            responses[i] = client.request(uri)
+                .body(HttpRequest.fromFile(source))
+                .version(HTTP_2)
+                .POST()
+                .responseAsync()
+                .thenCompose(r -> r.bodyAsync(HttpResponse.asFile(tempFile())))
+                .thenApply(path -> compareFiles(path, source));
+            Thread.sleep(100);
+        }
+        CompletableFuture.allOf(responses).join();
+        System.err.println("DONE");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/HpackDriver.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016, 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 8153353
+ * @modules java.httpclient/sun.net.httpclient.hpack
+ * @key randomness
+ * @compile/module=java.httpclient sun/net/httpclient/hpack/SpecHelper.java
+ * @compile/module=java.httpclient sun/net/httpclient/hpack/TestHelper.java
+ * @compile/module=java.httpclient sun/net/httpclient/hpack/BuffersTestingKit.java
+ * @run testng/othervm -XaddReads:java.httpclient=ALL-UNNAMED java.httpclient/sun.net.httpclient.hpack.BinaryPrimitivesTest
+ * @run testng/othervm -XaddReads:java.httpclient=ALL-UNNAMED java.httpclient/sun.net.httpclient.hpack.CircularBufferTest
+ * @run testng/othervm -XaddReads:java.httpclient=ALL-UNNAMED java.httpclient/sun.net.httpclient.hpack.DecoderTest
+ * @run testng/othervm -XaddReads:java.httpclient=ALL-UNNAMED java.httpclient/sun.net.httpclient.hpack.EncoderTest
+ * @run testng/othervm -XaddReads:java.httpclient=ALL-UNNAMED java.httpclient/sun.net.httpclient.hpack.HeaderTableTest
+ * @run testng/othervm -XaddReads:java.httpclient=ALL-UNNAMED java.httpclient/sun.net.httpclient.hpack.HuffmanTest
+ * @run testng/othervm -XaddReads:java.httpclient=ALL-UNNAMED java.httpclient/sun.net.httpclient.hpack.TestHelper
+ */
+public class HpackDriver { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/ServerPush.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2015, 2016, 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 8087112
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.SimpleSSLContext
+ * @modules java.httpclient
+ * @compile/module=java.httpclient java/net/http/BodyOutputStream.java
+ * @compile/module=java.httpclient java/net/http/BodyInputStream.java
+ * @compile/module=java.httpclient java/net/http/PushHandler.java
+ * @compile/module=java.httpclient java/net/http/Http2Handler.java
+ * @compile/module=java.httpclient java/net/http/Http2TestExchange.java
+ * @compile/module=java.httpclient java/net/http/Http2TestServerConnection.java
+ * @compile/module=java.httpclient java/net/http/Http2TestServer.java
+ * @compile/module=java.httpclient java/net/http/OutgoingPushPromise.java
+ * @compile/module=java.httpclient java/net/http/TestUtil.java
+ * @run testng/othervm -Djava.net.http.HttpClient.log=requests,responses ServerPush
+ */
+
+import java.io.*;
+import java.net.*;
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.net.http.*;
+import java.util.*;
+import java.util.concurrent.*;
+import org.testng.annotations.Test;
+
+public class ServerPush {
+
+    static ExecutorService e = Executors.newCachedThreadPool();
+
+    static final int LOOPS = 13;
+    static final int FILE_SIZE = 32 * 1024;
+
+    static Path tempFile;
+
+    @Test(timeOut=30000)
+    public static void test() throws Exception {
+        Http2TestServer server = null;
+        Path dir = null;
+        try {
+            server = new Http2TestServer(false, 0,
+                                         new PushHandler(FILE_SIZE, LOOPS));
+            tempFile = TestUtil.getAFile(FILE_SIZE);
+
+            System.err.println("Server listening on port " + server.getAddress().getPort());
+            server.start();
+            int port = server.getAddress().getPort();
+            dir = Files.createTempDirectory("serverPush");
+
+            URI uri = new URI("http://127.0.0.1:" + Integer.toString(port) + "/foo");
+            HttpRequest request = HttpRequest.create(uri)
+                    .version(HttpClient.Version.HTTP_2)
+                    .GET();
+
+            CompletableFuture<Map<URI,Path>> cf =
+            request.multiResponseAsync(HttpResponse.multiFile(dir));
+            Map<URI,Path> results = cf.get();
+
+            //HttpResponse resp = request.response();
+            System.err.println(results.size());
+            Set<URI> uris = results.keySet();
+            for (URI u : uris) {
+                Path result = results.get(u);
+                System.err.printf("%s -> %s\n", u.toString(), result.toString());
+                TestUtil.compareFiles(result, tempFile);
+            }
+            System.out.println("TEST OK");
+        } finally {
+            e.shutdownNow();
+            server.stop();
+            Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
+                public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
+                    dir.toFile().delete();
+                    return FileVisitResult.CONTINUE;
+                }
+                public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) {
+                    path.toFile().delete();
+                    return FileVisitResult.CONTINUE;
+                }
+            });
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/TEST.properties	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,1 @@
+bootclasspath.dirs = /java/net/httpclient
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/BodyInputStream.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,107 @@
+package java.net.http;
+
+import java.io.*;
+import java.nio.ByteBuffer;
+
+/**
+ * InputStream reads frames off stream q and supplies read demand from any
+ * DataFrames it finds. Window updates are sent back on the connections send
+ * q.
+ */
+class BodyInputStream extends InputStream {
+
+    final Queue<Http2Frame> q;
+    final int streamid;
+    boolean closed;
+    boolean eof;
+    final Http2TestServerConnection conn;
+
+    @SuppressWarnings({"rawtypes","unchecked"})
+    BodyInputStream(Queue q, int streamid, Http2TestServerConnection conn) {
+        this.q = q;
+        this.streamid = streamid;
+        this.conn = conn;
+    }
+
+    DataFrame df;
+    ByteBuffer[] buffers;
+    ByteBuffer buffer;
+    int nextIndex = -1;
+
+    private DataFrame getData() throws IOException {
+        if (eof) {
+            return null;
+        }
+        Http2Frame frame;
+        do {
+            frame = q.take();
+            if (frame.type() == ResetFrame.TYPE) {
+                conn.handleStreamReset((ResetFrame) frame); // throws IOException
+            }
+            // ignoring others for now Wupdates handled elsewhere
+            if (frame.type() != DataFrame.TYPE) {
+                System.out.println("Ignoring " + frame.toString() + " CHECK THIS");
+            }
+        } while (frame.type() != DataFrame.TYPE);
+        df = (DataFrame) frame;
+        int len = df.getDataLength();
+        eof = frame.getFlag(DataFrame.END_STREAM);
+        // acknowledge
+        conn.sendWindowUpdates(len, streamid);
+        return (DataFrame) frame;
+    }
+
+    // null return means EOF
+    private ByteBuffer getBuffer() throws IOException {
+        if (buffer == null || !buffer.hasRemaining()) {
+            if (nextIndex == -1 || nextIndex == buffers.length) {
+                DataFrame df = getData();
+                if (df == null) {
+                    return null;
+                }
+                int len = df.getDataLength();
+                if ((len == 0) && eof) {
+                    return null;
+                }
+                buffers = df.getData();
+                nextIndex = 0;
+            }
+            buffer = buffers[nextIndex++];
+        }
+        return buffer;
+    }
+
+    @Override
+    public int read(byte[] buf, int offset, int length) throws IOException {
+        if (closed) {
+            throw new IOException("closed");
+        }
+        ByteBuffer b = getBuffer();
+        if (b == null) {
+            return -1;
+        }
+        int remaining = b.remaining();
+        if (remaining < length) {
+            length = remaining;
+        }
+        b.get(buf, offset, length);
+        return length;
+    }
+
+    byte[] one = new byte[1];
+
+    @Override
+    public int read() throws IOException {
+        int c = read(one, 0, 1);
+        if (c == -1) {
+            return -1;
+        }
+        return one[0];
+    }
+
+    @Override
+    public void close() {
+        // TODO reset this stream
+        closed = true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/BodyOutputStream.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,106 @@
+package java.net.http;
+
+import java.io.*;
+import java.nio.ByteBuffer;
+
+/**
+ * OutputStream. Incoming window updates handled by the main connection
+ * reader thread.
+ */
+@SuppressWarnings({"rawtypes","unchecked"})
+class BodyOutputStream extends OutputStream {
+    final static byte[] EMPTY_BARRAY = new byte[0];
+
+    final int streamid;
+    int window;
+    boolean closed;
+    boolean goodToGo = false; // not allowed to send until headers sent
+    final Http2TestServerConnection conn;
+    final Queue outputQ;
+
+    BodyOutputStream(int streamid, int initialWindow, Http2TestServerConnection conn) {
+        this.window = initialWindow;
+        this.streamid = streamid;
+        this.conn = conn;
+        this.outputQ = conn.outputQ;
+        conn.registerStreamWindowUpdater(streamid, this::updateWindow);
+    }
+
+    // called from connection reader thread as all incoming window
+    // updates are handled there.
+    synchronized void updateWindow(int update) {
+        window += update;
+        notifyAll();
+    }
+
+    void waitForWindow(int demand) throws InterruptedException {
+        // first wait for the connection window
+        conn.obtainConnectionWindow(demand);
+        // now wait for the stream window
+        synchronized (this) {
+            while (demand > 0) {
+                int n = Math.min(demand, window);
+                demand -= n;
+                window -= n;
+                if (demand > 0) {
+                    wait();
+                }
+            }
+        }
+    }
+
+    void goodToGo() {
+        goodToGo = true;
+    }
+
+    @Override
+    public void write(byte[] buf, int offset, int len) throws IOException {
+        if (closed) {
+            throw new IOException("closed");
+        }
+
+        if (!goodToGo) {
+            throw new IllegalStateException("sendResponseHeaders must be called first");
+        }
+        try {
+            waitForWindow(len);
+            send(buf, offset, len, 0);
+        } catch (InterruptedException ex) {
+            throw new IOException(ex);
+        }
+    }
+
+    private void send(byte[] buf, int offset, int len, int flags) throws IOException {
+        ByteBuffer buffer = ByteBuffer.allocate(len);
+        buffer.put(buf, offset, len);
+        buffer.flip();
+        DataFrame df = new DataFrame();
+        assert streamid != 0;
+        df.streamid(streamid);
+        df.setFlags(flags);
+        df.setData(buffer);
+        outputQ.put(df);
+    }
+
+    byte[] one = new byte[1];
+
+    @Override
+    public void write(int b) throws IOException {
+        one[0] = (byte) b;
+        write(one, 0, 1);
+    }
+
+    @Override
+    public void close() {
+        if (closed) {
+            return;
+        }
+        closed = true;
+        try {
+            send(EMPTY_BARRAY, 0, 0, DataFrame.END_STREAM);
+        } catch (IOException ex) {
+            System.err.println("TestServer: OutputStream.close exception: " + ex);
+            ex.printStackTrace();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/EchoHandler.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net.http;
+
+import java.util.*;
+import java.util.concurrent.*;
+import java.io.*;
+import java.net.*;
+
+public class EchoHandler implements Http2Handler {
+    public EchoHandler() {}
+
+    @Override
+    public void handle(Http2TestExchange t)
+            throws IOException {
+        try {
+            System.err.println("EchoHandler received request to " + t.getRequestURI());
+            InputStream is = t.getRequestBody();
+            HttpHeadersImpl map = t.getRequestHeaders();
+            HttpHeadersImpl map1 = t.getResponseHeaders();
+            map1.addHeader("X-Hello", "world");
+            map1.addHeader("X-Bye", "universe");
+            String fixedrequest = map.firstValue("XFixed").orElse(null);
+            File outfile = File.createTempFile("foo", "bar");
+            FileOutputStream fos = new FileOutputStream(outfile);
+            int count = (int) is.transferTo(fos);
+            System.err.printf("EchoHandler read %d bytes\n", count);
+            is.close();
+            fos.close();
+            InputStream is1 = new FileInputStream(outfile);
+            OutputStream os = null;
+            // return the number of bytes received (no echo)
+            String summary = map.firstValue("XSummary").orElse(null);
+            if (fixedrequest != null && summary == null) {
+                t.sendResponseHeaders(200, count);
+                os = t.getResponseBody();
+                is1.transferTo(os);
+            } else {
+                t.sendResponseHeaders(200, 0);
+                os = t.getResponseBody();
+                int count1 = (int)is1.transferTo(os);
+                System.err.printf("EchoHandler wrote %d bytes\n", count1);
+
+                if (summary != null) {
+                    String s = Integer.toString(count);
+                    os.write(s.getBytes());
+                }
+            }
+            outfile.delete();
+            os.close();
+            is1.close();
+        } catch (Throwable e) {
+            e.printStackTrace();
+            throw new IOException(e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/Http2Handler.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,18 @@
+package java.net.http;
+
+import java.io.IOException;
+
+/**
+ * A handler which is invoked to process HTTP exchanges. Each
+ * HTTP exchange is handled by one of these handlers.
+ */
+public interface Http2Handler {
+    /**
+     * Handle the given request and generate an appropriate response.
+     * @param exchange the exchange containing the request from the
+     *      client and used to send the response
+     * @throws NullPointerException if exchange is <code>null</code>
+     */
+    public abstract void handle (Http2TestExchange exchange) throws IOException;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/Http2TestExchange.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,126 @@
+package java.net.http;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+import java.net.URI;
+import java.net.InetSocketAddress;
+
+public class Http2TestExchange {
+
+    final HttpHeadersImpl reqheaders;
+    final HttpHeadersImpl rspheaders;
+    final URI uri;
+    final String method;
+    final InputStream is;
+    final BodyOutputStream os;
+    final int streamid;
+    final boolean pushAllowed;
+    final Http2TestServerConnection conn;
+    final Http2TestServer server;
+
+    int responseCode = -1;
+    long responseLength;
+
+    Http2TestExchange(int streamid, String method, HttpHeadersImpl reqheaders,
+            HttpHeadersImpl rspheaders, URI uri, InputStream is,
+            BodyOutputStream os, Http2TestServerConnection conn, boolean pushAllowed) {
+        this.reqheaders = reqheaders;
+        this.rspheaders = rspheaders;
+        this.uri = uri;
+        this.method = method;
+        this.is = is;
+        this.streamid = streamid;
+        this.os = os;
+        this.pushAllowed = pushAllowed;
+        this.conn = conn;
+        this.server = conn.server;
+    }
+
+    public HttpHeadersImpl getRequestHeaders() {
+        return reqheaders;
+    }
+
+    public HttpHeadersImpl getResponseHeaders() {
+        return rspheaders;
+    }
+
+    public URI getRequestURI() {
+        return uri;
+    }
+
+    public String getRequestMethod() {
+        return method;
+    }
+
+    public void close() {
+        try {
+            is.close();
+            os.close();
+        } catch (IOException e) {
+            System.err.println("TestServer: HttpExchange.close exception: " + e);
+            e.printStackTrace();
+        }
+    }
+
+    public InputStream getRequestBody() {
+        return is;
+    }
+
+    public OutputStream getResponseBody() {
+        return os;
+    }
+
+    public void sendResponseHeaders(int rCode, long responseLength) throws IOException {
+        this.responseLength = responseLength;
+        if (responseLength > 0 || responseLength < 0) {
+                long clen = responseLength > 0 ? responseLength : 0;
+            rspheaders.setHeader("Content-length", Long.toString(clen));
+        }
+
+        rspheaders.setHeader(":status", Integer.toString(rCode));
+
+        Http2TestServerConnection.ResponseHeaders response
+                = new Http2TestServerConnection.ResponseHeaders(rspheaders);
+        response.streamid(streamid);
+        response.setFlag(HeaderFrame.END_HEADERS);
+        conn.outputQ.put(response);
+        os.goodToGo();
+        System.err.println("Sent response headers " + rCode);
+    }
+
+    public InetSocketAddress getRemoteAddress() {
+        return (InetSocketAddress) conn.socket.getRemoteSocketAddress();
+    }
+
+    public int getResponseCode() {
+        return responseCode;
+    }
+
+    public InetSocketAddress getLocalAddress() {
+        return server.getAddress();
+    }
+
+    public String getProtocol() {
+        return "HTTP/2";
+    }
+
+    public boolean serverPushAllowed() {
+        return pushAllowed;
+    }
+
+    public void serverPush(URI uri, HttpHeadersImpl headers, InputStream content) {
+        OutgoingPushPromise pp = new OutgoingPushPromise(
+                streamid, uri, headers, content);
+        headers.setHeader(":method", "GET");
+        headers.setHeader(":scheme", uri.getScheme());
+        headers.setHeader(":authority", uri.getAuthority());
+        headers.setHeader(":path", uri.getPath());
+        try {
+            conn.outputQ.put(pp);
+            // writeLoop will spin up thread to read the InputStream
+        } catch (IOException ex) {
+            System.err.println("TestServer: pushPromise exception: " + ex);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/Http2TestServer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2015, 2016, 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 java.net.http;
+
+import java.io.IOException;
+import java.net.*;
+import java.util.HashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import javax.net.ServerSocketFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLServerSocketFactory;
+
+/**
+ * Waits for incoming TCP connections from a client and establishes
+ * a HTTP2 connection. Two threads are created per connection. One for reading
+ * and one for writing. Incoming requests are dispatched to the supplied
+ * Http2Handler on additional threads. All threads
+ * obtained from the supplied ExecutorService.
+ */
+public class Http2TestServer {
+    final ServerSocket server;
+    boolean secure;
+    SettingsFrame serverSettings, clientSettings;
+    final ExecutorService exec;
+    volatile boolean stopping = false;
+    final Http2Handler handler;
+    final SSLContext sslContext;
+    final HashMap<InetSocketAddress,Http2TestServerConnection> connections;
+
+    private static ThreadFactory defaultThreadFac =
+        (Runnable r) -> {
+            Thread t = new Thread(r);
+            t.setName("Test-server-pool");
+            return t;
+        };
+
+
+    private static ExecutorService getDefaultExecutor() {
+        return Executors.newCachedThreadPool(defaultThreadFac);
+    }
+
+    public Http2TestServer(boolean secure, int port, Http2Handler handler) throws Exception {
+        this(secure, port, handler, getDefaultExecutor(), null);
+    }
+
+    public InetSocketAddress getAddress() {
+        return (InetSocketAddress)server.getLocalSocketAddress();
+    }
+
+    /**
+     * Create a Http2Server listening on the given port. Currently needs
+     * to know in advance whether incoming connections are plain TCP "h2c"
+     * or TLS "h2"/
+     *
+     * @param secure https or http
+     * @param port listen port
+     * @param handler the handler which receives incoming requests
+     * @param exec executor service (cached thread pool is used if null)
+     * @param context the SSLContext used when secure is true
+     * @throws Exception
+     */
+    public Http2TestServer(boolean secure, int port, Http2Handler handler,
+            ExecutorService exec, SSLContext context) throws Exception {
+        if (secure) {
+            server = initSecure(port);
+        } else {
+            server = initPlaintext(port);
+        }
+        this.secure = secure;
+        this.exec = exec == null ? getDefaultExecutor() : exec;
+        this.handler = handler;
+        this.sslContext = context;
+        this.connections = new HashMap<>();
+    }
+
+    final ServerSocket initPlaintext(int port) throws Exception {
+        return new ServerSocket(port);
+    }
+
+    public void stop() {
+        // TODO: clean shutdown GoAway
+        stopping = true;
+        for (Http2TestServerConnection connection : connections.values()) {
+            connection.close();
+        }
+        try {
+            server.close();
+        } catch (IOException e) {}
+        exec.shutdownNow();
+    }
+
+
+    final ServerSocket initSecure(int port) throws Exception {
+        ServerSocketFactory fac;
+        if (sslContext != null) {
+            fac = sslContext.getServerSocketFactory();
+        } else {
+            fac = SSLServerSocketFactory.getDefault();
+        }
+        SSLServerSocket se = (SSLServerSocket) fac.createServerSocket(port);
+        SSLParameters sslp = se.getSSLParameters();
+        sslp.setApplicationProtocols(new String[]{"h2"});
+        se.setSSLParameters(sslp);
+        se.setEnabledCipherSuites(se.getSupportedCipherSuites());
+        se.setEnabledProtocols(se.getSupportedProtocols());
+        // other initialisation here
+        return se;
+    }
+
+    /**
+     * Start thread which waits for incoming connections.
+     *
+     * @throws Exception
+     */
+    public void start() {
+        exec.submit(() -> {
+            try {
+                while (!stopping) {
+                    Socket socket = server.accept();
+                    InetSocketAddress addr = (InetSocketAddress) socket.getRemoteSocketAddress();
+                    Http2TestServerConnection c = new Http2TestServerConnection(this, socket);
+                    connections.put(addr, c);
+                    c.run();
+                }
+            } catch (Throwable e) {
+                if (!stopping) {
+                    System.err.println("TestServer: start exception: " + e);
+                    e.printStackTrace();
+                }
+            }
+        });
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/Http2TestServerConnection.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,730 @@
+/*
+ * Copyright (c) 2015, 2016, 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 java.net.http;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.net.URI;
+import java.net.URISyntaxException;
+import static java.net.http.SettingsFrame.HEADER_TABLE_SIZE;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+import java.util.concurrent.ExecutorService;
+import java.util.function.Consumer;
+import sun.net.httpclient.hpack.Decoder;
+import sun.net.httpclient.hpack.DecodingCallback;
+import sun.net.httpclient.hpack.Encoder;
+
+/**
+ * Represents one HTTP2 connection, either plaintext upgraded from HTTP/1.1
+ * or HTTPS opened using "h2" ALPN.
+ */
+public class Http2TestServerConnection {
+    final Http2TestServer server;
+    @SuppressWarnings({"rawtypes","unchecked"})
+    final Map<Integer, Queue> streams; // input q per stream
+    final Queue<Http2Frame> outputQ;
+    int nextstream;
+    final Socket socket;
+    final InputStream is;
+    final OutputStream os;
+    Encoder hpackOut;
+    Decoder hpackIn;
+    SettingsFrame clientSettings, serverSettings;
+    final ExecutorService exec;
+    final boolean secure;
+    final Http2Handler handler;
+    volatile boolean stopping;
+    int nextPushStreamId = 2;
+
+    final static ByteBuffer EMPTY_BUFFER = ByteBuffer.allocate(0);
+    final static byte[] EMPTY_BARRAY = new byte[0];
+
+    final static byte[] clientPreface = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n".getBytes();
+
+    Http2TestServerConnection(Http2TestServer server, Socket socket) throws IOException {
+        System.err.println("New connection from " + socket);
+        this.server = server;
+        this.streams = Collections.synchronizedMap(new HashMap<>());
+        this.outputQ = new Queue<>();
+        this.socket = socket;
+        this.clientSettings = server.clientSettings;
+        this.serverSettings = server.serverSettings;
+        this.exec = server.exec;
+        this.secure = server.secure;
+        this.handler = server.handler;
+        is = new BufferedInputStream(socket.getInputStream());
+        os = new BufferedOutputStream(socket.getOutputStream());
+    }
+
+    void close() {
+        streams.forEach((i, q) -> {
+            q.close();
+        });
+        stopping = true;
+        try {
+            socket.close();
+            // TODO: put a reset on each stream
+        } catch (IOException e) {
+        }
+    }
+
+    private void readPreface() throws IOException {
+        int len = clientPreface.length;
+        byte[] bytes = new byte[len];
+        is.readNBytes(bytes, 0, len);
+        if (Arrays.compare(clientPreface, bytes) != 0) {
+            throw new IOException("Invalid preface: " + new String(bytes, 0, len));
+        }
+    }
+
+    String doUpgrade() throws IOException {
+        String upgrade = readHttp1Request();
+        String h2c = getHeader(upgrade, "Upgrade");
+        if (h2c == null || !h2c.equals("h2c")) {
+            throw new IOException("Bad upgrade 1 " + h2c);
+        }
+
+        sendHttp1Response(101, "Switching Protocols", "Connection", "Upgrade",
+                "Upgrade", "h2c");
+
+        sendSettingsFrame();
+        readPreface();
+
+        String clientSettingsString = getHeader(upgrade, "HTTP2-Settings");
+        clientSettings = getSettingsFromString(clientSettingsString);
+
+        return upgrade;
+    }
+
+    /**
+     * Client settings payload provided in base64 HTTP1 header. Decode it
+     * and add a header so we can interpret it.
+     *
+     * @param s
+     * @return
+     * @throws IOException
+     */
+    private SettingsFrame getSettingsFromString(String s) throws IOException {
+        Base64.Decoder decoder = Base64.getUrlDecoder();
+        byte[] payload = decoder.decode(s);
+        ByteBuffer bb1 = ByteBuffer.wrap(payload);
+        // simulate header of Settings Frame
+        ByteBuffer bb0 = ByteBuffer.wrap(
+                new byte[] {0, 0, (byte)payload.length, 4, 0, 0, 0, 0, 0});
+        ByteBufferConsumer bbc = new ByteBufferConsumer(
+                new LinkedList<ByteBuffer>(List.of(bb0, bb1)),
+                this::getBuffer);
+        Http2Frame frame = Http2Frame.readIncoming(bbc);
+        if (!(frame instanceof SettingsFrame))
+            throw new IOException("Expected SettingsFrame");
+        return (SettingsFrame)frame;
+    }
+
+    void run() throws Exception {
+        String upgrade = null;
+        if (!secure) {
+            upgrade = doUpgrade();
+        } else {
+            readPreface();
+            sendSettingsFrame(true);
+            clientSettings = (SettingsFrame) readFrame();
+            nextstream = 1;
+        }
+
+        hpackOut = new Encoder(serverSettings.getParameter(HEADER_TABLE_SIZE));
+        hpackIn = new Decoder(clientSettings.getParameter(HEADER_TABLE_SIZE));
+
+        exec.submit(() -> {
+            readLoop();
+        });
+        exec.submit(() -> {
+            writeLoop();
+        });
+        if (!secure) {
+            createPrimordialStream(upgrade);
+            nextstream = 3;
+        }
+    }
+
+    static class BufferPool implements BufferHandler {
+
+        public void setMinBufferSize(int size) {
+        }
+
+        public ByteBuffer getBuffer(int size) {
+            if (size == -1)
+                size = 32 * 1024;
+            return ByteBuffer.allocate(size);
+        }
+
+        public void returnBuffer(ByteBuffer buffer) {
+        }
+    }
+
+    static BufferPool bufferpool = new BufferPool();
+
+    private void writeFrame(Http2Frame frame) throws IOException {
+        ByteBufferGenerator bg = new ByteBufferGenerator(bufferpool);
+        frame.computeLength();
+        System.err.println("Writing frame " + frame.toString());
+        frame.writeOutgoing(bg);
+        ByteBuffer[] bufs = bg.getBufferArray();
+        int c = 0;
+        for (ByteBuffer buf : bufs) {
+            byte[] ba = buf.array();
+            int start = buf.arrayOffset() + buf.position();
+            c += buf.remaining();
+            os.write(ba, start, buf.remaining());
+        }
+        os.flush();
+        System.err.printf("wrote %d bytes\n", c);
+    }
+
+    void handleStreamReset(ResetFrame resetFrame) throws IOException {
+        // TODO: cleanup
+        throw new IOException("Stream reset");
+    }
+
+    private void handleCommonFrame(Http2Frame f) throws IOException {
+        if (f instanceof SettingsFrame) {
+            serverSettings = (SettingsFrame) f;
+            if (serverSettings.getFlag(SettingsFrame.ACK)) // ignore
+            {
+                return;
+            }
+            // otherwise acknowledge it
+            SettingsFrame frame = new SettingsFrame();
+            frame.setFlag(SettingsFrame.ACK);
+            frame.streamid(0);
+            outputQ.put(frame);
+            return;
+        }
+        System.err.println("Received ---> " + f.toString());
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    void sendWindowUpdates(int len, int streamid) throws IOException {
+        if (len == 0)
+            return;
+        WindowUpdateFrame wup = new WindowUpdateFrame();
+        wup.streamid(streamid);
+        wup.setUpdate(len);
+        outputQ.put(wup);
+        wup = new WindowUpdateFrame();
+        wup.streamid(0);
+        wup.setUpdate(len);
+        outputQ.put(wup);
+    }
+
+    HttpHeadersImpl decodeHeaders(List<HeaderFrame> frames) {
+        HttpHeadersImpl headers = new HttpHeadersImpl();
+
+        DecodingCallback cb = (name, value) -> {
+            headers.addHeader(name.toString(), value.toString());
+        };
+
+        for (HeaderFrame frame : frames) {
+            ByteBuffer[] buffers = frame.getHeaderBlock();
+            for (ByteBuffer buffer : buffers) {
+                hpackIn.decode(buffer, false, cb);
+            }
+        }
+        hpackIn.decode(EMPTY_BUFFER, true, cb);
+        return headers;
+    }
+
+    String getRequestLine(String request) {
+        int eol = request.indexOf(CRLF);
+        return request.substring(0, eol);
+    }
+
+    // First stream (1) comes from a plaintext HTTP/1.1 request
+    @SuppressWarnings({"rawtypes","unchecked"})
+    void createPrimordialStream(String request) throws IOException {
+        HttpHeadersImpl headers = new HttpHeadersImpl();
+        String requestLine = getRequestLine(request);
+        String[] tokens = requestLine.split(" ");
+        if (!tokens[2].equals("HTTP/1.1")) {
+            throw new IOException("bad request line");
+        }
+        URI uri = null;
+        try {
+            uri = new URI(tokens[1]);
+        } catch (URISyntaxException e) {
+            throw new IOException(e);
+        }
+        String host = getHeader(request, "Host");
+        if (host == null) {
+            throw new IOException("missing Host");
+        }
+
+        headers.setHeader(":method", tokens[0]);
+        headers.setHeader(":scheme", "http"); // always in this case
+        headers.setHeader(":authority", host);
+        headers.setHeader(":path", uri.getPath());
+        Queue q = new Queue();
+        String body = getRequestBody(request);
+        headers.setHeader("Content-length", Integer.toString(body.length()));
+
+        addRequestBodyToQueue(body, q);
+        streams.put(1, q);
+        exec.submit(() -> {
+            handleRequest(headers, q, 1);
+        });
+    }
+
+    // all other streams created here
+    @SuppressWarnings({"rawtypes","unchecked"})
+    void createStream(HeaderFrame frame) throws IOException {
+        List<HeaderFrame> frames = new LinkedList<>();
+        frames.add(frame);
+        int streamid = frame.streamid();
+        if (streamid != nextstream) {
+            throw new IOException("unexpected stream id");
+        }
+        nextstream += 2;
+
+        while (!frame.getFlag(HeaderFrame.END_HEADERS)) {
+            Http2Frame f = readFrame();
+            if (!(f instanceof HeaderFrame)) {
+                handleCommonFrame(f); // should only be error frames
+            } else {
+                frame = (HeaderFrame) f;
+                frames.add(frame);
+            }
+        }
+        HttpHeadersImpl headers = decodeHeaders(frames);
+        Queue q = new Queue();
+        streams.put(streamid, q);
+        exec.submit(() -> {
+            handleRequest(headers, q, streamid);
+        });
+    }
+
+    // runs in own thread. Handles request from start to finish. Incoming frames
+    // for this stream/request delivered on Q
+
+    @SuppressWarnings({"rawtypes","unchecked"})
+    void handleRequest(HttpHeadersImpl headers, Queue queue, int streamid) {
+        String method = headers.firstValue(":method").orElse("");
+        System.out.println("method = " + method);
+        String path = headers.firstValue(":path").orElse("");
+        System.out.println("path = " + path);
+        String scheme = headers.firstValue(":scheme").orElse("");
+        System.out.println("scheme = " + scheme);
+        String authority = headers.firstValue(":authority").orElse("");
+        System.out.println("authority = " + authority);
+        HttpHeadersImpl rspheaders = new HttpHeadersImpl();
+        int winsize = clientSettings.getParameter(
+                        SettingsFrame.INITIAL_WINDOW_SIZE);
+        System.err.println ("Stream window size = " + winsize);
+        try (
+            BodyInputStream bis = new BodyInputStream(queue, streamid, this);
+            BodyOutputStream bos = new BodyOutputStream(streamid, winsize, this);
+        )
+        {
+            String us = scheme + "://" + authority + path;
+            URI uri = new URI(us);
+            boolean pushAllowed = clientSettings.getParameter(SettingsFrame.ENABLE_PUSH) == 1;
+            Http2TestExchange exchange = new Http2TestExchange(streamid, method,
+                    headers, rspheaders, uri, bis, bos, this, pushAllowed);
+
+            // give to user
+            handler.handle(exchange);
+
+            // everything happens in the exchange from here. Hopefully will
+            // return though.
+        } catch (Throwable e) {
+            System.err.println("TestServer: handleRequest exception: " + e);
+            e.printStackTrace();
+        }
+    }
+
+    // Runs in own thread
+
+    @SuppressWarnings({"rawtypes","unchecked"})
+    void readLoop() {
+        try {
+            while (!stopping) {
+                Http2Frame frame = readFrame();
+                int stream = frame.streamid();
+                if (stream == 0) {
+                    if (frame.type() == WindowUpdateFrame.TYPE) {
+                        WindowUpdateFrame wup = (WindowUpdateFrame) frame;
+                        updateConnectionWindow(wup.getUpdate());
+                    } else {
+                        // other common frame types
+                        handleCommonFrame(frame);
+                    }
+                } else {
+                    Queue q = streams.get(stream);
+                    if (frame.type() == HeadersFrame.TYPE) {
+                        if (q != null) {
+                            System.err.println("HEADERS frame for existing stream! Error.");
+                            // TODO: close connection
+                            continue;
+                        } else {
+                            createStream((HeadersFrame) frame);
+                        }
+                    } else {
+                        if (q == null) {
+                            System.err.printf("Non Headers frame received with"+
+                                " non existing stream (%d) ", frame.streamid());
+                            System.err.println(frame);
+                            continue;
+                        }
+                        if (frame.type() == WindowUpdateFrame.TYPE) {
+                            WindowUpdateFrame wup = (WindowUpdateFrame) frame;
+                            synchronized (updaters) {
+                                Consumer<Integer> r = updaters.get(stream);
+                                r.accept(wup.getUpdate());
+                            }
+                        } else {
+                            q.put(frame);
+                        }
+                    }
+                }
+            }
+        } catch (Throwable e) {
+            close();
+            if (!stopping) {
+                System.err.println("Http server reader thread shutdown");
+                e.printStackTrace();
+            }
+        }
+    }
+
+    // set streamid outside plus other specific fields
+    void encodeHeaders(HttpHeadersImpl headers, HeaderFrame out) {
+        List<ByteBuffer> buffers = new LinkedList<>();
+
+        ByteBuffer buf = getBuffer();
+        boolean encoded;
+        for (Map.Entry<String, List<String>> entry : headers.map().entrySet()) {
+            List<String> values = entry.getValue();
+            String key = entry.getKey().toLowerCase();
+            for (String value : values) {
+                do {
+                    hpackOut.header(key, value);
+                    encoded = hpackOut.encode(buf);
+                    if (!encoded) {
+                        buf.flip();
+                        buffers.add(buf);
+                        buf = getBuffer();
+                    }
+                } while (!encoded);
+            }
+        }
+        buf.flip();
+        buffers.add(buf);
+        out.setFlags(HeaderFrame.END_HEADERS);
+        out.setHeaderBlock(buffers.toArray(bbarray));
+    }
+
+    static void closeIgnore(Closeable c) {
+        try {
+            c.close();
+        } catch (IOException e) {}
+    }
+
+    // Runs in own thread
+    void writeLoop() {
+        try {
+            while (!stopping) {
+                Http2Frame frame = outputQ.take();
+                if (frame instanceof ResponseHeaders) {
+                    ResponseHeaders rh = (ResponseHeaders)frame;
+                    HeadersFrame hf = new HeadersFrame();
+                    encodeHeaders(rh.headers, hf);
+                    hf.streamid(rh.streamid());
+                    writeFrame(hf);
+                } else if (frame instanceof OutgoingPushPromise) {
+                    handlePush((OutgoingPushPromise)frame);
+                } else
+                    writeFrame(frame);
+            }
+            System.err.println("Connection writer stopping");
+        } catch (Throwable e) {
+            e.printStackTrace();
+            /*close();
+            if (!stopping) {
+                e.printStackTrace();
+                System.err.println("TestServer: writeLoop exception: " + e);
+            }*/
+        }
+    }
+
+    private void handlePush(OutgoingPushPromise op) throws IOException {
+        PushPromiseFrame pp = new PushPromiseFrame();
+        encodeHeaders(op.headers, pp);
+        int promisedStreamid = nextPushStreamId;
+        nextPushStreamId += 2;
+        pp.streamid(op.parentStream);
+        pp.setPromisedStream(promisedStreamid);
+        writeFrame(pp);
+        final InputStream ii = op.is;
+        final BodyOutputStream oo = new BodyOutputStream(
+                promisedStreamid,
+                clientSettings.getParameter(
+                        SettingsFrame.INITIAL_WINDOW_SIZE), this);
+        oo.goodToGo();
+        exec.submit(() -> {
+            try {
+                ResponseHeaders oh = getPushResponse(promisedStreamid);
+                outputQ.put(oh);
+                ii.transferTo(oo);
+            } catch (Throwable ex) {
+                System.err.printf("TestServer: pushing response error: %s\n",
+                        ex.toString());
+            } finally {
+                closeIgnore(ii);
+                closeIgnore(oo);
+            }
+        });
+
+    }
+
+    // returns a minimal response with status 200
+    // that is the response to the push promise just sent
+    private ResponseHeaders getPushResponse(int streamid) {
+        HttpHeadersImpl h = new HttpHeadersImpl();
+        h.addHeader(":status", "200");
+        ResponseHeaders oh = new ResponseHeaders(h);
+        oh.streamid(streamid);
+        return oh;
+    }
+
+    private ByteBuffer getBuffer() {
+        return ByteBuffer.allocate(8 * 1024);
+    }
+
+    private Http2Frame readFrame() throws IOException {
+        byte[] buf = new byte[9];
+        if (is.readNBytes(buf, 0, 9) != 9)
+            throw new IOException("readFrame: connection closed");
+        int len = 0;
+        for (int i = 0; i < 3; i++) {
+            int n = buf[i] & 0xff;
+            //System.err.println("n = " + n);
+            len = (len << 8) + n;
+        }
+        byte[] rest = new byte[len];
+        int n = is.readNBytes(rest, 0, len);
+        if (n != len)
+            throw new IOException("Error reading frame");
+        ByteBufferConsumer bc = new ByteBufferConsumer(
+                new LinkedList<ByteBuffer>(List.of(ByteBuffer.wrap(buf), ByteBuffer.wrap(rest))),
+                this::getBuffer);
+        return Http2Frame.readIncoming(bc);
+    }
+
+    void sendSettingsFrame() throws IOException {
+        sendSettingsFrame(false);
+    }
+
+    void sendSettingsFrame(boolean now) throws IOException {
+        if (serverSettings == null) {
+            serverSettings = SettingsFrame.getDefaultSettings();
+        }
+        if (now) {
+            writeFrame(serverSettings);
+        } else {
+            outputQ.put(serverSettings);
+        }
+    }
+
+    String readUntil(String end) throws IOException {
+        int number = end.length();
+        int found = 0;
+        StringBuilder sb = new StringBuilder();
+        while (found < number) {
+            char expected = end.charAt(found);
+            int c = is.read();
+            if (c == -1) {
+                throw new IOException("Connection closed");
+            }
+            char c0 = (char) c;
+            sb.append(c0);
+            if (c0 != expected) {
+                found = 0;
+                continue;
+            }
+            found++;
+        }
+        return sb.toString();
+    }
+
+    private int getContentLength(String headers) {
+        return getIntHeader(headers, "Content-length");
+    }
+
+    private int getIntHeader(String headers, String name) {
+        String val = getHeader(headers, name);
+        if (val == null) {
+            return -1;
+        }
+        return Integer.parseInt(val);
+    }
+
+    private String getHeader(String headers, String name) {
+        String headers1 = headers.toLowerCase(); // not efficient
+        name = CRLF + name.toLowerCase();
+        int start = headers1.indexOf(name);
+        if (start == -1) {
+            return null;
+        }
+        start += 2;
+        int end = headers1.indexOf(CRLF, start);
+        String line = headers.substring(start, end);
+        start = line.indexOf(':');
+        if (start == -1) {
+            return null;
+        }
+        return line.substring(start + 1).trim();
+    }
+
+    final static String CRLF = "\r\n";
+
+    String readHttp1Request() throws IOException {
+        String headers = readUntil(CRLF + CRLF);
+        int clen = getContentLength(headers);
+        // read the content. There shouldn't be content but ..
+        byte[] buf = new byte[clen];
+        is.readNBytes(buf, 0, clen);
+        String body = new String(buf, "US-ASCII");
+        return headers + body;
+    }
+
+    void sendHttp1Response(int code, String msg, String... headers) throws IOException {
+        StringBuilder sb = new StringBuilder();
+        sb.append("HTTP/1.1 ")
+                .append(code)
+                .append(' ')
+                .append(msg)
+                .append(CRLF);
+        int numheaders = headers.length;
+        for (int i = 0; i < numheaders; i += 2) {
+            sb.append(headers[i])
+                    .append(": ")
+                    .append(headers[i + 1])
+                    .append(CRLF);
+        }
+        sb.append(CRLF);
+        String s = sb.toString();
+        os.write(s.getBytes("US-ASCII"));
+        os.flush();
+    }
+
+    private void unexpectedFrame(Http2Frame frame) {
+        System.err.println("OOPS. Unexpected");
+        assert false;
+    }
+
+    final static ByteBuffer[] bbarray = new ByteBuffer[0];
+
+    // wrapper around a BlockingQueue that throws an exception when it's closed
+    // Each stream has one of these
+
+    String getRequestBody(String request) {
+        int bodystart = request.indexOf(CRLF+CRLF);
+        String body;
+        if (bodystart == -1)
+            body = "";
+        else
+            body = request.substring(bodystart+4);
+        return body;
+    }
+
+    @SuppressWarnings({"rawtypes","unchecked"})
+    void addRequestBodyToQueue(String body, Queue q) throws IOException {
+        ByteBuffer buf = ByteBuffer.wrap(body.getBytes(StandardCharsets.US_ASCII));
+        DataFrame df = new DataFrame();
+        df.streamid(1); // only used for primordial stream
+        df.setData(buf);
+        df.computeLength();
+        df.setFlag(DataFrame.END_STREAM);
+        q.put(df);
+    }
+
+    // window updates done in main reader thread because they may
+    // be used to unblock BodyOutputStreams waiting for WUPs
+
+    HashMap<Integer,Consumer<Integer>> updaters = new HashMap<>();
+
+    void registerStreamWindowUpdater(int streamid, Consumer<Integer> r) {
+        synchronized(updaters) {
+            updaters.put(streamid, r);
+        }
+    }
+
+    int sendWindow = 64 * 1024 - 1; // connection level send window
+
+    /**
+     * BodyOutputStreams call this to get the connection window first.
+     *
+     * @param amount
+     */
+    synchronized void obtainConnectionWindow(int amount) throws InterruptedException {
+       while (amount > 0) {
+           int n = Math.min(amount, sendWindow);
+           amount -= n;
+           sendWindow -= n;
+           if (amount > 0)
+               wait();
+       }
+    }
+
+    synchronized void updateConnectionWindow(int amount) {
+        sendWindow += amount;
+        notifyAll();
+    }
+
+    // simplified output headers class. really just a type safe container
+    // for the hashmap.
+
+    static class ResponseHeaders extends Http2Frame {
+        HttpHeadersImpl headers;
+
+        ResponseHeaders(HttpHeadersImpl headers) {
+            this.headers = headers;
+        }
+
+        @Override
+        void readIncomingImpl(ByteBufferConsumer bc) throws IOException {
+            throw new UnsupportedOperationException("Not supported ever!");
+        }
+
+        @Override
+        void computeLength() {
+            throw new UnsupportedOperationException("Not supported ever!");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/OutgoingPushPromise.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,31 @@
+package java.net.http;
+
+import java.io.*;
+import java.net.*;
+
+// will be converted to a PushPromiseFrame in the writeLoop
+// a thread is then created to produce the DataFrames from the InputStream
+class OutgoingPushPromise extends Http2Frame {
+    final HttpHeadersImpl headers;
+    final URI uri;
+    final InputStream is;
+    final int parentStream; // not the pushed streamid
+
+    OutgoingPushPromise(int parentStream, URI uri, HttpHeadersImpl headers, InputStream is) {
+        this.uri = uri;
+        this.headers = headers;
+        this.is = is;
+        this.parentStream = parentStream;
+    }
+
+    @Override
+    void readIncomingImpl(ByteBufferConsumer bc) throws IOException {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    void computeLength() {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/PushHandler.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2015, 2016, 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 java.net.http;
+
+import java.io.*;
+import java.net.*;
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.net.http.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+public class PushHandler implements Http2Handler {
+
+    final Path tempFile;
+    final int loops;
+
+    public PushHandler(int file_size, int loops) throws Exception {
+        tempFile = TestUtil.getAFile(file_size);
+        this.loops = loops;
+    }
+
+    int invocation = 0;
+
+    public void handle(Http2TestExchange ee) {
+        try {
+            System.err.println ("Server: handle " + ee);
+            invocation++;
+
+            if (ee.serverPushAllowed()) {
+                for (int i=0; i<loops; i++) {
+                    InputStream is = new FileInputStream(tempFile.toFile());
+                    URI u = new URI ("http://www.foo.com/" + Integer.toString(i));
+                    HttpHeadersImpl h = new HttpHeadersImpl();
+                    h.addHeader("X-foo", "bar");
+                    ee.serverPush(u, h, is);
+                }
+                System.err.println ("Server: sent all pushes");
+            }
+            ee.sendResponseHeaders(200, 0);
+            OutputStream os = ee.getResponseBody();
+            InputStream iis = new FileInputStream(tempFile.toFile());
+            iis.transferTo(os);
+            os.close();
+            iis.close();
+        } catch (Exception ex) {
+            System.err.println ("Server: exception " + ex);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/TestUtil.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2015, 2016, 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 java.net.http;
+
+import java.io.*;
+import java.net.*;
+import java.nio.file.*;
+import java.util.concurrent.*;
+import java.util.Arrays;
+
+public class TestUtil {
+
+    final static String fileContent = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; // repeated
+
+    public static Path getAFile(int size) throws IOException {
+        Path p = tempFile();
+        BufferedWriter writer = Files.newBufferedWriter(p);
+        int len = fileContent.length();
+        int iterations = size / len;
+        int remainder = size - (iterations * len);
+        for (int i=0; i<iterations; i++)
+            writer.write(fileContent, 0, len);
+        writer.write(fileContent, 0, remainder);
+        writer.close();
+        return p;
+    }
+
+    public static Path tempFile() {
+        try {
+            Path p = Files.createTempFile("foo", "test");
+            p.toFile().deleteOnExit();
+            return p;
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    public static Void compareFiles(Path path1, Path path2) {
+        try {
+            if (Files.size(path1) != Files.size(path2))
+                throw new RuntimeException("File sizes do not match");
+            compareContents(path1, path2);
+            return null;
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    static void compareContents(Path path1, Path path2) {
+        try {
+            byte[] b1 = Files.readAllBytes(path1);
+            byte[] b2 = Files.readAllBytes(path2);
+            if (!Arrays.equals(b1, b2))
+                throw new RuntimeException ("Files do not match");
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/BinaryPrimitivesTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2014, 2016, 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 sun.net.httpclient.hpack;
+
+import org.testng.annotations.Test;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+import static sun.net.httpclient.hpack.BuffersTestingKit.*;
+import static sun.net.httpclient.hpack.TestHelper.newRandom;
+
+//
+// Some of the tests below overlap in what they test. This allows to diagnose
+// bugs quicker and with less pain by simply ruling out common working bits.
+//
+public final class BinaryPrimitivesTest {
+
+    private final Random rnd = newRandom();
+
+    @Test
+    public void integerRead1() {
+        verifyRead(bytes(0b00011111, 0b10011010, 0b00001010), 1337, 5);
+    }
+
+    @Test
+    public void integerRead2() {
+        verifyRead(bytes(0b00001010), 10, 5);
+    }
+
+    @Test
+    public void integerRead3() {
+        verifyRead(bytes(0b00101010), 42, 8);
+    }
+
+    @Test
+    public void integerWrite1() {
+        verifyWrite(bytes(0b00011111, 0b10011010, 0b00001010), 1337, 5);
+    }
+
+    @Test
+    public void integerWrite2() {
+        verifyWrite(bytes(0b00001010), 10, 5);
+    }
+
+    @Test
+    public void integerWrite3() {
+        verifyWrite(bytes(0b00101010), 42, 8);
+    }
+
+    //
+    // Since readInteger(x) is the inverse of writeInteger(x), thus:
+    //
+    // for all x: readInteger(writeInteger(x)) == x
+    //
+    @Test
+    public void integerIdentity() {
+        final int MAX_VALUE = 1 << 22;
+        int totalCases = 0;
+        int maxFilling = 0;
+        IntegerReader r = new IntegerReader();
+        IntegerWriter w = new IntegerWriter();
+        ByteBuffer buf = ByteBuffer.allocate(8);
+        for (int N = 1; N < 9; N++) {
+            for (int expected = 0; expected <= MAX_VALUE; expected++) {
+                w.reset().configure(expected, N, 1).write(buf);
+                buf.flip();
+                totalCases++;
+                maxFilling = Math.max(maxFilling, buf.remaining());
+                r.reset().configure(N).read(buf);
+                assertEquals(r.get(), expected);
+                buf.clear();
+            }
+        }
+        System.out.printf("totalCases: %,d, maxFilling: %,d, maxValue: %,d%n",
+                totalCases, maxFilling, MAX_VALUE);
+    }
+
+    @Test
+    public void integerReadChunked() {
+        final int NUM_TESTS = 1024;
+        IntegerReader r = new IntegerReader();
+        ByteBuffer bb = ByteBuffer.allocate(8);
+        IntegerWriter w = new IntegerWriter();
+        for (int i = 0; i < NUM_TESTS; i++) {
+            final int N = 1 + rnd.nextInt(8);
+            final int expected = rnd.nextInt(Integer.MAX_VALUE) + 1;
+            w.reset().configure(expected, N, rnd.nextInt()).write(bb);
+            bb.flip();
+
+            forEachSplit(bb,
+                    (buffers) -> {
+                        Iterable<? extends ByteBuffer> buf = relocateBuffers(injectEmptyBuffers(buffers));
+                        r.configure(N);
+                        for (ByteBuffer b : buf) {
+                            r.read(b);
+                        }
+                        assertEquals(r.get(), expected);
+                        r.reset();
+                    });
+            bb.clear();
+        }
+    }
+
+    // FIXME: use maxValue in the test
+
+    @Test
+    // FIXME: tune values for better coverage
+    public void integerWriteChunked() {
+        ByteBuffer bb = ByteBuffer.allocate(6);
+        IntegerWriter w = new IntegerWriter();
+        IntegerReader r = new IntegerReader();
+        for (int i = 0; i < 1024; i++) { // number of tests
+            final int N = 1 + rnd.nextInt(8);
+            final int payload = rnd.nextInt(255);
+            final int expected = rnd.nextInt(Integer.MAX_VALUE) + 1;
+
+            forEachSplit(bb,
+                    (buffers) -> {
+                        List<ByteBuffer> buf = new ArrayList<>();
+                        relocateBuffers(injectEmptyBuffers(buffers)).forEach(buf::add);
+                        boolean written = false;
+                        w.configure(expected, N, payload); // TODO: test for payload it can be read after written
+                        for (ByteBuffer b : buf) {
+                            int pos = b.position();
+                            written = w.write(b);
+                            b.position(pos);
+                        }
+                        if (!written) {
+                            fail("please increase bb size");
+                        }
+                        r.configure(N).read(concat(buf));
+                        // TODO: check payload here
+                        assertEquals(r.get(), expected);
+                        w.reset();
+                        r.reset();
+                        bb.clear();
+                    });
+        }
+    }
+
+
+    //
+    // Since readString(x) is the inverse of writeString(x), thus:
+    //
+    // for all x: readString(writeString(x)) == x
+    //
+    @Test
+    public void stringIdentity() {
+        final int MAX_STRING_LENGTH = 4096;
+        ByteBuffer bytes = ByteBuffer.allocate(MAX_STRING_LENGTH + 6); // it takes 6 bytes to encode string length of Integer.MAX_VALUE
+        CharBuffer chars = CharBuffer.allocate(MAX_STRING_LENGTH);
+        StringReader reader = new StringReader();
+        StringWriter writer = new StringWriter();
+        for (int len = 0; len <= MAX_STRING_LENGTH; len++) {
+            for (int i = 0; i < 64; i++) {
+                // not so much "test in isolation", I know... we're testing .reset() as well
+                bytes.clear();
+                chars.clear();
+
+                byte[] b = new byte[len];
+                rnd.nextBytes(b);
+
+                String expected = new String(b, StandardCharsets.ISO_8859_1); // reference string
+
+                boolean written = writer
+                        .configure(CharBuffer.wrap(expected), 0, expected.length(), false)
+                        .write(bytes);
+
+                if (!written) {
+                    fail("please increase 'bytes' size");
+                }
+                bytes.flip();
+                reader.read(bytes, chars);
+                chars.flip();
+                assertEquals(chars.toString(), expected);
+                reader.reset();
+                writer.reset();
+            }
+        }
+    }
+
+//    @Test
+//    public void huffmanStringWriteChunked() {
+//        fail();
+//    }
+//
+//    @Test
+//    public void huffmanStringReadChunked() {
+//        fail();
+//    }
+
+    @Test
+    public void stringWriteChunked() {
+        final int MAX_STRING_LENGTH = 8;
+        final ByteBuffer bytes = ByteBuffer.allocate(MAX_STRING_LENGTH + 6);
+        final CharBuffer chars = CharBuffer.allocate(MAX_STRING_LENGTH);
+        final StringReader reader = new StringReader();
+        final StringWriter writer = new StringWriter();
+        for (int len = 0; len <= MAX_STRING_LENGTH; len++) {
+
+            byte[] b = new byte[len];
+            rnd.nextBytes(b);
+
+            String expected = new String(b, StandardCharsets.ISO_8859_1); // reference string
+
+            forEachSplit(bytes, (buffers) -> {
+                writer.configure(expected, 0, expected.length(), false);
+                boolean written = false;
+                for (ByteBuffer buf : buffers) {
+                    int p0 = buf.position();
+                    written = writer.write(buf);
+                    buf.position(p0);
+                }
+                if (!written) {
+                    fail("please increase 'bytes' size");
+                }
+                reader.read(concat(buffers), chars);
+                chars.flip();
+                assertEquals(chars.toString(), expected);
+                reader.reset();
+                writer.reset();
+                chars.clear();
+                bytes.clear();
+            });
+        }
+    }
+
+    @Test
+    public void stringReadChunked() {
+        final int MAX_STRING_LENGTH = 16;
+        final ByteBuffer bytes = ByteBuffer.allocate(MAX_STRING_LENGTH + 6);
+        final CharBuffer chars = CharBuffer.allocate(MAX_STRING_LENGTH);
+        final StringReader reader = new StringReader();
+        final StringWriter writer = new StringWriter();
+        for (int len = 0; len <= MAX_STRING_LENGTH; len++) {
+
+            byte[] b = new byte[len];
+            rnd.nextBytes(b);
+
+            String expected = new String(b, StandardCharsets.ISO_8859_1); // reference string
+
+            boolean written = writer
+                    .configure(CharBuffer.wrap(expected), 0, expected.length(), false)
+                    .write(bytes);
+            writer.reset();
+
+            if (!written) {
+                fail("please increase 'bytes' size");
+            }
+            bytes.flip();
+
+            forEachSplit(bytes, (buffers) -> {
+                for (ByteBuffer buf : buffers) {
+                    int p0 = buf.position();
+                    reader.read(buf, chars);
+                    buf.position(p0);
+                }
+                chars.flip();
+                assertEquals(chars.toString(), expected);
+                reader.reset();
+                chars.clear();
+            });
+
+            bytes.clear();
+        }
+    }
+
+//    @Test
+//    public void test_Huffman_String_Identity() {
+//        StringWriter writer = new StringWriter();
+//        StringReader reader = new StringReader();
+//        // 256 * 8 gives 2048 bits in case of plain 8 bit coding
+//        // 256 * 30 gives you 7680 bits or 960 bytes in case of almost
+//        //          improbable event of 256 30 bits symbols in a row
+//        ByteBuffer binary = ByteBuffer.allocate(960);
+//        CharBuffer text = CharBuffer.allocate(960 / 5); // 5 = minimum code length
+//        for (int len = 0; len < 128; len++) {
+//            for (int i = 0; i < 256; i++) {
+//                // not so much "test in isolation", I know...
+//                binary.clear();
+//
+//                byte[] bytes = new byte[len];
+//                rnd.nextBytes(bytes);
+//
+//                String s = new String(bytes, StandardCharsets.ISO_8859_1);
+//
+//                writer.write(CharBuffer.wrap(s), binary, true);
+//                binary.flip();
+//                reader.read(binary, text);
+//                text.flip();
+//                assertEquals(text.toString(), s);
+//            }
+//        }
+//    }
+
+    // TODO: atomic failures: e.g. readonly/overflow
+
+    private static byte[] bytes(int... data) {
+        byte[] bytes = new byte[data.length];
+        for (int i = 0; i < data.length; i++) {
+            bytes[i] = (byte) data[i];
+        }
+        return bytes;
+    }
+
+    private static void verifyRead(byte[] data, int expected, int N) {
+        ByteBuffer buf = ByteBuffer.wrap(data, 0, data.length);
+        IntegerReader reader = new IntegerReader();
+        reader.configure(N).read(buf);
+        assertEquals(expected, reader.get());
+    }
+
+    private void verifyWrite(byte[] expected, int data, int N) {
+        IntegerWriter w = new IntegerWriter();
+        ByteBuffer buf = ByteBuffer.allocate(2 * expected.length);
+        w.configure(data, N, 1).write(buf);
+        buf.flip();
+        assertEquals(ByteBuffer.wrap(expected), buf);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/BuffersTestingKit.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2015, 2016, 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 sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+import java.util.*;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+import static java.nio.ByteBuffer.allocate;
+
+public final class BuffersTestingKit {
+
+    /**
+     * Relocates a {@code [position, limit)} region of the given buffer to
+     * corresponding region in a new buffer starting with provided {@code
+     * newPosition}.
+     *
+     * <p> Might be useful to make sure ByteBuffer's users do not rely on any
+     * absolute positions, but solely on what's reported by position(), limit().
+     *
+     * <p> The contents between the given buffer and the returned one are not
+     * shared.
+     */
+    public static ByteBuffer relocate(ByteBuffer buffer, int newPosition,
+                                      int newCapacity) {
+        int oldPosition = buffer.position();
+        int oldLimit = buffer.limit();
+
+        if (newPosition + oldLimit - oldPosition > newCapacity) {
+            throw new IllegalArgumentException();
+        }
+
+        ByteBuffer result;
+        if (buffer.isDirect()) {
+            result = ByteBuffer.allocateDirect(newCapacity);
+        } else {
+            result = allocate(newCapacity);
+        }
+
+        result.position(newPosition);
+        result.put(buffer).limit(result.position()).position(newPosition);
+        buffer.position(oldPosition);
+
+        if (buffer.isReadOnly()) {
+            return result.asReadOnlyBuffer();
+        }
+        return result;
+    }
+
+    public static Iterable<? extends ByteBuffer> relocateBuffers(
+            Iterable<? extends ByteBuffer> source) {
+        return () ->
+                new Iterator<ByteBuffer>() {
+
+                    private final Iterator<? extends ByteBuffer> it = source.iterator();
+
+                    @Override
+                    public boolean hasNext() {
+                        return it.hasNext();
+                    }
+
+                    @Override
+                    public ByteBuffer next() {
+                        ByteBuffer buf = it.next();
+                        int remaining = buf.remaining();
+                        int newCapacity = remaining + random.nextInt(17);
+                        int newPosition = random.nextInt(newCapacity - remaining + 1);
+                        return relocate(buf, newPosition, newCapacity);
+                    }
+                };
+    }
+
+    // TODO: not always of size 0 (it's fine for buffer to report !b.hasRemaining())
+    public static Iterable<? extends ByteBuffer> injectEmptyBuffers(
+            Iterable<? extends ByteBuffer> source) {
+        return injectEmptyBuffers(source, () -> allocate(0));
+    }
+
+    public static Iterable<? extends ByteBuffer> injectEmptyBuffers(
+            Iterable<? extends ByteBuffer> source,
+            Supplier<? extends ByteBuffer> emptyBufferFactory) {
+
+        return () ->
+                new Iterator<ByteBuffer>() {
+
+                    private final Iterator<? extends ByteBuffer> it = source.iterator();
+                    private ByteBuffer next = calculateNext();
+
+                    private ByteBuffer calculateNext() {
+                        if (random.nextBoolean()) {
+                            return emptyBufferFactory.get();
+                        } else if (it.hasNext()) {
+                            return it.next();
+                        } else {
+                            return null;
+                        }
+                    }
+
+                    @Override
+                    public boolean hasNext() {
+                        return next != null;
+                    }
+
+                    @Override
+                    public ByteBuffer next() {
+                        if (!hasNext()) {
+                            throw new NoSuchElementException();
+                        }
+                        ByteBuffer next = this.next;
+                        this.next = calculateNext();
+                        return next;
+                    }
+                };
+    }
+
+    public static ByteBuffer concat(Iterable<? extends ByteBuffer> split) {
+        return concat(split, ByteBuffer::allocate);
+    }
+
+    public static ByteBuffer concat(Iterable<? extends ByteBuffer> split,
+                                    Function<? super Integer, ? extends ByteBuffer> concatBufferFactory) {
+        int size = 0;
+        for (ByteBuffer bb : split) {
+            size += bb.remaining();
+        }
+
+        ByteBuffer result = concatBufferFactory.apply(size);
+        for (ByteBuffer bb : split) {
+            result.put(bb);
+        }
+
+        result.flip();
+        return result;
+    }
+
+    public static void forEachSplit(ByteBuffer bb,
+                                    Consumer<? super Iterable<? extends ByteBuffer>> action) {
+        forEachSplit(bb.remaining(),
+                (lengths) -> {
+                    int end = bb.position();
+                    List<ByteBuffer> buffers = new LinkedList<>();
+                    for (int len : lengths) {
+                        ByteBuffer d = bb.duplicate();
+                        d.position(end);
+                        d.limit(end + len);
+                        end += len;
+                        buffers.add(d);
+                    }
+                    action.accept(buffers);
+                });
+    }
+
+    private static void forEachSplit(int n, Consumer<? super Iterable<? extends Integer>> action) {
+        forEachSplit(n, new Stack<>(), action);
+    }
+
+    private static void forEachSplit(int n, Stack<Integer> path,
+                                     Consumer<? super Iterable<? extends Integer>> action) {
+        if (n == 0) {
+            action.accept(path);
+        } else {
+            for (int i = 1; i <= n; i++) {
+                path.push(i);
+                forEachSplit(n - i, path, action);
+                path.pop();
+            }
+        }
+    }
+
+    private static final Random random = new Random();
+
+    private BuffersTestingKit() {
+        throw new InternalError();
+    }
+
+//    public static void main(String[] args) {
+//
+//        List<ByteBuffer> buffers = Arrays.asList(
+//                (ByteBuffer) allocate(3).position(1).limit(2),
+//                allocate(0),
+//                allocate(7));
+//
+//        Iterable<? extends ByteBuffer> buf = relocateBuffers(injectEmptyBuffers(buffers));
+//        List<ByteBuffer> result = new ArrayList<>();
+//        buf.forEach(result::add);
+//        System.out.println(result);
+//    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/CircularBufferTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2016, 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 sun.net.httpclient.hpack;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import sun.net.httpclient.hpack.HeaderTable.CircularBuffer;
+
+import java.util.Queue;
+import java.util.Random;
+import java.util.concurrent.ArrayBlockingQueue;
+
+import static org.testng.Assert.assertEquals;
+import static sun.net.httpclient.hpack.TestHelper.newRandom;
+
+public final class CircularBufferTest {
+
+    private final Random r = newRandom();
+
+    @BeforeClass
+    public void setUp() {
+        r.setSeed(System.currentTimeMillis());
+    }
+
+    @Test
+    public void queue() {
+        for (int capacity = 1; capacity <= 2048; capacity++) {
+            queueOnce(capacity, 32);
+        }
+    }
+
+    @Test
+    public void resize() {
+        for (int capacity = 1; capacity <= 4096; capacity++) {
+            resizeOnce(capacity);
+        }
+    }
+
+    @Test
+    public void downSizeEmptyBuffer() {
+        CircularBuffer<Integer> buffer = new CircularBuffer<>(16);
+        buffer.resize(15);
+    }
+
+    private void resizeOnce(int capacity) {
+
+        int nextNumberToPut = 0;
+
+        Queue<Integer> referenceQueue = new ArrayBlockingQueue<>(capacity);
+        CircularBuffer<Integer> buffer = new CircularBuffer<>(capacity);
+
+        // Fill full, so the next add will wrap
+        for (int i = 0; i < capacity; i++, nextNumberToPut++) {
+            buffer.add(nextNumberToPut);
+            referenceQueue.add(nextNumberToPut);
+        }
+        int gets = r.nextInt(capacity); // [0, capacity)
+        for (int i = 0; i < gets; i++) {
+            referenceQueue.poll();
+            buffer.remove();
+        }
+        int puts = r.nextInt(gets + 1); // [0, gets]
+        for (int i = 0; i < puts; i++, nextNumberToPut++) {
+            buffer.add(nextNumberToPut);
+            referenceQueue.add(nextNumberToPut);
+        }
+
+        Integer[] expected = referenceQueue.toArray(new Integer[0]);
+        buffer.resize(expected.length);
+
+        assertEquals(buffer.elements, expected);
+    }
+
+    private void queueOnce(int capacity, int numWraps) {
+
+        Queue<Integer> referenceQueue = new ArrayBlockingQueue<>(capacity);
+        CircularBuffer<Integer> buffer = new CircularBuffer<>(capacity);
+
+        int nextNumberToPut = 0;
+        int totalPuts = 0;
+        int putsLimit = capacity * numWraps;
+        int remainingCapacity = capacity;
+        int size = 0;
+
+        while (totalPuts < putsLimit) {
+            assert remainingCapacity + size == capacity;
+            int puts = r.nextInt(remainingCapacity + 1); // [0, remainingCapacity]
+            remainingCapacity -= puts;
+            size += puts;
+            for (int i = 0; i < puts; i++, nextNumberToPut++) {
+                referenceQueue.add(nextNumberToPut);
+                buffer.add(nextNumberToPut);
+            }
+            totalPuts += puts;
+            int gets = r.nextInt(size + 1); // [0, size]
+            size -= gets;
+            remainingCapacity += gets;
+            for (int i = 0; i < gets; i++) {
+                Integer expected = referenceQueue.poll();
+                Integer actual = buffer.remove();
+                assertEquals(actual, expected);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/DecoderTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,595 @@
+/*
+ * Copyright (c) 2015, 2016, 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 sun.net.httpclient.hpack;
+
+import org.testng.annotations.Test;
+
+import java.io.UncheckedIOException;
+import java.net.ProtocolException;
+import java.nio.ByteBuffer;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static sun.net.httpclient.hpack.TestHelper.*;
+
+public final class DecoderTest {
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.2.1
+    //
+    @Test
+    public void example1() {
+        // @formatter:off
+        test("400a 6375 7374 6f6d 2d6b 6579 0d63 7573\n" +
+             "746f 6d2d 6865 6164 6572",
+
+             "[  1] (s =  55) custom-key: custom-header\n" +
+             "      Table size:  55",
+
+             "custom-key: custom-header");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.2.2
+    //
+    @Test
+    public void example2() {
+        // @formatter:off
+        test("040c 2f73 616d 706c 652f 7061 7468",
+             "empty.",
+             ":path: /sample/path");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.2.3
+    //
+    @Test
+    public void example3() {
+        // @formatter:off
+        test("1008 7061 7373 776f 7264 0673 6563 7265\n" +
+             "74",
+             "empty.",
+             "password: secret");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.2.4
+    //
+    @Test
+    public void example4() {
+        // @formatter:off
+        test("82",
+             "empty.",
+             ":method: GET");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.3
+    //
+    @Test
+    public void example5() {
+        // @formatter:off
+        Decoder d = new Decoder(256);
+
+        test(d, "8286 8441 0f77 7777 2e65 7861 6d70 6c65\n" +
+                "2e63 6f6d",
+
+                "[  1] (s =  57) :authority: www.example.com\n" +
+                "      Table size:  57",
+
+                ":method: GET\n" +
+                ":scheme: http\n" +
+                ":path: /\n" +
+                ":authority: www.example.com");
+
+        test(d, "8286 84be 5808 6e6f 2d63 6163 6865",
+
+                "[  1] (s =  53) cache-control: no-cache\n" +
+                "[  2] (s =  57) :authority: www.example.com\n" +
+                "      Table size: 110",
+
+                ":method: GET\n" +
+                ":scheme: http\n" +
+                ":path: /\n" +
+                ":authority: www.example.com\n" +
+                "cache-control: no-cache");
+
+        test(d, "8287 85bf 400a 6375 7374 6f6d 2d6b 6579\n" +
+                "0c63 7573 746f 6d2d 7661 6c75 65",
+
+                "[  1] (s =  54) custom-key: custom-value\n" +
+                "[  2] (s =  53) cache-control: no-cache\n" +
+                "[  3] (s =  57) :authority: www.example.com\n" +
+                "      Table size: 164",
+
+                ":method: GET\n" +
+                ":scheme: https\n" +
+                ":path: /index.html\n" +
+                ":authority: www.example.com\n" +
+                "custom-key: custom-value");
+
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.4
+    //
+    @Test
+    public void example6() {
+        // @formatter:off
+        Decoder d = new Decoder(256);
+
+        test(d, "8286 8441 8cf1 e3c2 e5f2 3a6b a0ab 90f4\n" +
+                "ff",
+
+                "[  1] (s =  57) :authority: www.example.com\n" +
+                "      Table size:  57",
+
+                ":method: GET\n" +
+                ":scheme: http\n" +
+                ":path: /\n" +
+                ":authority: www.example.com");
+
+        test(d, "8286 84be 5886 a8eb 1064 9cbf",
+
+                "[  1] (s =  53) cache-control: no-cache\n" +
+                "[  2] (s =  57) :authority: www.example.com\n" +
+                "      Table size: 110",
+
+                ":method: GET\n" +
+                ":scheme: http\n" +
+                ":path: /\n" +
+                ":authority: www.example.com\n" +
+                "cache-control: no-cache");
+
+        test(d, "8287 85bf 4088 25a8 49e9 5ba9 7d7f 8925\n" +
+                "a849 e95b b8e8 b4bf",
+
+                "[  1] (s =  54) custom-key: custom-value\n" +
+                "[  2] (s =  53) cache-control: no-cache\n" +
+                "[  3] (s =  57) :authority: www.example.com\n" +
+                "      Table size: 164",
+
+                ":method: GET\n" +
+                ":scheme: https\n" +
+                ":path: /index.html\n" +
+                ":authority: www.example.com\n" +
+                "custom-key: custom-value");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.5
+    //
+    @Test
+    public void example7() {
+        // @formatter:off
+        Decoder d = new Decoder(256);
+
+        test(d, "4803 3330 3258 0770 7269 7661 7465 611d\n" +
+                "4d6f 6e2c 2032 3120 4f63 7420 3230 3133\n" +
+                "2032 303a 3133 3a32 3120 474d 546e 1768\n" +
+                "7474 7073 3a2f 2f77 7777 2e65 7861 6d70\n" +
+                "6c65 2e63 6f6d",
+
+                "[  1] (s =  63) location: https://www.example.com\n" +
+                "[  2] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+                "[  3] (s =  52) cache-control: private\n" +
+                "[  4] (s =  42) :status: 302\n" +
+                "      Table size: 222",
+
+                ":status: 302\n" +
+                "cache-control: private\n" +
+                "date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+                "location: https://www.example.com");
+
+        test(d, "4803 3330 37c1 c0bf",
+
+                "[  1] (s =  42) :status: 307\n" +
+                "[  2] (s =  63) location: https://www.example.com\n" +
+                "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+                "[  4] (s =  52) cache-control: private\n" +
+                "      Table size: 222",
+
+                ":status: 307\n" +
+                "cache-control: private\n" +
+                "date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+                "location: https://www.example.com");
+
+        test(d, "88c1 611d 4d6f 6e2c 2032 3120 4f63 7420\n" +
+                "3230 3133 2032 303a 3133 3a32 3220 474d\n" +
+                "54c0 5a04 677a 6970 7738 666f 6f3d 4153\n" +
+                "444a 4b48 514b 425a 584f 5157 454f 5049\n" +
+                "5541 5851 5745 4f49 553b 206d 6178 2d61\n" +
+                "6765 3d33 3630 303b 2076 6572 7369 6f6e\n" +
+                "3d31",
+
+                "[  1] (s =  98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1\n" +
+                "[  2] (s =  52) content-encoding: gzip\n" +
+                "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:22 GMT\n" +
+                "      Table size: 215",
+
+                ":status: 200\n" +
+                "cache-control: private\n" +
+                "date: Mon, 21 Oct 2013 20:13:22 GMT\n" +
+                "location: https://www.example.com\n" +
+                "content-encoding: gzip\n" +
+                "set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.6
+    //
+    @Test
+    public void example8() {
+        // @formatter:off
+        Decoder d = new Decoder(256);
+
+        test(d, "4882 6402 5885 aec3 771a 4b61 96d0 7abe\n" +
+                "9410 54d4 44a8 2005 9504 0b81 66e0 82a6\n" +
+                "2d1b ff6e 919d 29ad 1718 63c7 8f0b 97c8\n" +
+                "e9ae 82ae 43d3",
+
+                "[  1] (s =  63) location: https://www.example.com\n" +
+                "[  2] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+                "[  3] (s =  52) cache-control: private\n" +
+                "[  4] (s =  42) :status: 302\n" +
+                "      Table size: 222",
+
+                ":status: 302\n" +
+                "cache-control: private\n" +
+                "date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+                "location: https://www.example.com");
+
+        test(d, "4883 640e ffc1 c0bf",
+
+                "[  1] (s =  42) :status: 307\n" +
+                "[  2] (s =  63) location: https://www.example.com\n" +
+                "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+                "[  4] (s =  52) cache-control: private\n" +
+                "      Table size: 222",
+
+                ":status: 307\n" +
+                "cache-control: private\n" +
+                "date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+                "location: https://www.example.com");
+
+        test(d, "88c1 6196 d07a be94 1054 d444 a820 0595\n" +
+                "040b 8166 e084 a62d 1bff c05a 839b d9ab\n" +
+                "77ad 94e7 821d d7f2 e6c7 b335 dfdf cd5b\n" +
+                "3960 d5af 2708 7f36 72c1 ab27 0fb5 291f\n" +
+                "9587 3160 65c0 03ed 4ee5 b106 3d50 07",
+
+                "[  1] (s =  98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1\n" +
+                "[  2] (s =  52) content-encoding: gzip\n" +
+                "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:22 GMT\n" +
+                "      Table size: 215",
+
+                ":status: 200\n" +
+                "cache-control: private\n" +
+                "date: Mon, 21 Oct 2013 20:13:22 GMT\n" +
+                "location: https://www.example.com\n" +
+                "content-encoding: gzip\n" +
+                "set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1");
+        // @formatter:on
+    }
+
+    @Test
+    // One of responses from Apache Server that helped to catch a bug
+    public void testX() {
+        Decoder d = new Decoder(4096);
+        // @formatter:off
+        test(d, "3fe1 1f88 6196 d07a be94 03ea 693f 7504\n" +
+                "00b6 a05c b827 2e32 fa98 b46f 769e 86b1\n" +
+                "9272 b025 da5c 2ea9 fd70 a8de 7fb5 3556\n" +
+                "5ab7 6ece c057 02e2 2ad2 17bf 6c96 d07a\n" +
+                "be94 0854 cb6d 4a08 0075 40bd 71b6 6e05\n" +
+                "a531 68df 0f13 8efe 4522 cd32 21b6 5686\n" +
+                "eb23 781f cf52 848f d24a 8f0f 0d02 3435\n" +
+                "5f87 497c a589 d34d 1f",
+
+                "[  1] (s =  53) content-type: text/html\n" +
+                "[  2] (s =  50) accept-ranges: bytes\n" +
+                "[  3] (s =  74) last-modified: Mon, 11 Jun 2007 18:53:14 GMT\n" +
+                "[  4] (s =  77) server: Apache/2.4.17 (Unix) OpenSSL/1.0.2e-dev\n" +
+                "[  5] (s =  65) date: Mon, 09 Nov 2015 16:26:39 GMT\n" +
+                "      Table size: 319",
+
+                ":status: 200\n" +
+                "date: Mon, 09 Nov 2015 16:26:39 GMT\n" +
+                "server: Apache/2.4.17 (Unix) OpenSSL/1.0.2e-dev\n" +
+                "last-modified: Mon, 11 Jun 2007 18:53:14 GMT\n" +
+                "etag: \"2d-432a5e4a73a80\"\n" +
+                "accept-ranges: bytes\n" +
+                "content-length: 45\n" +
+                "content-type: text/html");
+        // @formatter:on
+    }
+
+    //
+    // This test is missing in the spec
+    //
+    @Test
+    public void sizeUpdate() {
+        Decoder d = new Decoder(4096);
+        assertEquals(d.getTable().maxSize(), 4096);
+        d.decode(ByteBuffer.wrap(new byte[]{0b00111110}), true, nopCallback()); // newSize = 30
+        assertEquals(d.getTable().maxSize(), 30);
+    }
+
+    @Test
+    public void incorrectSizeUpdate() {
+        ByteBuffer b = ByteBuffer.allocate(8);
+        Encoder e = new Encoder(8192) {
+            @Override
+            protected int calculateCapacity(int maxCapacity) {
+                return maxCapacity;
+            }
+        };
+        e.header("a", "b");
+        e.encode(b);
+        b.flip();
+        {
+            Decoder d = new Decoder(4096);
+            UncheckedIOException ex = assertVoidThrows(UncheckedIOException.class,
+                    () -> d.decode(b, true, (name, value) -> { }));
+
+            assertNotNull(ex.getCause());
+            assertEquals(ex.getCause().getClass(), ProtocolException.class);
+        }
+        b.flip();
+        {
+            Decoder d = new Decoder(4096);
+            UncheckedIOException ex = assertVoidThrows(UncheckedIOException.class,
+                    () -> d.decode(b, false, (name, value) -> { }));
+
+            assertNotNull(ex.getCause());
+            assertEquals(ex.getCause().getClass(), ProtocolException.class);
+        }
+    }
+
+    @Test
+    public void corruptedHeaderBlockInteger() {
+        Decoder d = new Decoder(4096);
+        ByteBuffer data = ByteBuffer.wrap(new byte[]{
+                (byte) 0b11111111, // indexed
+                (byte) 0b10011010  // 25 + ...
+        });
+        UncheckedIOException e = assertVoidThrows(UncheckedIOException.class,
+                () -> d.decode(data, true, nopCallback()));
+        assertNotNull(e.getCause());
+        assertEquals(e.getCause().getClass(), ProtocolException.class);
+        assertExceptionMessageContains(e, "Unexpected end of header block");
+    }
+
+    // 5.1.  Integer Representation
+    // ...
+    // Integer encodings that exceed implementation limits -- in value or octet
+    // length -- MUST be treated as decoding errors. Different limits can
+    // be set for each of the different uses of integers, based on
+    // implementation constraints.
+    @Test
+    public void headerBlockIntegerNoOverflow() {
+        Decoder d = new Decoder(4096);
+        ByteBuffer data = ByteBuffer.wrap(new byte[]{
+                (byte) 0b11111111, // indexed + 127
+                // Integer.MAX_VALUE - 127 (base 128, little-endian):
+                (byte) 0b10000000,
+                (byte) 0b11111111,
+                (byte) 0b11111111,
+                (byte) 0b11111111,
+                (byte) 0b00000111
+        });
+
+        IllegalArgumentException e = assertVoidThrows(IllegalArgumentException.class,
+                () -> d.decode(data, true, nopCallback()));
+
+        assertExceptionMessageContains(e, "index=2147483647");
+    }
+
+    @Test
+    public void headerBlockIntegerOverflow() {
+        Decoder d = new Decoder(4096);
+        ByteBuffer data = ByteBuffer.wrap(new byte[]{
+                (byte) 0b11111111, // indexed + 127
+                // Integer.MAX_VALUE - 127 + 1 (base 128, little endian):
+                (byte) 0b10000001,
+                (byte) 0b11111111,
+                (byte) 0b11111111,
+                (byte) 0b11111111,
+                (byte) 0b00000111
+        });
+
+        IllegalArgumentException e = assertVoidThrows(IllegalArgumentException.class,
+                () -> d.decode(data, true, nopCallback()));
+
+        assertExceptionMessageContains(e, "Integer overflow");
+    }
+
+    @Test
+    public void corruptedHeaderBlockString1() {
+        Decoder d = new Decoder(4096);
+        ByteBuffer data = ByteBuffer.wrap(new byte[]{
+                0b00001111, // literal, index=15
+                0b00000000,
+                0b00001000, // huffman=false, length=8
+                0b00000000, // \
+                0b00000000, //  but only 3 octets available...
+                0b00000000  // /
+        });
+        UncheckedIOException e = assertVoidThrows(UncheckedIOException.class,
+                () -> d.decode(data, true, nopCallback()));
+        assertNotNull(e.getCause());
+        assertEquals(e.getCause().getClass(), ProtocolException.class);
+        assertExceptionMessageContains(e, "Unexpected end of header block");
+    }
+
+    @Test
+    public void corruptedHeaderBlockString2() {
+        Decoder d = new Decoder(4096);
+        ByteBuffer data = ByteBuffer.wrap(new byte[]{
+                0b00001111, // literal, index=15
+                0b00000000,
+                (byte) 0b10001000, // huffman=true, length=8
+                0b00000000, // \
+                0b00000000, //  \
+                0b00000000, //   but only 5 octets available...
+                0b00000000, //  /
+                0b00000000  // /
+        });
+        UncheckedIOException e = assertVoidThrows(UncheckedIOException.class,
+                () -> d.decode(data, true, nopCallback()));
+        assertNotNull(e.getCause());
+        assertEquals(e.getCause().getClass(), ProtocolException.class);
+        assertExceptionMessageContains(e, "Unexpected end of header block");
+    }
+
+    // 5.2.  String Literal Representation
+    // ...A Huffman-encoded string literal containing the EOS symbol MUST be
+    // treated as a decoding error...
+    @Test
+    public void corruptedHeaderBlockHuffmanStringEOS() {
+        Decoder d = new Decoder(4096);
+        ByteBuffer data = ByteBuffer.wrap(new byte[]{
+                0b00001111, // literal, index=15
+                0b00000000,
+                (byte) 0b10000110, // huffman=true, length=6
+                0b00011001, 0b01001101, (byte) 0b11111111,
+                (byte) 0b11111111, (byte) 0b11111111, (byte) 0b11111100
+        });
+        IllegalArgumentException e = assertVoidThrows(IllegalArgumentException.class,
+                () -> d.decode(data, true, nopCallback()));
+
+        assertExceptionMessageContains(e, "Encountered EOS");
+    }
+
+    // 5.2.  String Literal Representation
+    // ...A padding strictly longer than 7 bits MUST be treated as a decoding
+    // error...
+    @Test
+    public void corruptedHeaderBlockHuffmanStringLongPadding1() {
+        Decoder d = new Decoder(4096);
+        ByteBuffer data = ByteBuffer.wrap(new byte[]{
+                0b00001111, // literal, index=15
+                0b00000000,
+                (byte) 0b10000011, // huffman=true, length=3
+                0b00011001, 0b01001101, (byte) 0b11111111
+                // len("aei") + len(padding) = (5 + 5 + 5) + (9)
+        });
+        IllegalArgumentException e = assertVoidThrows(IllegalArgumentException.class,
+                () -> d.decode(data, true, nopCallback()));
+
+        assertExceptionMessageContains(e, "Padding is too long", "len=9");
+    }
+
+    @Test
+    public void corruptedHeaderBlockHuffmanStringLongPadding2() {
+        Decoder d = new Decoder(4096);
+        ByteBuffer data = ByteBuffer.wrap(new byte[]{
+                0b00001111, // literal, index=15
+                0b00000000,
+                (byte) 0b10000011, // huffman=true, length=3
+                0b00011001, 0b01111010, (byte) 0b11111111
+                // len("aek") + len(padding) = (5 + 5 + 7) + (7)
+        });
+        assertVoidDoesNotThrow(() -> d.decode(data, true, nopCallback()));
+    }
+
+    // 5.2.  String Literal Representation
+    // ...A padding not corresponding to the most significant bits of the code
+    // for the EOS symbol MUST be treated as a decoding error...
+    @Test
+    public void corruptedHeaderBlockHuffmanStringNotEOSPadding() {
+        Decoder d = new Decoder(4096);
+        ByteBuffer data = ByteBuffer.wrap(new byte[]{
+                0b00001111, // literal, index=15
+                0b00000000,
+                (byte) 0b10000011, // huffman=true, length=3
+                0b00011001, 0b01111010, (byte) 0b11111110
+        });
+        IllegalArgumentException e = assertVoidThrows(IllegalArgumentException.class,
+                () -> d.decode(data, true, nopCallback()));
+
+        assertExceptionMessageContains(e, "Not a EOS prefix");
+    }
+
+    @Test
+    public void argsTestBiConsumerIsNull() {
+        Decoder decoder = new Decoder(4096);
+        assertVoidThrows(NullPointerException.class,
+                () -> decoder.decode(ByteBuffer.allocate(16), true, null));
+    }
+
+    @Test
+    public void argsTestByteBufferIsNull() {
+        Decoder decoder = new Decoder(4096);
+        assertVoidThrows(NullPointerException.class,
+                () -> decoder.decode(null, true, nopCallback()));
+    }
+
+    @Test
+    public void argsTestBothAreNull() {
+        Decoder decoder = new Decoder(4096);
+        assertVoidThrows(NullPointerException.class,
+                () -> decoder.decode(null, true, null));
+    }
+
+    private static void test(String hexdump,
+                             String headerTable, String headerList) {
+        test(new Decoder(4096), hexdump, headerTable, headerList);
+    }
+
+    //
+    // Sometimes we need to keep the same decoder along several runs,
+    // as it models the same connection
+    //
+    private static void test(Decoder d, String hexdump,
+                             String expectedHeaderTable, String expectedHeaderList) {
+
+        ByteBuffer source = SpecHelper.toBytes(hexdump);
+
+        List<String> actual = new LinkedList<>();
+        d.decode(source, true, (name, value) -> {
+            if (value == null) {
+                actual.add(name.toString());
+            } else {
+                actual.add(name + ": " + value);
+            }
+        });
+
+        assertEquals(d.getTable().getStateString(), expectedHeaderTable);
+        assertEquals(actual.stream().collect(Collectors.joining("\n")), expectedHeaderList);
+    }
+
+    private static DecodingCallback nopCallback() {
+        return (t, u) -> { };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/EncoderTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,623 @@
+/*
+ * Copyright (c) 2014, 2016, 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 sun.net.httpclient.hpack;
+
+import org.testng.annotations.Test;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Function;
+
+import static java.util.Arrays.asList;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static sun.net.httpclient.hpack.SpecHelper.toHexdump;
+import static sun.net.httpclient.hpack.TestHelper.assertVoidThrows;
+
+// TODO: map textual representation of commands from the spec to actual
+// calls to encoder (actually, this is a good idea for decoder as well)
+public final class EncoderTest {
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.2.1
+    //
+    @Test
+    public void example1() {
+
+        Encoder e = newCustomEncoder(256);
+        drainInitialUpdate(e);
+
+        e.literalWithIndexing("custom-key", false, "custom-header", false);
+        // @formatter:off
+        test(e,
+
+             "400a 6375 7374 6f6d 2d6b 6579 0d63 7573\n" +
+             "746f 6d2d 6865 6164 6572",
+
+             "[  1] (s =  55) custom-key: custom-header\n" +
+             "      Table size:  55");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.2.2
+    //
+    @Test
+    public void example2() {
+
+        Encoder e = newCustomEncoder(256);
+        drainInitialUpdate(e);
+
+        e.literal(4, "/sample/path", false);
+        // @formatter:off
+        test(e,
+
+             "040c 2f73 616d 706c 652f 7061 7468",
+
+             "empty.");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.2.3
+    //
+    @Test
+    public void example3() {
+
+        Encoder e = newCustomEncoder(256);
+        drainInitialUpdate(e);
+
+        e.literalNeverIndexed("password", false, "secret", false);
+        // @formatter:off
+        test(e,
+
+             "1008 7061 7373 776f 7264 0673 6563 7265\n" +
+             "74",
+
+             "empty.");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.2.4
+    //
+    @Test
+    public void example4() {
+
+        Encoder e = newCustomEncoder(256);
+        drainInitialUpdate(e);
+
+        e.indexed(2);
+        // @formatter:off
+        test(e,
+
+             "82",
+
+             "empty.");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.3
+    //
+    @Test
+    public void example5() {
+        Encoder e = newCustomEncoder(256);
+        drainInitialUpdate(e);
+
+        ByteBuffer output = ByteBuffer.allocate(64);
+        e.indexed(2);
+        e.encode(output);
+        e.indexed(6);
+        e.encode(output);
+        e.indexed(4);
+        e.encode(output);
+        e.literalWithIndexing(1, "www.example.com", false);
+        e.encode(output);
+
+        output.flip();
+
+        // @formatter:off
+        test(e, output,
+
+             "8286 8441 0f77 7777 2e65 7861 6d70 6c65\n" +
+             "2e63 6f6d",
+
+             "[  1] (s =  57) :authority: www.example.com\n" +
+             "      Table size:  57");
+
+        output.clear();
+
+        e.indexed( 2);
+        e.encode(output);
+        e.indexed( 6);
+        e.encode(output);
+        e.indexed( 4);
+        e.encode(output);
+        e.indexed(62);
+        e.encode(output);
+        e.literalWithIndexing(24, "no-cache", false);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "8286 84be 5808 6e6f 2d63 6163 6865",
+
+             "[  1] (s =  53) cache-control: no-cache\n" +
+             "[  2] (s =  57) :authority: www.example.com\n" +
+             "      Table size: 110");
+
+        output.clear();
+
+        e.indexed( 2);
+        e.encode(output);
+        e.indexed( 7);
+        e.encode(output);
+        e.indexed( 5);
+        e.encode(output);
+        e.indexed(63);
+        e.encode(output);
+        e.literalWithIndexing("custom-key", false, "custom-value", false);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "8287 85bf 400a 6375 7374 6f6d 2d6b 6579\n" +
+             "0c63 7573 746f 6d2d 7661 6c75 65",
+
+             "[  1] (s =  54) custom-key: custom-value\n" +
+             "[  2] (s =  53) cache-control: no-cache\n" +
+             "[  3] (s =  57) :authority: www.example.com\n" +
+             "      Table size: 164");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.4
+    //
+    @Test
+    public void example6() {
+        Encoder e = newCustomEncoder(256);
+        drainInitialUpdate(e);
+
+        ByteBuffer output = ByteBuffer.allocate(64);
+        e.indexed(2);
+        e.encode(output);
+        e.indexed(6);
+        e.encode(output);
+        e.indexed(4);
+        e.encode(output);
+        e.literalWithIndexing(1, "www.example.com", true);
+        e.encode(output);
+
+        output.flip();
+
+        // @formatter:off
+        test(e, output,
+
+             "8286 8441 8cf1 e3c2 e5f2 3a6b a0ab 90f4\n" +
+             "ff",
+
+             "[  1] (s =  57) :authority: www.example.com\n" +
+             "      Table size:  57");
+
+        output.clear();
+
+        e.indexed( 2);
+        e.encode(output);
+        e.indexed( 6);
+        e.encode(output);
+        e.indexed( 4);
+        e.encode(output);
+        e.indexed(62);
+        e.encode(output);
+        e.literalWithIndexing(24, "no-cache", true);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "8286 84be 5886 a8eb 1064 9cbf",
+
+             "[  1] (s =  53) cache-control: no-cache\n" +
+             "[  2] (s =  57) :authority: www.example.com\n" +
+             "      Table size: 110");
+
+        output.clear();
+
+        e.indexed( 2);
+        e.encode(output);
+        e.indexed( 7);
+        e.encode(output);
+        e.indexed( 5);
+        e.encode(output);
+        e.indexed(63);
+        e.encode(output);
+        e.literalWithIndexing("custom-key", true, "custom-value", true);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "8287 85bf 4088 25a8 49e9 5ba9 7d7f 8925\n" +
+             "a849 e95b b8e8 b4bf",
+
+             "[  1] (s =  54) custom-key: custom-value\n" +
+             "[  2] (s =  53) cache-control: no-cache\n" +
+             "[  3] (s =  57) :authority: www.example.com\n" +
+             "      Table size: 164");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.5
+    //
+    @Test
+    public void example7() {
+        Encoder e = newCustomEncoder(256);
+        drainInitialUpdate(e);
+
+        ByteBuffer output = ByteBuffer.allocate(128);
+        // @formatter:off
+        e.literalWithIndexing( 8, "302", false);
+        e.encode(output);
+        e.literalWithIndexing(24, "private", false);
+        e.encode(output);
+        e.literalWithIndexing(33, "Mon, 21 Oct 2013 20:13:21 GMT", false);
+        e.encode(output);
+        e.literalWithIndexing(46, "https://www.example.com", false);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "4803 3330 3258 0770 7269 7661 7465 611d\n" +
+             "4d6f 6e2c 2032 3120 4f63 7420 3230 3133\n" +
+             "2032 303a 3133 3a32 3120 474d 546e 1768\n" +
+             "7474 7073 3a2f 2f77 7777 2e65 7861 6d70\n" +
+             "6c65 2e63 6f6d",
+
+             "[  1] (s =  63) location: https://www.example.com\n" +
+             "[  2] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+             "[  3] (s =  52) cache-control: private\n" +
+             "[  4] (s =  42) :status: 302\n" +
+             "      Table size: 222");
+
+        output.clear();
+
+        e.literalWithIndexing( 8, "307", false);
+        e.encode(output);
+        e.indexed(65);
+        e.encode(output);
+        e.indexed(64);
+        e.encode(output);
+        e.indexed(63);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "4803 3330 37c1 c0bf",
+
+             "[  1] (s =  42) :status: 307\n" +
+             "[  2] (s =  63) location: https://www.example.com\n" +
+             "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+             "[  4] (s =  52) cache-control: private\n" +
+             "      Table size: 222");
+
+        output.clear();
+
+        e.indexed( 8);
+        e.encode(output);
+        e.indexed(65);
+        e.encode(output);
+        e.literalWithIndexing(33, "Mon, 21 Oct 2013 20:13:22 GMT", false);
+        e.encode(output);
+        e.indexed(64);
+        e.encode(output);
+        e.literalWithIndexing(26, "gzip", false);
+        e.encode(output);
+        e.literalWithIndexing(55, "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", false);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "88c1 611d 4d6f 6e2c 2032 3120 4f63 7420\n" +
+             "3230 3133 2032 303a 3133 3a32 3220 474d\n" +
+             "54c0 5a04 677a 6970 7738 666f 6f3d 4153\n" +
+             "444a 4b48 514b 425a 584f 5157 454f 5049\n" +
+             "5541 5851 5745 4f49 553b 206d 6178 2d61\n" +
+             "6765 3d33 3630 303b 2076 6572 7369 6f6e\n" +
+             "3d31",
+
+             "[  1] (s =  98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1\n" +
+             "[  2] (s =  52) content-encoding: gzip\n" +
+             "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:22 GMT\n" +
+             "      Table size: 215");
+        // @formatter:on
+    }
+
+    //
+    // http://tools.ietf.org/html/rfc7541#appendix-C.6
+    //
+    @Test
+    public void example8() {
+        Encoder e = newCustomEncoder(256);
+        drainInitialUpdate(e);
+
+        ByteBuffer output = ByteBuffer.allocate(128);
+        // @formatter:off
+        e.literalWithIndexing( 8, "302", true);
+        e.encode(output);
+        e.literalWithIndexing(24, "private", true);
+        e.encode(output);
+        e.literalWithIndexing(33, "Mon, 21 Oct 2013 20:13:21 GMT", true);
+        e.encode(output);
+        e.literalWithIndexing(46, "https://www.example.com", true);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "4882 6402 5885 aec3 771a 4b61 96d0 7abe\n" +
+             "9410 54d4 44a8 2005 9504 0b81 66e0 82a6\n" +
+             "2d1b ff6e 919d 29ad 1718 63c7 8f0b 97c8\n" +
+             "e9ae 82ae 43d3",
+
+             "[  1] (s =  63) location: https://www.example.com\n" +
+             "[  2] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+             "[  3] (s =  52) cache-control: private\n" +
+             "[  4] (s =  42) :status: 302\n" +
+             "      Table size: 222");
+
+        output.clear();
+
+        e.literalWithIndexing( 8, "307", true);
+        e.encode(output);
+        e.indexed(65);
+        e.encode(output);
+        e.indexed(64);
+        e.encode(output);
+        e.indexed(63);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "4883 640e ffc1 c0bf",
+
+             "[  1] (s =  42) :status: 307\n" +
+             "[  2] (s =  63) location: https://www.example.com\n" +
+             "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:21 GMT\n" +
+             "[  4] (s =  52) cache-control: private\n" +
+             "      Table size: 222");
+
+        output.clear();
+
+        e.indexed( 8);
+        e.encode(output);
+        e.indexed(65);
+        e.encode(output);
+        e.literalWithIndexing(33, "Mon, 21 Oct 2013 20:13:22 GMT", true);
+        e.encode(output);
+        e.indexed(64);
+        e.encode(output);
+        e.literalWithIndexing(26, "gzip", true);
+        e.encode(output);
+        e.literalWithIndexing(55, "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", true);
+        e.encode(output);
+
+        output.flip();
+
+        test(e, output,
+
+             "88c1 6196 d07a be94 1054 d444 a820 0595\n" +
+             "040b 8166 e084 a62d 1bff c05a 839b d9ab\n" +
+             "77ad 94e7 821d d7f2 e6c7 b335 dfdf cd5b\n" +
+             "3960 d5af 2708 7f36 72c1 ab27 0fb5 291f\n" +
+             "9587 3160 65c0 03ed 4ee5 b106 3d50 07",
+
+             "[  1] (s =  98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1\n" +
+             "[  2] (s =  52) content-encoding: gzip\n" +
+             "[  3] (s =  65) date: Mon, 21 Oct 2013 20:13:22 GMT\n" +
+             "      Table size: 215");
+        // @formatter:on
+    }
+
+    @Test
+    public void initialSizeUpdateDefaultEncoder() {
+        Function<Integer, Encoder> e = Encoder::new;
+        testSizeUpdate(e, 1024, asList(), asList(0));
+        testSizeUpdate(e, 1024, asList(1024), asList(0));
+        testSizeUpdate(e, 1024, asList(1024, 1024), asList(0));
+        testSizeUpdate(e, 1024, asList(1024, 512), asList(0));
+        testSizeUpdate(e, 1024, asList(512, 1024), asList(0));
+        testSizeUpdate(e, 1024, asList(512, 2048), asList(0));
+    }
+
+    @Test
+    public void initialSizeUpdateCustomEncoder() {
+        Function<Integer, Encoder> e = EncoderTest::newCustomEncoder;
+        testSizeUpdate(e, 1024, asList(), asList(1024));
+        testSizeUpdate(e, 1024, asList(1024), asList(1024));
+        testSizeUpdate(e, 1024, asList(1024, 1024), asList(1024));
+        testSizeUpdate(e, 1024, asList(1024, 512), asList(512));
+        testSizeUpdate(e, 1024, asList(512, 1024), asList(1024));
+        testSizeUpdate(e, 1024, asList(512, 2048), asList(2048));
+    }
+
+    @Test
+    public void seriesOfSizeUpdatesDefaultEncoder() {
+        Function<Integer, Encoder> e = c -> {
+            Encoder encoder = new Encoder(c);
+            drainInitialUpdate(encoder);
+            return encoder;
+        };
+        testSizeUpdate(e, 0, asList(0), asList());
+        testSizeUpdate(e, 1024, asList(1024), asList());
+        testSizeUpdate(e, 1024, asList(2048), asList());
+        testSizeUpdate(e, 1024, asList(512), asList());
+        testSizeUpdate(e, 1024, asList(1024, 1024), asList());
+        testSizeUpdate(e, 1024, asList(1024, 2048), asList());
+        testSizeUpdate(e, 1024, asList(2048, 1024), asList());
+        testSizeUpdate(e, 1024, asList(1024, 512), asList());
+        testSizeUpdate(e, 1024, asList(512, 1024), asList());
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#section-4.2
+    //
+    @Test
+    public void seriesOfSizeUpdatesCustomEncoder() {
+        Function<Integer, Encoder> e = c -> {
+            Encoder encoder = newCustomEncoder(c);
+            drainInitialUpdate(encoder);
+            return encoder;
+        };
+        testSizeUpdate(e, 0, asList(0), asList());
+        testSizeUpdate(e, 1024, asList(1024), asList());
+        testSizeUpdate(e, 1024, asList(2048), asList(2048));
+        testSizeUpdate(e, 1024, asList(512), asList(512));
+        testSizeUpdate(e, 1024, asList(1024, 1024), asList());
+        testSizeUpdate(e, 1024, asList(1024, 2048), asList(2048));
+        testSizeUpdate(e, 1024, asList(2048, 1024), asList());
+        testSizeUpdate(e, 1024, asList(1024, 512), asList(512));
+        testSizeUpdate(e, 1024, asList(512, 1024), asList(512, 1024));
+    }
+
+    @Test
+    public void callSequenceViolations() {
+        {   // Hasn't set up a header
+            Encoder e = new Encoder(0);
+            assertVoidThrows(IllegalStateException.class, () -> e.encode(ByteBuffer.allocate(16)));
+        }
+        {   // Can't set up header while there's an unfinished encoding
+            Encoder e = new Encoder(0);
+            e.indexed(32);
+            assertVoidThrows(IllegalStateException.class, () -> e.indexed(32));
+        }
+        {   // Can't setMaxCapacity while there's an unfinished encoding
+            Encoder e = new Encoder(0);
+            e.indexed(32);
+            assertVoidThrows(IllegalStateException.class, () -> e.setMaxCapacity(512));
+        }
+        {   // Hasn't set up a header
+            Encoder e = new Encoder(0);
+            e.setMaxCapacity(256);
+            assertVoidThrows(IllegalStateException.class, () -> e.encode(ByteBuffer.allocate(16)));
+        }
+        {   // Hasn't set up a header after the previous encoding
+            Encoder e = new Encoder(0);
+            e.indexed(0);
+            boolean encoded = e.encode(ByteBuffer.allocate(16));
+            assertTrue(encoded); // assumption
+            assertVoidThrows(IllegalStateException.class, () -> e.encode(ByteBuffer.allocate(16)));
+        }
+    }
+
+    private static void test(Encoder encoder,
+                             String expectedTableState,
+                             String expectedHexdump) {
+
+        ByteBuffer b = ByteBuffer.allocate(128);
+        encoder.encode(b);
+        b.flip();
+        test(encoder, b, expectedTableState, expectedHexdump);
+    }
+
+    private static void test(Encoder encoder,
+                             ByteBuffer output,
+                             String expectedHexdump,
+                             String expectedTableState) {
+
+        String actualTableState = encoder.getHeaderTable().getStateString();
+        assertEquals(actualTableState, expectedTableState);
+
+        String actualHexdump = toHexdump(output);
+        assertEquals(actualHexdump, expectedHexdump.replaceAll("\\n", " "));
+    }
+
+    // initial size - the size encoder is constructed with
+    // updates      - a sequence of values for consecutive calls to encoder.setMaxCapacity
+    // expected     - a sequence of values expected to be decoded by a decoder
+    private void testSizeUpdate(Function<Integer, Encoder> encoder,
+                                int initialSize,
+                                List<Integer> updates,
+                                List<Integer> expected) {
+        Encoder e = encoder.apply(initialSize);
+        updates.forEach(e::setMaxCapacity);
+        ByteBuffer b = ByteBuffer.allocate(64);
+        e.header("a", "b");
+        e.encode(b);
+        b.flip();
+        Decoder d = new Decoder(updates.isEmpty() ? initialSize : Collections.max(updates));
+        List<Integer> actual = new ArrayList<>();
+        d.decode(b, true, new DecodingCallback() {
+            @Override
+            public void onDecoded(CharSequence name, CharSequence value) { }
+
+            @Override
+            public void onSizeUpdate(int capacity) {
+                actual.add(capacity);
+            }
+        });
+        assertEquals(actual, expected);
+    }
+
+    //
+    // Default encoder does not need any table, therefore a subclass that
+    // behaves differently is needed
+    //
+    private static Encoder newCustomEncoder(int maxCapacity) {
+        return new Encoder(maxCapacity) {
+            @Override
+            protected int calculateCapacity(int maxCapacity) {
+                return maxCapacity;
+            }
+        };
+    }
+
+    private static void drainInitialUpdate(Encoder e) {
+        ByteBuffer b = ByteBuffer.allocate(4);
+        e.header("a", "b");
+        boolean done;
+        do {
+            done = e.encode(b);
+            b.flip();
+        } while (!done);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/HeaderTableTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,375 @@
+/*
+ * Copyright (c) 2014, 2016, 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 sun.net.httpclient.hpack;
+
+import org.testng.annotations.Test;
+import sun.net.httpclient.hpack.HeaderTable.HeaderField;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static java.lang.String.format;
+import static org.testng.Assert.assertEquals;
+import static sun.net.httpclient.hpack.TestHelper.*;
+
+public class HeaderTableTest {
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-A
+    //
+    // @formatter:off
+    private static final String SPEC =
+       "          | 1     | :authority                  |               |\n" +
+       "          | 2     | :method                     | GET           |\n" +
+       "          | 3     | :method                     | POST          |\n" +
+       "          | 4     | :path                       | /             |\n" +
+       "          | 5     | :path                       | /index.html   |\n" +
+       "          | 6     | :scheme                     | http          |\n" +
+       "          | 7     | :scheme                     | https         |\n" +
+       "          | 8     | :status                     | 200           |\n" +
+       "          | 9     | :status                     | 204           |\n" +
+       "          | 10    | :status                     | 206           |\n" +
+       "          | 11    | :status                     | 304           |\n" +
+       "          | 12    | :status                     | 400           |\n" +
+       "          | 13    | :status                     | 404           |\n" +
+       "          | 14    | :status                     | 500           |\n" +
+       "          | 15    | accept-charset              |               |\n" +
+       "          | 16    | accept-encoding             | gzip, deflate |\n" +
+       "          | 17    | accept-language             |               |\n" +
+       "          | 18    | accept-ranges               |               |\n" +
+       "          | 19    | accept                      |               |\n" +
+       "          | 20    | access-control-allow-origin |               |\n" +
+       "          | 21    | age                         |               |\n" +
+       "          | 22    | allow                       |               |\n" +
+       "          | 23    | authorization               |               |\n" +
+       "          | 24    | cache-control               |               |\n" +
+       "          | 25    | content-disposition         |               |\n" +
+       "          | 26    | content-encoding            |               |\n" +
+       "          | 27    | content-language            |               |\n" +
+       "          | 28    | content-length              |               |\n" +
+       "          | 29    | content-location            |               |\n" +
+       "          | 30    | content-range               |               |\n" +
+       "          | 31    | content-type                |               |\n" +
+       "          | 32    | cookie                      |               |\n" +
+       "          | 33    | date                        |               |\n" +
+       "          | 34    | etag                        |               |\n" +
+       "          | 35    | expect                      |               |\n" +
+       "          | 36    | expires                     |               |\n" +
+       "          | 37    | from                        |               |\n" +
+       "          | 38    | host                        |               |\n" +
+       "          | 39    | if-match                    |               |\n" +
+       "          | 40    | if-modified-since           |               |\n" +
+       "          | 41    | if-none-match               |               |\n" +
+       "          | 42    | if-range                    |               |\n" +
+       "          | 43    | if-unmodified-since         |               |\n" +
+       "          | 44    | last-modified               |               |\n" +
+       "          | 45    | link                        |               |\n" +
+       "          | 46    | location                    |               |\n" +
+       "          | 47    | max-forwards                |               |\n" +
+       "          | 48    | proxy-authenticate          |               |\n" +
+       "          | 49    | proxy-authorization         |               |\n" +
+       "          | 50    | range                       |               |\n" +
+       "          | 51    | referer                     |               |\n" +
+       "          | 52    | refresh                     |               |\n" +
+       "          | 53    | retry-after                 |               |\n" +
+       "          | 54    | server                      |               |\n" +
+       "          | 55    | set-cookie                  |               |\n" +
+       "          | 56    | strict-transport-security   |               |\n" +
+       "          | 57    | transfer-encoding           |               |\n" +
+       "          | 58    | user-agent                  |               |\n" +
+       "          | 59    | vary                        |               |\n" +
+       "          | 60    | via                         |               |\n" +
+       "          | 61    | www-authenticate            |               |\n";
+    // @formatter:on
+
+    private static final int STATIC_TABLE_LENGTH = createStaticEntries().size();
+    private final Random rnd = newRandom();
+
+    @Test
+    public void staticData() {
+        HeaderTable table = new HeaderTable(0);
+        Map<Integer, HeaderField> staticHeaderFields = createStaticEntries();
+
+        Map<String, Integer> minimalIndexes = new HashMap<>();
+
+        for (Map.Entry<Integer, HeaderField> e : staticHeaderFields.entrySet()) {
+            Integer idx = e.getKey();
+            String hName = e.getValue().name;
+            Integer midx = minimalIndexes.get(hName);
+            if (midx == null) {
+                minimalIndexes.put(hName, idx);
+            } else {
+                minimalIndexes.put(hName, Math.min(idx, midx));
+            }
+        }
+
+        staticHeaderFields.entrySet().forEach(
+                e -> {
+                    // lookup
+                    HeaderField actualHeaderField = table.get(e.getKey());
+                    HeaderField expectedHeaderField = e.getValue();
+                    assertEquals(actualHeaderField, expectedHeaderField);
+
+                    // reverse lookup (name, value)
+                    String hName = expectedHeaderField.name;
+                    String hValue = expectedHeaderField.value;
+                    int expectedIndex = e.getKey();
+                    int actualIndex = table.indexOf(hName, hValue);
+
+                    assertEquals(actualIndex, expectedIndex);
+
+                    // reverse lookup (name)
+                    int expectedMinimalIndex = minimalIndexes.get(hName);
+                    int actualMinimalIndex = table.indexOf(hName, "blah-blah");
+
+                    assertEquals(-actualMinimalIndex, expectedMinimalIndex);
+                }
+        );
+    }
+
+    @Test
+    public void constructorSetsMaxSize() {
+        int size = rnd.nextInt(64);
+        HeaderTable t = new HeaderTable(size);
+        assertEquals(t.size(), 0);
+        assertEquals(t.maxSize(), size);
+    }
+
+    @Test
+    public void negativeMaximumSize() {
+        int maxSize = -(rnd.nextInt(100) + 1); // [-100, -1]
+        IllegalArgumentException e =
+                assertVoidThrows(IllegalArgumentException.class,
+                        () -> new HeaderTable(0).setMaxSize(maxSize));
+        assertExceptionMessageContains(e, "maxSize");
+    }
+
+    @Test
+    public void zeroMaximumSize() {
+        HeaderTable table = new HeaderTable(0);
+        table.setMaxSize(0);
+        assertEquals(table.maxSize(), 0);
+    }
+
+    @Test
+    public void negativeIndex() {
+        int idx = -(rnd.nextInt(256) + 1); // [-256, -1]
+        IllegalArgumentException e =
+                assertVoidThrows(IllegalArgumentException.class,
+                        () -> new HeaderTable(0).get(idx));
+        assertExceptionMessageContains(e, "index");
+    }
+
+    @Test
+    public void zeroIndex() {
+        IllegalArgumentException e =
+                assertThrows(IllegalArgumentException.class,
+                        () -> new HeaderTable(0).get(0));
+        assertExceptionMessageContains(e, "index");
+    }
+
+    @Test
+    public void length() {
+        HeaderTable table = new HeaderTable(0);
+        assertEquals(table.length(), STATIC_TABLE_LENGTH);
+    }
+
+    @Test
+    public void indexOutsideStaticRange() {
+        HeaderTable table = new HeaderTable(0);
+        int idx = table.length() + (rnd.nextInt(256) + 1);
+        IllegalArgumentException e =
+                assertThrows(IllegalArgumentException.class,
+                        () -> table.get(idx));
+        assertExceptionMessageContains(e, "index");
+    }
+
+    @Test
+    public void entryPutAfterStaticArea() {
+        HeaderTable table = new HeaderTable(256);
+        int idx = table.length() + 1;
+        assertThrows(IllegalArgumentException.class, () -> table.get(idx));
+
+        byte[] bytes = new byte[32];
+        rnd.nextBytes(bytes);
+        String name = new String(bytes, StandardCharsets.ISO_8859_1);
+        String value = "custom-value";
+
+        table.put(name, value);
+        HeaderField f = table.get(idx);
+        assertEquals(name, f.name);
+        assertEquals(value, f.value);
+    }
+
+    @Test
+    public void staticTableHasZeroSize() {
+        HeaderTable table = new HeaderTable(0);
+        assertEquals(0, table.size());
+    }
+
+    @Test
+    public void lowerIndexPriority() {
+        HeaderTable table = new HeaderTable(256);
+        int oldLength = table.length();
+        table.put("bender", "rodriguez");
+        table.put("bender", "rodriguez");
+        table.put("bender", "rodriguez");
+
+        assertEquals(table.length(), oldLength + 3); // more like an assumption
+        int i = table.indexOf("bender", "rodriguez");
+        assertEquals(oldLength + 1, i);
+    }
+
+    @Test
+    public void lowerIndexPriority2() {
+        HeaderTable table = new HeaderTable(256);
+        int oldLength = table.length();
+        int idx = rnd.nextInt(oldLength) + 1;
+        HeaderField f = table.get(idx);
+        table.put(f.name, f.value);
+        assertEquals(table.length(), oldLength + 1);
+        int i = table.indexOf(f.name, f.value);
+        assertEquals(idx, i);
+    }
+
+    // TODO: negative indexes check
+    // TODO: ensure full table clearance when adding huge header field
+    // TODO: ensure eviction deletes minimum needed entries, not more
+
+    @Test
+    public void fifo() {
+        HeaderTable t = new HeaderTable(Integer.MAX_VALUE);
+        // Let's add a series of header fields
+        int NUM_HEADERS = 32;
+        for (int i = 1; i <= NUM_HEADERS; i++) {
+            String s = String.valueOf(i);
+            t.put(s, s);
+        }
+        // They MUST appear in a FIFO order:
+        //   newer entries are at lower indexes
+        //   older entries are at higher indexes
+        for (int j = 1; j <= NUM_HEADERS; j++) {
+            HeaderField f = t.get(STATIC_TABLE_LENGTH + j);
+            int actualName = Integer.parseInt(f.name);
+            int expectedName = NUM_HEADERS - j + 1;
+            assertEquals(expectedName, actualName);
+        }
+        // Entries MUST be evicted in the order they were added:
+        //   the newer the entry the later it is evicted
+        for (int k = 1; k <= NUM_HEADERS; k++) {
+            HeaderField f = t.evictEntry();
+            assertEquals(String.valueOf(k), f.name);
+        }
+    }
+
+    @Test
+    public void indexOf() {
+        HeaderTable t = new HeaderTable(Integer.MAX_VALUE);
+        // Let's put a series of header fields
+        int NUM_HEADERS = 32;
+        for (int i = 1; i <= NUM_HEADERS; i++) {
+            String s = String.valueOf(i);
+            t.put(s, s);
+        }
+        // and verify indexOf (reverse lookup) returns correct indexes for
+        // full lookup
+        for (int j = 1; j <= NUM_HEADERS; j++) {
+            String s = String.valueOf(j);
+            int actualIndex = t.indexOf(s, s);
+            int expectedIndex = STATIC_TABLE_LENGTH + NUM_HEADERS - j + 1;
+            assertEquals(expectedIndex, actualIndex);
+        }
+        // as well as for just a name lookup
+        for (int j = 1; j <= NUM_HEADERS; j++) {
+            String s = String.valueOf(j);
+            int actualIndex = t.indexOf(s, "blah");
+            int expectedIndex = -(STATIC_TABLE_LENGTH + NUM_HEADERS - j + 1);
+            assertEquals(expectedIndex, actualIndex);
+        }
+        // lookup for non-existent name returns 0
+        assertEquals(0, t.indexOf("chupacabra", "1"));
+    }
+
+    @Test
+    public void testToString() {
+        HeaderTable table = new HeaderTable(0);
+        {
+            table.setMaxSize(2048);
+            assertEquals("entries: 0; used 0/2048 (0.0%)", table.toString());
+        }
+
+        {
+            String name = "custom-name";
+            String value = "custom-value";
+            int size = 512;
+
+            table.setMaxSize(size);
+            table.put(name, value);
+            String s = table.toString();
+
+            int used = name.length() + value.length() + 32;
+            double ratio = used * 100.0 / size;
+
+            String expected = format("entries: 1; used %s/%s (%.1f%%)", used, size, ratio);
+            assertEquals(expected, s);
+        }
+
+        {
+            table.setMaxSize(78);
+            table.put(":method", "");
+            table.put(":status", "");
+            String s = table.toString();
+            assertEquals("entries: 2; used 78/78 (100.0%)", s);
+        }
+    }
+
+    @Test
+    public void stateString() {
+        HeaderTable table = new HeaderTable(256);
+        table.put("custom-key", "custom-header");
+        // @formatter:off
+        assertEquals("[  1] (s =  55) custom-key: custom-header\n" +
+                     "      Table size:  55", table.getStateString());
+        // @formatter:on
+    }
+
+    private static Map<Integer, HeaderField> createStaticEntries() {
+        Pattern line = Pattern.compile(
+                "\\|\\s*(?<index>\\d+?)\\s*\\|\\s*(?<name>.+?)\\s*\\|\\s*(?<value>.*?)\\s*\\|");
+        Matcher m = line.matcher(SPEC);
+        Map<Integer, HeaderField> result = new HashMap<>();
+        while (m.find()) {
+            int index = Integer.parseInt(m.group("index"));
+            String name = m.group("name");
+            String value = m.group("value");
+            HeaderField f = new HeaderField(name, value);
+            result.put(index, f);
+        }
+        return Collections.unmodifiableMap(result); // lol
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/HuffmanTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,623 @@
+/*
+ * Copyright (c) 2015, 2016, 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 sun.net.httpclient.hpack;
+
+import org.testng.annotations.Test;
+
+import java.nio.ByteBuffer;
+import java.util.Stack;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static java.lang.Integer.parseInt;
+import static org.testng.Assert.*;
+
+public final class HuffmanTest {
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-B
+    //
+    private static final String SPEC =
+            // @formatter:off
+     "                          code as bits                 as hex   len\n" +
+     "        sym              aligned to MSB                aligned   in\n" +
+     "                                                       to LSB   bits\n" +
+     "       (  0)  |11111111|11000                             1ff8  [13]\n" +
+     "       (  1)  |11111111|11111111|1011000                7fffd8  [23]\n" +
+     "       (  2)  |11111111|11111111|11111110|0010         fffffe2  [28]\n" +
+     "       (  3)  |11111111|11111111|11111110|0011         fffffe3  [28]\n" +
+     "       (  4)  |11111111|11111111|11111110|0100         fffffe4  [28]\n" +
+     "       (  5)  |11111111|11111111|11111110|0101         fffffe5  [28]\n" +
+     "       (  6)  |11111111|11111111|11111110|0110         fffffe6  [28]\n" +
+     "       (  7)  |11111111|11111111|11111110|0111         fffffe7  [28]\n" +
+     "       (  8)  |11111111|11111111|11111110|1000         fffffe8  [28]\n" +
+     "       (  9)  |11111111|11111111|11101010               ffffea  [24]\n" +
+     "       ( 10)  |11111111|11111111|11111111|111100      3ffffffc  [30]\n" +
+     "       ( 11)  |11111111|11111111|11111110|1001         fffffe9  [28]\n" +
+     "       ( 12)  |11111111|11111111|11111110|1010         fffffea  [28]\n" +
+     "       ( 13)  |11111111|11111111|11111111|111101      3ffffffd  [30]\n" +
+     "       ( 14)  |11111111|11111111|11111110|1011         fffffeb  [28]\n" +
+     "       ( 15)  |11111111|11111111|11111110|1100         fffffec  [28]\n" +
+     "       ( 16)  |11111111|11111111|11111110|1101         fffffed  [28]\n" +
+     "       ( 17)  |11111111|11111111|11111110|1110         fffffee  [28]\n" +
+     "       ( 18)  |11111111|11111111|11111110|1111         fffffef  [28]\n" +
+     "       ( 19)  |11111111|11111111|11111111|0000         ffffff0  [28]\n" +
+     "       ( 20)  |11111111|11111111|11111111|0001         ffffff1  [28]\n" +
+     "       ( 21)  |11111111|11111111|11111111|0010         ffffff2  [28]\n" +
+     "       ( 22)  |11111111|11111111|11111111|111110      3ffffffe  [30]\n" +
+     "       ( 23)  |11111111|11111111|11111111|0011         ffffff3  [28]\n" +
+     "       ( 24)  |11111111|11111111|11111111|0100         ffffff4  [28]\n" +
+     "       ( 25)  |11111111|11111111|11111111|0101         ffffff5  [28]\n" +
+     "       ( 26)  |11111111|11111111|11111111|0110         ffffff6  [28]\n" +
+     "       ( 27)  |11111111|11111111|11111111|0111         ffffff7  [28]\n" +
+     "       ( 28)  |11111111|11111111|11111111|1000         ffffff8  [28]\n" +
+     "       ( 29)  |11111111|11111111|11111111|1001         ffffff9  [28]\n" +
+     "       ( 30)  |11111111|11111111|11111111|1010         ffffffa  [28]\n" +
+     "       ( 31)  |11111111|11111111|11111111|1011         ffffffb  [28]\n" +
+     "   ' ' ( 32)  |010100                                       14  [ 6]\n" +
+     "   '!' ( 33)  |11111110|00                                 3f8  [10]\n" +
+     "  '\"' ( 34)  |11111110|01                                 3f9  [10]\n" +
+     "   '#' ( 35)  |11111111|1010                               ffa  [12]\n" +
+     "   '$' ( 36)  |11111111|11001                             1ff9  [13]\n" +
+     "   '%' ( 37)  |010101                                       15  [ 6]\n" +
+     "   '&' ( 38)  |11111000                                     f8  [ 8]\n" +
+     "   ''' ( 39)  |11111111|010                                7fa  [11]\n" +
+     "   '(' ( 40)  |11111110|10                                 3fa  [10]\n" +
+     "   ')' ( 41)  |11111110|11                                 3fb  [10]\n" +
+     "   '*' ( 42)  |11111001                                     f9  [ 8]\n" +
+     "   '+' ( 43)  |11111111|011                                7fb  [11]\n" +
+     "   ',' ( 44)  |11111010                                     fa  [ 8]\n" +
+     "   '-' ( 45)  |010110                                       16  [ 6]\n" +
+     "   '.' ( 46)  |010111                                       17  [ 6]\n" +
+     "   '/' ( 47)  |011000                                       18  [ 6]\n" +
+     "   '0' ( 48)  |00000                                         0  [ 5]\n" +
+     "   '1' ( 49)  |00001                                         1  [ 5]\n" +
+     "   '2' ( 50)  |00010                                         2  [ 5]\n" +
+     "   '3' ( 51)  |011001                                       19  [ 6]\n" +
+     "   '4' ( 52)  |011010                                       1a  [ 6]\n" +
+     "   '5' ( 53)  |011011                                       1b  [ 6]\n" +
+     "   '6' ( 54)  |011100                                       1c  [ 6]\n" +
+     "   '7' ( 55)  |011101                                       1d  [ 6]\n" +
+     "   '8' ( 56)  |011110                                       1e  [ 6]\n" +
+     "   '9' ( 57)  |011111                                       1f  [ 6]\n" +
+     "   ':' ( 58)  |1011100                                      5c  [ 7]\n" +
+     "   ';' ( 59)  |11111011                                     fb  [ 8]\n" +
+     "   '<' ( 60)  |11111111|1111100                           7ffc  [15]\n" +
+     "   '=' ( 61)  |100000                                       20  [ 6]\n" +
+     "   '>' ( 62)  |11111111|1011                               ffb  [12]\n" +
+     "   '?' ( 63)  |11111111|00                                 3fc  [10]\n" +
+     "   '@' ( 64)  |11111111|11010                             1ffa  [13]\n" +
+     "   'A' ( 65)  |100001                                       21  [ 6]\n" +
+     "   'B' ( 66)  |1011101                                      5d  [ 7]\n" +
+     "   'C' ( 67)  |1011110                                      5e  [ 7]\n" +
+     "   'D' ( 68)  |1011111                                      5f  [ 7]\n" +
+     "   'E' ( 69)  |1100000                                      60  [ 7]\n" +
+     "   'F' ( 70)  |1100001                                      61  [ 7]\n" +
+     "   'G' ( 71)  |1100010                                      62  [ 7]\n" +
+     "   'H' ( 72)  |1100011                                      63  [ 7]\n" +
+     "   'I' ( 73)  |1100100                                      64  [ 7]\n" +
+     "   'J' ( 74)  |1100101                                      65  [ 7]\n" +
+     "   'K' ( 75)  |1100110                                      66  [ 7]\n" +
+     "   'L' ( 76)  |1100111                                      67  [ 7]\n" +
+     "   'M' ( 77)  |1101000                                      68  [ 7]\n" +
+     "   'N' ( 78)  |1101001                                      69  [ 7]\n" +
+     "   'O' ( 79)  |1101010                                      6a  [ 7]\n" +
+     "   'P' ( 80)  |1101011                                      6b  [ 7]\n" +
+     "   'Q' ( 81)  |1101100                                      6c  [ 7]\n" +
+     "   'R' ( 82)  |1101101                                      6d  [ 7]\n" +
+     "   'S' ( 83)  |1101110                                      6e  [ 7]\n" +
+     "   'T' ( 84)  |1101111                                      6f  [ 7]\n" +
+     "   'U' ( 85)  |1110000                                      70  [ 7]\n" +
+     "   'V' ( 86)  |1110001                                      71  [ 7]\n" +
+     "   'W' ( 87)  |1110010                                      72  [ 7]\n" +
+     "   'X' ( 88)  |11111100                                     fc  [ 8]\n" +
+     "   'Y' ( 89)  |1110011                                      73  [ 7]\n" +
+     "   'Z' ( 90)  |11111101                                     fd  [ 8]\n" +
+     "   '[' ( 91)  |11111111|11011                             1ffb  [13]\n" +
+     "  '\\' ( 92)  |11111111|11111110|000                     7fff0  [19]\n" +
+     "   ']' ( 93)  |11111111|11100                             1ffc  [13]\n" +
+     "   '^' ( 94)  |11111111|111100                            3ffc  [14]\n" +
+     "   '_' ( 95)  |100010                                       22  [ 6]\n" +
+     "   '`' ( 96)  |11111111|1111101                           7ffd  [15]\n" +
+     "   'a' ( 97)  |00011                                         3  [ 5]\n" +
+     "   'b' ( 98)  |100011                                       23  [ 6]\n" +
+     "   'c' ( 99)  |00100                                         4  [ 5]\n" +
+     "   'd' (100)  |100100                                       24  [ 6]\n" +
+     "   'e' (101)  |00101                                         5  [ 5]\n" +
+     "   'f' (102)  |100101                                       25  [ 6]\n" +
+     "   'g' (103)  |100110                                       26  [ 6]\n" +
+     "   'h' (104)  |100111                                       27  [ 6]\n" +
+     "   'i' (105)  |00110                                         6  [ 5]\n" +
+     "   'j' (106)  |1110100                                      74  [ 7]\n" +
+     "   'k' (107)  |1110101                                      75  [ 7]\n" +
+     "   'l' (108)  |101000                                       28  [ 6]\n" +
+     "   'm' (109)  |101001                                       29  [ 6]\n" +
+     "   'n' (110)  |101010                                       2a  [ 6]\n" +
+     "   'o' (111)  |00111                                         7  [ 5]\n" +
+     "   'p' (112)  |101011                                       2b  [ 6]\n" +
+     "   'q' (113)  |1110110                                      76  [ 7]\n" +
+     "   'r' (114)  |101100                                       2c  [ 6]\n" +
+     "   's' (115)  |01000                                         8  [ 5]\n" +
+     "   't' (116)  |01001                                         9  [ 5]\n" +
+     "   'u' (117)  |101101                                       2d  [ 6]\n" +
+     "   'v' (118)  |1110111                                      77  [ 7]\n" +
+     "   'w' (119)  |1111000                                      78  [ 7]\n" +
+     "   'x' (120)  |1111001                                      79  [ 7]\n" +
+     "   'y' (121)  |1111010                                      7a  [ 7]\n" +
+     "   'z' (122)  |1111011                                      7b  [ 7]\n" +
+     "   '{' (123)  |11111111|1111110                           7ffe  [15]\n" +
+     "   '|' (124)  |11111111|100                                7fc  [11]\n" +
+     "   '}' (125)  |11111111|111101                            3ffd  [14]\n" +
+     "   '~' (126)  |11111111|11101                             1ffd  [13]\n" +
+     "       (127)  |11111111|11111111|11111111|1100         ffffffc  [28]\n" +
+     "       (128)  |11111111|11111110|0110                    fffe6  [20]\n" +
+     "       (129)  |11111111|11111111|010010                 3fffd2  [22]\n" +
+     "       (130)  |11111111|11111110|0111                    fffe7  [20]\n" +
+     "       (131)  |11111111|11111110|1000                    fffe8  [20]\n" +
+     "       (132)  |11111111|11111111|010011                 3fffd3  [22]\n" +
+     "       (133)  |11111111|11111111|010100                 3fffd4  [22]\n" +
+     "       (134)  |11111111|11111111|010101                 3fffd5  [22]\n" +
+     "       (135)  |11111111|11111111|1011001                7fffd9  [23]\n" +
+     "       (136)  |11111111|11111111|010110                 3fffd6  [22]\n" +
+     "       (137)  |11111111|11111111|1011010                7fffda  [23]\n" +
+     "       (138)  |11111111|11111111|1011011                7fffdb  [23]\n" +
+     "       (139)  |11111111|11111111|1011100                7fffdc  [23]\n" +
+     "       (140)  |11111111|11111111|1011101                7fffdd  [23]\n" +
+     "       (141)  |11111111|11111111|1011110                7fffde  [23]\n" +
+     "       (142)  |11111111|11111111|11101011               ffffeb  [24]\n" +
+     "       (143)  |11111111|11111111|1011111                7fffdf  [23]\n" +
+     "       (144)  |11111111|11111111|11101100               ffffec  [24]\n" +
+     "       (145)  |11111111|11111111|11101101               ffffed  [24]\n" +
+     "       (146)  |11111111|11111111|010111                 3fffd7  [22]\n" +
+     "       (147)  |11111111|11111111|1100000                7fffe0  [23]\n" +
+     "       (148)  |11111111|11111111|11101110               ffffee  [24]\n" +
+     "       (149)  |11111111|11111111|1100001                7fffe1  [23]\n" +
+     "       (150)  |11111111|11111111|1100010                7fffe2  [23]\n" +
+     "       (151)  |11111111|11111111|1100011                7fffe3  [23]\n" +
+     "       (152)  |11111111|11111111|1100100                7fffe4  [23]\n" +
+     "       (153)  |11111111|11111110|11100                  1fffdc  [21]\n" +
+     "       (154)  |11111111|11111111|011000                 3fffd8  [22]\n" +
+     "       (155)  |11111111|11111111|1100101                7fffe5  [23]\n" +
+     "       (156)  |11111111|11111111|011001                 3fffd9  [22]\n" +
+     "       (157)  |11111111|11111111|1100110                7fffe6  [23]\n" +
+     "       (158)  |11111111|11111111|1100111                7fffe7  [23]\n" +
+     "       (159)  |11111111|11111111|11101111               ffffef  [24]\n" +
+     "       (160)  |11111111|11111111|011010                 3fffda  [22]\n" +
+     "       (161)  |11111111|11111110|11101                  1fffdd  [21]\n" +
+     "       (162)  |11111111|11111110|1001                    fffe9  [20]\n" +
+     "       (163)  |11111111|11111111|011011                 3fffdb  [22]\n" +
+     "       (164)  |11111111|11111111|011100                 3fffdc  [22]\n" +
+     "       (165)  |11111111|11111111|1101000                7fffe8  [23]\n" +
+     "       (166)  |11111111|11111111|1101001                7fffe9  [23]\n" +
+     "       (167)  |11111111|11111110|11110                  1fffde  [21]\n" +
+     "       (168)  |11111111|11111111|1101010                7fffea  [23]\n" +
+     "       (169)  |11111111|11111111|011101                 3fffdd  [22]\n" +
+     "       (170)  |11111111|11111111|011110                 3fffde  [22]\n" +
+     "       (171)  |11111111|11111111|11110000               fffff0  [24]\n" +
+     "       (172)  |11111111|11111110|11111                  1fffdf  [21]\n" +
+     "       (173)  |11111111|11111111|011111                 3fffdf  [22]\n" +
+     "       (174)  |11111111|11111111|1101011                7fffeb  [23]\n" +
+     "       (175)  |11111111|11111111|1101100                7fffec  [23]\n" +
+     "       (176)  |11111111|11111111|00000                  1fffe0  [21]\n" +
+     "       (177)  |11111111|11111111|00001                  1fffe1  [21]\n" +
+     "       (178)  |11111111|11111111|100000                 3fffe0  [22]\n" +
+     "       (179)  |11111111|11111111|00010                  1fffe2  [21]\n" +
+     "       (180)  |11111111|11111111|1101101                7fffed  [23]\n" +
+     "       (181)  |11111111|11111111|100001                 3fffe1  [22]\n" +
+     "       (182)  |11111111|11111111|1101110                7fffee  [23]\n" +
+     "       (183)  |11111111|11111111|1101111                7fffef  [23]\n" +
+     "       (184)  |11111111|11111110|1010                    fffea  [20]\n" +
+     "       (185)  |11111111|11111111|100010                 3fffe2  [22]\n" +
+     "       (186)  |11111111|11111111|100011                 3fffe3  [22]\n" +
+     "       (187)  |11111111|11111111|100100                 3fffe4  [22]\n" +
+     "       (188)  |11111111|11111111|1110000                7ffff0  [23]\n" +
+     "       (189)  |11111111|11111111|100101                 3fffe5  [22]\n" +
+     "       (190)  |11111111|11111111|100110                 3fffe6  [22]\n" +
+     "       (191)  |11111111|11111111|1110001                7ffff1  [23]\n" +
+     "       (192)  |11111111|11111111|11111000|00           3ffffe0  [26]\n" +
+     "       (193)  |11111111|11111111|11111000|01           3ffffe1  [26]\n" +
+     "       (194)  |11111111|11111110|1011                    fffeb  [20]\n" +
+     "       (195)  |11111111|11111110|001                     7fff1  [19]\n" +
+     "       (196)  |11111111|11111111|100111                 3fffe7  [22]\n" +
+     "       (197)  |11111111|11111111|1110010                7ffff2  [23]\n" +
+     "       (198)  |11111111|11111111|101000                 3fffe8  [22]\n" +
+     "       (199)  |11111111|11111111|11110110|0            1ffffec  [25]\n" +
+     "       (200)  |11111111|11111111|11111000|10           3ffffe2  [26]\n" +
+     "       (201)  |11111111|11111111|11111000|11           3ffffe3  [26]\n" +
+     "       (202)  |11111111|11111111|11111001|00           3ffffe4  [26]\n" +
+     "       (203)  |11111111|11111111|11111011|110          7ffffde  [27]\n" +
+     "       (204)  |11111111|11111111|11111011|111          7ffffdf  [27]\n" +
+     "       (205)  |11111111|11111111|11111001|01           3ffffe5  [26]\n" +
+     "       (206)  |11111111|11111111|11110001               fffff1  [24]\n" +
+     "       (207)  |11111111|11111111|11110110|1            1ffffed  [25]\n" +
+     "       (208)  |11111111|11111110|010                     7fff2  [19]\n" +
+     "       (209)  |11111111|11111111|00011                  1fffe3  [21]\n" +
+     "       (210)  |11111111|11111111|11111001|10           3ffffe6  [26]\n" +
+     "       (211)  |11111111|11111111|11111100|000          7ffffe0  [27]\n" +
+     "       (212)  |11111111|11111111|11111100|001          7ffffe1  [27]\n" +
+     "       (213)  |11111111|11111111|11111001|11           3ffffe7  [26]\n" +
+     "       (214)  |11111111|11111111|11111100|010          7ffffe2  [27]\n" +
+     "       (215)  |11111111|11111111|11110010               fffff2  [24]\n" +
+     "       (216)  |11111111|11111111|00100                  1fffe4  [21]\n" +
+     "       (217)  |11111111|11111111|00101                  1fffe5  [21]\n" +
+     "       (218)  |11111111|11111111|11111010|00           3ffffe8  [26]\n" +
+     "       (219)  |11111111|11111111|11111010|01           3ffffe9  [26]\n" +
+     "       (220)  |11111111|11111111|11111111|1101         ffffffd  [28]\n" +
+     "       (221)  |11111111|11111111|11111100|011          7ffffe3  [27]\n" +
+     "       (222)  |11111111|11111111|11111100|100          7ffffe4  [27]\n" +
+     "       (223)  |11111111|11111111|11111100|101          7ffffe5  [27]\n" +
+     "       (224)  |11111111|11111110|1100                    fffec  [20]\n" +
+     "       (225)  |11111111|11111111|11110011               fffff3  [24]\n" +
+     "       (226)  |11111111|11111110|1101                    fffed  [20]\n" +
+     "       (227)  |11111111|11111111|00110                  1fffe6  [21]\n" +
+     "       (228)  |11111111|11111111|101001                 3fffe9  [22]\n" +
+     "       (229)  |11111111|11111111|00111                  1fffe7  [21]\n" +
+     "       (230)  |11111111|11111111|01000                  1fffe8  [21]\n" +
+     "       (231)  |11111111|11111111|1110011                7ffff3  [23]\n" +
+     "       (232)  |11111111|11111111|101010                 3fffea  [22]\n" +
+     "       (233)  |11111111|11111111|101011                 3fffeb  [22]\n" +
+     "       (234)  |11111111|11111111|11110111|0            1ffffee  [25]\n" +
+     "       (235)  |11111111|11111111|11110111|1            1ffffef  [25]\n" +
+     "       (236)  |11111111|11111111|11110100               fffff4  [24]\n" +
+     "       (237)  |11111111|11111111|11110101               fffff5  [24]\n" +
+     "       (238)  |11111111|11111111|11111010|10           3ffffea  [26]\n" +
+     "       (239)  |11111111|11111111|1110100                7ffff4  [23]\n" +
+     "       (240)  |11111111|11111111|11111010|11           3ffffeb  [26]\n" +
+     "       (241)  |11111111|11111111|11111100|110          7ffffe6  [27]\n" +
+     "       (242)  |11111111|11111111|11111011|00           3ffffec  [26]\n" +
+     "       (243)  |11111111|11111111|11111011|01           3ffffed  [26]\n" +
+     "       (244)  |11111111|11111111|11111100|111          7ffffe7  [27]\n" +
+     "       (245)  |11111111|11111111|11111101|000          7ffffe8  [27]\n" +
+     "       (246)  |11111111|11111111|11111101|001          7ffffe9  [27]\n" +
+     "       (247)  |11111111|11111111|11111101|010          7ffffea  [27]\n" +
+     "       (248)  |11111111|11111111|11111101|011          7ffffeb  [27]\n" +
+     "       (249)  |11111111|11111111|11111111|1110         ffffffe  [28]\n" +
+     "       (250)  |11111111|11111111|11111101|100          7ffffec  [27]\n" +
+     "       (251)  |11111111|11111111|11111101|101          7ffffed  [27]\n" +
+     "       (252)  |11111111|11111111|11111101|110          7ffffee  [27]\n" +
+     "       (253)  |11111111|11111111|11111101|111          7ffffef  [27]\n" +
+     "       (254)  |11111111|11111111|11111110|000          7fffff0  [27]\n" +
+     "       (255)  |11111111|11111111|11111011|10           3ffffee  [26]\n" +
+     "   EOS (256)  |11111111|11111111|11111111|111111      3fffffff  [30]";
+    // @formatter:on
+
+    @Test
+    public void read_table() {
+        Pattern line = Pattern.compile(
+                "\\(\\s*(?<ascii>\\d+)\\s*\\)\\s*(?<binary>(\\|(0|1)+)+)\\s*" +
+                        "(?<hex>[0-9a-zA-Z]+)\\s*\\[\\s*(?<len>\\d+)\\s*\\]");
+        Matcher m = line.matcher(SPEC);
+        int i = 0;
+        while (m.find()) {
+            String ascii = m.group("ascii");
+            String binary = m.group("binary").replaceAll("\\|", "");
+            String hex = m.group("hex");
+            String len = m.group("len");
+
+            // Several sanity checks for the data read from the table, just to
+            // make sure what we read makes sense
+            assertEquals(parseInt(len), binary.length());
+            assertEquals(parseInt(binary, 2), parseInt(hex, 16));
+
+            int expected = parseInt(ascii);
+
+            // TODO: find actual eos, do not hardcode it!
+            byte[] bytes = intToBytes(0x3fffffff, 30,
+                    parseInt(hex, 16), parseInt(len));
+
+            StringBuilder actual = new StringBuilder();
+            Huffman.Reader t = new Huffman.Reader();
+            t.read(ByteBuffer.wrap(bytes), actual, false, true);
+
+            // What has been read MUST represent a single symbol
+            assertEquals(actual.length(), 1, "ascii: " + ascii);
+
+            // It's a lot more visual to compare char as codes rather than
+            // characters (as some of them might not be visible)
+            assertEquals(actual.charAt(0), expected);
+            i++;
+        }
+        assertEquals(i, 257); // 256 + EOS
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.4.1
+    //
+    @Test
+    public void read_1() {
+        read("f1e3 c2e5 f23a 6ba0 ab90 f4ff", "www.example.com");
+    }
+
+    @Test
+    public void write_1() {
+        write("www.example.com", "f1e3 c2e5 f23a 6ba0 ab90 f4ff");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.4.2
+    //
+    @Test
+    public void read_2() {
+        read("a8eb 1064 9cbf", "no-cache");
+    }
+
+    @Test
+    public void write_2() {
+        write("no-cache", "a8eb 1064 9cbf");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.4.3
+    //
+    @Test
+    public void read_3() {
+        read("25a8 49e9 5ba9 7d7f", "custom-key");
+    }
+
+    @Test
+    public void write_3() {
+        write("custom-key", "25a8 49e9 5ba9 7d7f");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.4.3
+    //
+    @Test
+    public void read_4() {
+        read("25a8 49e9 5bb8 e8b4 bf", "custom-value");
+    }
+
+    @Test
+    public void write_4() {
+        write("custom-value", "25a8 49e9 5bb8 e8b4 bf");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.6.1
+    //
+    @Test
+    public void read_5() {
+        read("6402", "302");
+    }
+
+    @Test
+    public void write_5() {
+        write("302", "6402");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.6.1
+    //
+    @Test
+    public void read_6() {
+        read("aec3 771a 4b", "private");
+    }
+
+    @Test
+    public void write_6() {
+        write("private", "aec3 771a 4b");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.6.1
+    //
+    @Test
+    public void read_7() {
+        read("d07a be94 1054 d444 a820 0595 040b 8166 e082 a62d 1bff",
+                "Mon, 21 Oct 2013 20:13:21 GMT");
+    }
+
+    @Test
+    public void write_7() {
+        write("Mon, 21 Oct 2013 20:13:21 GMT",
+                "d07a be94 1054 d444 a820 0595 040b 8166 e082 a62d 1bff");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.6.1
+    //
+    @Test
+    public void read_8() {
+        read("9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 d3",
+                "https://www.example.com");
+    }
+
+    @Test
+    public void write_8() {
+        write("https://www.example.com",
+                "9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 d3");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.6.2
+    //
+    @Test
+    public void read_9() {
+        read("640e ff", "307");
+    }
+
+    @Test
+    public void write_9() {
+        write("307", "640e ff");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.6.3
+    //
+    @Test
+    public void read_10() {
+        read("d07a be94 1054 d444 a820 0595 040b 8166 e084 a62d 1bff",
+                "Mon, 21 Oct 2013 20:13:22 GMT");
+    }
+
+    @Test
+    public void write_10() {
+        write("Mon, 21 Oct 2013 20:13:22 GMT",
+                "d07a be94 1054 d444 a820 0595 040b 8166 e084 a62d 1bff");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.6.3
+    //
+    @Test
+    public void read_11() {
+        read("9bd9 ab", "gzip");
+    }
+
+    @Test
+    public void write_11() {
+        write("gzip", "9bd9 ab");
+    }
+
+    //
+    // https://tools.ietf.org/html/rfc7541#appendix-C.6.3
+    //
+    @Test
+    public void read_12() {
+        read("94e7 821d d7f2 e6c7 b335 dfdf cd5b 3960 " +
+             "d5af 2708 7f36 72c1 ab27 0fb5 291f 9587 " +
+             "3160 65c0 03ed 4ee5 b106 3d50 07",
+             "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1");
+    }
+
+    @Test
+    public void test_trie_has_no_empty_nodes() {
+        Huffman.Node root = Huffman.INSTANCE.getRoot();
+        Stack<Huffman.Node> backlog = new Stack<>();
+        backlog.push(root);
+        while (!backlog.isEmpty()) {
+            Huffman.Node n = backlog.pop();
+            // The only type of nodes we couldn't possibly catch during
+            // construction is an empty node: no children and no char
+            if (n.left != null) {
+                backlog.push(n.left);
+            }
+            if (n.right != null) {
+                backlog.push(n.right);
+            }
+            assertFalse(!n.charIsSet && n.left == null && n.right == null,
+                    "Empty node in the trie");
+        }
+    }
+
+    @Test
+    public void test_trie_has_257_nodes() {
+        int count = 0;
+        Huffman.Node root = Huffman.INSTANCE.getRoot();
+        Stack<Huffman.Node> backlog = new Stack<>();
+        backlog.push(root);
+        while (!backlog.isEmpty()) {
+            Huffman.Node n = backlog.pop();
+            if (n.left != null) {
+                backlog.push(n.left);
+            }
+            if (n.right != null) {
+                backlog.push(n.right);
+            }
+            if (n.isLeaf()) {
+                count++;
+            }
+        }
+        assertEquals(count, 257);
+    }
+
+    @Test
+    public void cant_encode_outside_byte() {
+        TestHelper.Block<Object> coding =
+                () -> new Huffman.Writer()
+                        .from(((char) 256) + "", 0, 1)
+                        .write(ByteBuffer.allocate(1));
+        RuntimeException e =
+                TestHelper.assertVoidThrows(RuntimeException.class, coding);
+        TestHelper.assertExceptionMessageContains(e, "char");
+    }
+
+    private static void read(String hexdump, String decoded) {
+        ByteBuffer source = SpecHelper.toBytes(hexdump);
+        Appendable actual = new StringBuilder();
+        new Huffman.Reader().read(source, actual, true);
+        assertEquals(actual.toString(), decoded);
+    }
+
+    private static void write(String decoded, String hexdump) {
+        int n = Huffman.INSTANCE.lengthOf(decoded);
+        ByteBuffer destination = ByteBuffer.allocate(n); // Extra margin (1) to test having more bytes in the destination than needed is ok
+        Huffman.Writer writer = new Huffman.Writer();
+        BuffersTestingKit.forEachSplit(destination, byteBuffers -> {
+            writer.from(decoded, 0, decoded.length());
+            boolean written = false;
+            for (ByteBuffer b : byteBuffers) {
+                int pos = b.position();
+                written = writer.write(b);
+                b.position(pos);
+            }
+            assertTrue(written);
+            ByteBuffer concated = BuffersTestingKit.concat(byteBuffers);
+            String actual = SpecHelper.toHexdump(concated);
+            assertEquals(actual, hexdump);
+            writer.reset();
+        });
+    }
+
+    //
+    // It's not very pretty, yes I know that
+    //
+    //      hex:
+    //
+    //      |31|30|...|N-1|...|01|00|
+    //                  \        /
+    //                  codeLength
+    //
+    //      hex <<= 32 - codeLength; (align to MSB):
+    //
+    //      |31|30|...|32-N|...|01|00|
+    //        \        /
+    //        codeLength
+    //
+    //      EOS:
+    //
+    //      |31|30|...|M-1|...|01|00|
+    //                   \        /
+    //                   eosLength
+    //
+    //      eos <<= 32 - eosLength; (align to MSB):
+    //
+    //      pad with MSBs of EOS:
+    //
+    //      |31|30|...|32-N|32-N-1|...|01|00|
+    //                     |    32|...|
+    //
+    //      Finally, split into byte[]
+    //
+    private byte[] intToBytes(int eos, int eosLength, int hex, int codeLength) {
+        hex <<= 32 - codeLength;
+        eos >>= codeLength - (32 - eosLength);
+        hex |= eos;
+        int n = (int) Math.ceil(codeLength / 8.0);
+        byte[] result = new byte[n];
+        for (int i = 0; i < n; i++) {
+            result[i] = (byte) (hex >> (32 - 8 * (i + 1)));
+        }
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/SpecHelper.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.net.httpclient.hpack;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+//
+// THIS IS NOT A TEST
+//
+public final class SpecHelper {
+
+    private SpecHelper() {
+        throw new AssertionError();
+    }
+
+    public static ByteBuffer toBytes(String hexdump) {
+        Pattern hexByte = Pattern.compile("[0-9a-fA-F]{2}");
+        List<String> bytes = new ArrayList<>();
+        Matcher matcher = hexByte.matcher(hexdump);
+        while (matcher.find()) {
+            bytes.add(matcher.group(0));
+        }
+        ByteBuffer result = ByteBuffer.allocate(bytes.size());
+        for (String f : bytes) {
+            result.put((byte) Integer.parseInt(f, 16));
+        }
+        result.flip();
+        return result;
+    }
+
+    public static String toHexdump(ByteBuffer bb) {
+        List<String> words = new ArrayList<>();
+        int i = 0;
+        while (bb.hasRemaining()) {
+            if (i % 2 == 0) {
+                words.add("");
+            }
+            byte b = bb.get();
+            String hex = Integer.toHexString(256 + Byte.toUnsignedInt(b)).substring(1);
+            words.set(i / 2, words.get(i / 2) + hex);
+            i++;
+        }
+        return words.stream().collect(Collectors.joining(" "));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/http2/java.httpclient/sun/net/httpclient/hpack/TestHelper.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2014, 2016, 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 sun.net.httpclient.hpack;
+
+import org.testng.annotations.Test;
+
+import java.util.Objects;
+import java.util.Random;
+
+public final class TestHelper {
+
+    public static Random newRandom() {
+        long seed = Long.getLong("jdk.test.lib.random.seed", System.currentTimeMillis());
+        System.out.println("new java.util.Random(" + seed + ")");
+        return new Random(seed);
+    }
+
+    public static <T extends Throwable> T assertVoidThrows(Class<T> clazz, Block<?> code) {
+        return assertThrows(clazz, () -> {
+            code.run();
+            return null;
+        });
+    }
+
+    public static <T extends Throwable> T assertThrows(Class<T> clazz, ReturningBlock<?> code) {
+        Objects.requireNonNull(clazz, "clazz == null");
+        Objects.requireNonNull(code, "code == null");
+        try {
+            code.run();
+        } catch (Throwable t) {
+            if (clazz.isInstance(t)) {
+                return clazz.cast(t);
+            }
+            throw new AssertionError("Expected to catch exception of type "
+                    + clazz.getCanonicalName() + ", instead caught "
+                    + t.getClass().getCanonicalName(), t);
+
+        }
+        throw new AssertionError(
+                "Expected to catch exception of type " + clazz.getCanonicalName()
+                        + ", but caught nothing");
+    }
+
+    public static <T> T assertDoesNotThrow(ReturningBlock<T> code) {
+        Objects.requireNonNull(code, "code == null");
+        try {
+            return code.run();
+        } catch (Throwable t) {
+            throw new AssertionError(
+                    "Expected code block to exit normally, instead " +
+                            "caught " + t.getClass().getCanonicalName(), t);
+        }
+    }
+
+    public static void assertVoidDoesNotThrow(Block<?> code) {
+        Objects.requireNonNull(code, "code == null");
+        try {
+            code.run();
+        } catch (Throwable t) {
+            throw new AssertionError(
+                    "Expected code block to exit normally, instead " +
+                            "caught " + t.getClass().getCanonicalName(), t);
+        }
+    }
+
+
+    public static void assertExceptionMessageContains(Throwable t,
+                                                      CharSequence firstSubsequence,
+                                                      CharSequence... others) {
+        assertCharSequenceContains(t.getMessage(), firstSubsequence, others);
+    }
+
+    public static void assertCharSequenceContains(CharSequence s,
+                                                  CharSequence firstSubsequence,
+                                                  CharSequence... others) {
+        if (s == null) {
+            throw new NullPointerException("Exception message is null");
+        }
+        String str = s.toString();
+        String missing = null;
+        if (!str.contains(firstSubsequence.toString())) {
+            missing = firstSubsequence.toString();
+        } else {
+            for (CharSequence o : others) {
+                if (!str.contains(o.toString())) {
+                    missing = o.toString();
+                    break;
+                }
+            }
+        }
+        if (missing != null) {
+            throw new AssertionError("CharSequence '" + s + "'" + " does not "
+                    + "contain subsequence '" + missing + "'");
+        }
+    }
+
+    public interface ReturningBlock<T> {
+        T run() throws Throwable;
+    }
+
+    public interface Block<T> {
+        void run() throws Throwable;
+    }
+
+    // tests
+
+    @Test
+    public void assertThrows() {
+        assertThrows(NullPointerException.class, () -> ((Object) null).toString());
+    }
+
+    @Test
+    public void assertThrowsWrongType() {
+        try {
+            assertThrows(IllegalArgumentException.class, () -> ((Object) null).toString());
+        } catch (AssertionError e) {
+            Throwable cause = e.getCause();
+            String message = e.getMessage();
+            if (cause != null
+                    && cause instanceof NullPointerException
+                    && message != null
+                    && message.contains("instead caught")) {
+                return;
+            }
+        }
+        throw new AssertionError();
+    }
+
+    @Test
+    public void assertThrowsNoneCaught() {
+        try {
+            assertThrows(IllegalArgumentException.class, () -> null);
+        } catch (AssertionError e) {
+            Throwable cause = e.getCause();
+            String message = e.getMessage();
+            if (cause == null
+                    && message != null
+                    && message.contains("but caught nothing")) {
+                return;
+            }
+        }
+        throw new AssertionError();
+    }
+}
--- a/jdk/test/java/net/httpclient/security/15.policy	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/net/httpclient/security/15.policy	Thu Apr 28 23:08:16 2016 -0700
@@ -16,7 +16,7 @@
     permission java.net.URLPermission "socket://127.0.0.1:27301", "CONNECT";
 
     // Test checks for this explicitly
-    permission java.net.RuntimePermission "foobar"; 
+    permission java.net.RuntimePermission "foobar";
 };
 
 
--- a/jdk/test/java/nio/channels/DatagramChannel/SocketOptionTests.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/nio/channels/DatagramChannel/SocketOptionTests.java	Thu Apr 28 23:08:16 2016 -0700
@@ -22,8 +22,10 @@
  */
 
 /* @test
- * @bug 4640544
+ * @bug 4640544 8044773
  * @summary Unit test for setOption/getOption/options methods
+ * @run main SocketOptionTests
+ * @run main/othervm -Djdk.launcher.limitmods=java.base SocketOptionTests
  */
 
 import java.nio.*;
--- a/jdk/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java	Thu Apr 28 23:08:16 2016 -0700
@@ -22,9 +22,11 @@
  */
 
 /* @test
- * @bug 4640544
+ * @bug 4640544 8044773
  * @summary Unit test for ServerSocketChannel setOption/getOption/options
  *          methods.
+ * @run main SocketOptionTests
+ * @run main/othervm -Djdk.launcher.limitmods=java.base SocketOptionTests
  */
 
 import java.nio.*;
--- a/jdk/test/java/nio/channels/SocketChannel/SocketOptionTests.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/nio/channels/SocketChannel/SocketOptionTests.java	Thu Apr 28 23:08:16 2016 -0700
@@ -22,9 +22,11 @@
  */
 
 /* @test
- * @bug 4640544
+ * @bug 4640544 8044773
  * @summary Unit test to check SocketChannel setOption/getOption/options
  *          methods.
+ * @run main SocketOptionTests
+ * @run main/othervm -Djdk.launcher.limitmods=java.base SocketOptionTests
  */
 
 import java.nio.*;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/WatchService/DeleteInterference.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2016, Red Hat, Inc. and/or its affiliates.
+ * 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.
+ */
+
+/**
+ * @test
+ * @bug 8153925
+ * @summary Tests potential interference between a thread creating and closing
+ *     a WatchService with another thread that is deleting and re-creating the
+ *     directory at around the same time. This scenario tickled a timing bug
+ *     in the Windows implementation.
+ */
+
+import java.io.IOException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.WatchService;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import static java.nio.file.StandardWatchEventKinds.*;
+
+public class DeleteInterference {
+
+    private static final int ITERATIONS_COUNT = 1024;
+
+    /**
+     * Execute two tasks in a thread pool. One task loops on creating and
+     * closing a WatchService, the other task deletes and re-creates the
+     * directory.
+     */
+    public static void main(String[] args) throws Exception {
+        Path dir = Files.createTempDirectory("work");
+        ExecutorService pool = Executors.newCachedThreadPool();
+        try {
+            Future<?> task1 = pool.submit(() -> openAndCloseWatcher(dir));
+            Future<?> task2 = pool.submit(() -> deleteAndRecreateDirectory(dir));
+            task1.get();
+            task2.get();
+        } finally {
+            pool.shutdown();
+            deleteFileTree(dir);
+        }
+    }
+
+    private static void openAndCloseWatcher(Path dir) {
+        FileSystem fs = FileSystems.getDefault();
+        for (int i = 0; i < ITERATIONS_COUNT; i++) {
+            try (WatchService watcher = fs.newWatchService()) {
+                dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
+            } catch (IOException ioe) {
+                // ignore
+            }
+        }
+    }
+
+    private static void deleteAndRecreateDirectory(Path dir) {
+        for (int i = 0; i < ITERATIONS_COUNT; i++) {
+            try {
+                deleteFileTree(dir);
+                Path subdir = Files.createDirectories(dir.resolve("subdir"));
+                Files.createFile(subdir.resolve("test"));
+            } catch (IOException ioe) {
+                // ignore
+            }
+        }
+    }
+
+    private static void deleteFileTree(Path file) {
+        try {
+            if (Files.isDirectory(file)) {
+                try (DirectoryStream<Path> stream = Files.newDirectoryStream(file)) {
+                    for (Path pa : stream) {
+                        deleteFileTree(pa);
+                    }
+                }
+            }
+            Files.delete(file);
+        } catch (IOException ioe) {
+            // ignore
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/TEST.properties	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,1 @@
+modules = java.rmi
--- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/Main.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/Main.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, 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 @@
  * @summary The Serialization benchmark test. This java class is used to run the
  *          test under JTREG.
  * @library ../../
+ * @modules java.desktop
  * @build bench.BenchInfo bench.HtmlReporter bench.Util bench.Benchmark
  * @build bench.Reporter bench.XmlReporter bench.ConfigFormatException
  * @build bench.Harness bench.TextReporter
--- a/jdk/test/java/security/Signature/TestInitSignWithMyOwnRandom.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/security/Signature/TestInitSignWithMyOwnRandom.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -55,9 +55,9 @@
 
     int count = 0;
 
-    public int nextInt() {
+    @Override
+    public void nextBytes(byte[] rs) {
         count++;
-        return 0;
     }
 
     public boolean isUsed() {
--- a/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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,6 +71,7 @@
 
 import java.text.ParsePosition;
 import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.time.YearMonth;
 import java.time.ZoneOffset;
 import java.time.format.DateTimeFormatter;
@@ -661,6 +662,8 @@
             {"W"},
             {"W"},
 
+            {"g"},
+            {"ggggg"},
         };
     }
 
@@ -762,6 +765,37 @@
     }
 
     //-----------------------------------------------------------------------
+    @DataProvider(name="modJulianFieldPattern")
+    Object[][] data_modJuilanFieldPattern() {
+        return new Object[][] {
+            {"g", "1"},
+            {"g", "123456"},
+            {"gggggg", "123456"},
+        };
+    }
+
+    @Test(dataProvider="modJulianFieldPattern")
+    public void test_modJulianFieldPattern(String pattern, String input) throws Exception {
+        DateTimeFormatter.ofPattern(pattern).parse(input);
+    }
+
+    @DataProvider(name="modJulianFieldValues")
+    Object[][] data_modJuilanFieldValues() {
+        return new Object[][] {
+            {1970, 1, 1, "40587"},
+            {1858, 11, 17, "0"},
+            {1858, 11, 16, "-1"},
+        };
+    }
+
+    @Test(dataProvider="modJulianFieldValues")
+    public void test_modJulianFieldValues(int y, int m, int d, String expected) throws Exception {
+        DateTimeFormatter df = new DateTimeFormatterBuilder().appendPattern("g").toFormatter();
+         assertEquals(LocalDate.of(y, m, d).format(df), expected);
+    }
+
+
+    //-----------------------------------------------------------------------
     @Test
     public void test_adjacent_strict_firstFixedWidth() throws Exception {
         // succeeds because both number elements are fixed width
@@ -897,7 +931,7 @@
 
     @Test
     public void test_adjacent_lenient_fractionFollows_0digit() throws Exception {
-        // succeeds because hour/min are fixed width
+        // succeeds because hour, min and fraction of seconds are fixed width
         DateTimeFormatter f = builder.parseLenient().appendValue(HOUR_OF_DAY, 2).appendValue(MINUTE_OF_HOUR, 2).appendFraction(NANO_OF_SECOND, 3, 3, false).toFormatter(Locale.UK);
         ParsePosition pp = new ParsePosition(0);
         TemporalAccessor parsed = f.parseUnresolved("1230", pp);
@@ -907,6 +941,21 @@
         assertEquals(parsed.getLong(MINUTE_OF_HOUR), 30L);
     }
 
+    @DataProvider(name="adjacentFractionParseData")
+    Object[][] data_adjacent_fraction_parse() {
+        return new Object[][] {
+            {"20130812214600025", "yyyyMMddHHmmssSSS", LocalDateTime.of(2013, 8, 12, 21, 46, 00, 25000000)},
+            {"201308122146000256", "yyyyMMddHHmmssSSSS", LocalDateTime.of(2013, 8, 12, 21, 46, 00, 25600000)},
+        };
+    }
+
+    @Test(dataProvider = "adjacentFractionParseData")
+    public void test_adjacent_fraction(String input, String pattern, LocalDateTime expected) {
+        DateTimeFormatter dtf = DateTimeFormatter.ofPattern(pattern);
+        LocalDateTime actual = LocalDateTime.parse(input, dtf);
+        assertEquals(actual, expected);
+    }
+
     @DataProvider(name="lenientOffsetParseData")
     Object[][] data_lenient_offset_parse() {
         return new Object[][] {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/time/tck/java/time/format/TCKLocalizedOffsetIdPrinterParser.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016, 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 tck.java.time.format;
+
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Locale;
+
+import org.testng.annotations.Test;
+
+/**
+ * Test localized behavior of formatter.
+ */
+@Test
+public class TCKLocalizedOffsetIdPrinterParser {
+    @Test
+    public void test_localized_offset_parse() {
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.S O")
+                                                       .withLocale(Locale.ENGLISH);
+        String date = formatter.format(ZonedDateTime.now(ZoneOffset.UTC));
+        formatter.parse(date) ;
+     }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Arrays/AsList.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2016, 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 8155600
+ * @summary Tests for Arrays.asList()
+ * @run testng AsList
+ */
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.stream.IntStream;
+
+import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.fail;
+
+public class AsList {
+    /*
+     * Iterator contract test
+     */
+    @Test(dataProvider = "Arrays")
+    public void testIterator(Object[] array) {
+        Iterator<Object> itr = Arrays.asList(array).iterator();
+        for (int i = 0; i < array.length; i++) {
+            assertTrue(itr.hasNext());
+            assertTrue(itr.hasNext()); // must be idempotent
+            assertSame(array[i], itr.next());
+            try {
+                itr.remove();
+                fail("Remove must throw");
+            } catch (UnsupportedOperationException ex) {
+                // expected
+            }
+        }
+        assertFalse(itr.hasNext());
+        for (int i = 0; i < 3; i++) {
+            assertFalse(itr.hasNext());
+            try {
+                itr.next();
+                fail("Next succeed when there's no data left");
+            } catch (NoSuchElementException ex) {
+                // expected
+            }
+        }
+    }
+
+    @DataProvider(name = "Arrays")
+    public static Object[][] arrays() {
+        Object[][] arrays = {
+            { new Object[] { } },
+            { new Object[] { 1 } },
+            { new Object[] { null } },
+            { new Object[] { null, 1 } },
+            { new Object[] { 1, null } },
+            { new Object[] { null, null } },
+            { new Object[] { null, 1, 2 } },
+            { new Object[] { 1, null, 2 } },
+            { new Object[] { 1, 2, null } },
+            { new Object[] { null, null, null } },
+            { new Object[] { 1, 2, 3, null, 4 } },
+            { new Object[] { "a", "a", "a", "a" } },
+            { IntStream.range(0, 100).boxed().toArray() }
+        };
+
+        return arrays;
+    }
+}
--- a/jdk/test/java/util/ServiceLoader/modules/BasicTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.lang.reflect.Layer;
-import java.security.Provider;
-import java.util.ServiceLoader;
-
-import org.testng.annotations.Test;
-import static org.testng.Assert.*;
-
-/*
- * @test
- * @run testng BasicTest
- * @summary Basic test of ServiceLoader with modules
- */
-
-public class BasicTest {
-
-    @Test
-    public void testEmptyLayer() {
-        ServiceLoader<Provider> sl
-            = ServiceLoader.load(Layer.empty(), Provider.class);
-        assertFalse(sl.iterator().hasNext());
-    }
-
-    @Test
-    public void testBootLayer() {
-        ServiceLoader<Provider> sl
-            = ServiceLoader.load(Layer.boot(), Provider.class);
-        boolean found = false;
-        for (Provider provider : sl) {
-            if (provider.getName().equals("SunJCE"))
-                found = true;
-        }
-        assertTrue(found);
-    }
-
-    @Test(expectedExceptions = { NullPointerException.class })
-    public void testNullLayer() {
-        ServiceLoader.load(null, Provider.class);
-    }
-
-    @Test(expectedExceptions = { NullPointerException.class })
-    public void testNullService() {
-        ServiceLoader.load(Layer.empty(), null);
-    }
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ServiceLoader/modules/MiscTests.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.reflect.Layer;
+import java.security.Provider;
+import java.util.ServiceLoader;
+
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+/*
+ * @test
+ * @run testng MiscTests
+ * @summary Basic test of ServiceLoader with modules
+ */
+
+public class MiscTests {
+
+    @Test
+    public void testEmptyLayer() {
+        ServiceLoader<Provider> sl
+            = ServiceLoader.load(Layer.empty(), Provider.class);
+        assertFalse(sl.iterator().hasNext());
+    }
+
+    @Test(expectedExceptions = { NullPointerException.class })
+    public void testNullLayer() {
+        ServiceLoader.load(null, Provider.class);
+    }
+
+    @Test(expectedExceptions = { NullPointerException.class })
+    public void testNullService() {
+        ServiceLoader.load(Layer.empty(), null);
+    }
+
+}
--- a/jdk/test/java/util/TimeZone/Bug6772689.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/util/TimeZone/Bug6772689.java	Thu Apr 28 23:08:16 2016 -0700
@@ -24,7 +24,6 @@
 /*
  * @test
  * @bug 6772689
- * @key intermittent
  * @summary Test for standard-to-daylight transitions at midnight:
  * date stays on the given day.
  */
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/DoublePrimitiveOpsTests.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/DoublePrimitiveOpsTests.java	Thu Apr 28 23:08:16 2016 -0700
@@ -27,11 +27,18 @@
 
 import java.util.Arrays;
 import java.util.Random;
+import java.util.Spliterator;
 import java.util.stream.DoubleStream;
 import java.util.stream.LongStream;
 
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
 
+/**
+ * @test
+ * @bug 8153293
+ */
 @Test
 public class DoublePrimitiveOpsTests {
 
@@ -42,6 +49,13 @@
         assertEquals(sum, 1.0 + 2.0 + 3.0 + 4.0 + 5.0);
     }
 
+    public void testFlags() {
+        assertTrue(LongStream.range(1, 10).asDoubleStream().boxed().spliterator()
+                      .hasCharacteristics(Spliterator.SORTED));
+        assertFalse(DoubleStream.of(1, 10).boxed().spliterator()
+                      .hasCharacteristics(Spliterator.SORTED));
+    }
+
     public void testToArray() {
         {
             double[] array =  LongStream.range(1, 10).asDoubleStream().map(i -> i * 2).toArray();
@@ -72,6 +86,22 @@
         }
     }
 
+    public void testSortDistinct() {
+        {
+            double[] range = LongStream.range(0, 10).asDoubleStream().toArray();
+
+            assertEquals(LongStream.range(0, 10).asDoubleStream().sorted().distinct().toArray(), range);
+            assertEquals(LongStream.range(0, 10).asDoubleStream().parallel().sorted().distinct().toArray(), range);
+
+            double[] data = {5, 3, 1, 1, 5, Double.NaN, 3, 9, Double.POSITIVE_INFINITY,
+                             Double.NEGATIVE_INFINITY, 2, 9, 1, 0, 8, Double.NaN, -0.0};
+            double[] expected = {Double.NEGATIVE_INFINITY, -0.0, 0, 1, 2, 3, 5, 8, 9,
+                                 Double.POSITIVE_INFINITY, Double.NaN};
+            assertEquals(DoubleStream.of(data).sorted().distinct().toArray(), expected);
+            assertEquals(DoubleStream.of(data).parallel().sorted().distinct().toArray(), expected);
+        }
+    }
+
     public void testSortSort() {
         Random r = new Random();
 
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/IntPrimitiveOpsTests.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/IntPrimitiveOpsTests.java	Thu Apr 28 23:08:16 2016 -0700
@@ -28,13 +28,21 @@
 import java.util.Arrays;
 import java.util.List;
 import java.util.Random;
+import java.util.Spliterator;
+import java.util.TreeSet;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.IntConsumer;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
 
+/**
+ * @test
+ * @bug 8153293
+ */
 @Test
 public class IntPrimitiveOpsTests {
 
@@ -85,6 +93,29 @@
         assertEquals(sum, 15);
     }
 
+    public void testFlags() {
+        assertTrue(IntStream.range(1, 10).boxed().spliterator()
+                      .hasCharacteristics(Spliterator.SORTED | Spliterator.DISTINCT));
+        assertFalse(IntStream.of(1, 10).boxed().spliterator()
+                      .hasCharacteristics(Spliterator.SORTED));
+        assertFalse(IntStream.of(1, 10).boxed().spliterator()
+                      .hasCharacteristics(Spliterator.DISTINCT));
+
+        assertTrue(IntStream.range(1, 10).asLongStream().spliterator()
+                      .hasCharacteristics(Spliterator.SORTED | Spliterator.DISTINCT));
+        assertFalse(IntStream.of(1, 10).asLongStream().spliterator()
+                      .hasCharacteristics(Spliterator.SORTED));
+        assertFalse(IntStream.of(1, 10).asLongStream().spliterator()
+                      .hasCharacteristics(Spliterator.DISTINCT));
+
+        assertTrue(IntStream.range(1, 10).asDoubleStream().spliterator()
+                      .hasCharacteristics(Spliterator.SORTED | Spliterator.DISTINCT));
+        assertFalse(IntStream.of(1, 10).asDoubleStream().spliterator()
+                      .hasCharacteristics(Spliterator.SORTED));
+        assertFalse(IntStream.of(1, 10).asDoubleStream().spliterator()
+                      .hasCharacteristics(Spliterator.DISTINCT));
+    }
+
     public void testToArray() {
         {
             int[] array =  IntStream.range(1, 10).map(i -> i * 2).toArray();
@@ -115,6 +146,35 @@
         }
     }
 
+    public void testSortDistinct() {
+        {
+            int[] range = IntStream.range(0, 10).toArray();
+
+            assertEquals(IntStream.range(0, 10).sorted().distinct().toArray(), range);
+            assertEquals(IntStream.range(0, 10).parallel().sorted().distinct().toArray(), range);
+
+            int[] data = {5, 3, 1, 1, 5, 3, 9, 2, 9, 1, 0, 8};
+            int[] expected = {0, 1, 2, 3, 5, 8, 9};
+            assertEquals(IntStream.of(data).sorted().distinct().toArray(), expected);
+            assertEquals(IntStream.of(data).parallel().sorted().distinct().toArray(), expected);
+        }
+
+        {
+            int[] input = new Random().ints(100, -10, 10).map(x -> x+Integer.MAX_VALUE).toArray();
+            TreeSet<Long> longs = new TreeSet<>();
+            for(int i : input) longs.add((long)i);
+            long[] expectedLongs = longs.stream().mapToLong(Long::longValue).toArray();
+            assertEquals(IntStream.of(input).sorted().asLongStream().sorted().distinct().toArray(),
+                         expectedLongs);
+
+            TreeSet<Double> doubles = new TreeSet<>();
+            for(int i : input) doubles.add((double)i);
+            double[] expectedDoubles = doubles.stream().mapToDouble(Double::doubleValue).toArray();
+            assertEquals(IntStream.of(input).sorted().distinct().asDoubleStream()
+                         .sorted().distinct().toArray(), expectedDoubles);
+        }
+    }
+
     public void testSortSort() {
         Random r = new Random();
 
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/LongPrimitiveOpsTests.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/LongPrimitiveOpsTests.java	Thu Apr 28 23:08:16 2016 -0700
@@ -28,13 +28,21 @@
 import java.util.Arrays;
 import java.util.List;
 import java.util.Random;
+import java.util.Spliterator;
+import java.util.TreeSet;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.function.LongConsumer;
 import java.util.stream.Collectors;
 import java.util.stream.LongStream;
 
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
 
+/**
+ * @test
+ * @bug 8153293
+ */
 @Test
 public class LongPrimitiveOpsTests {
 
@@ -85,6 +93,22 @@
         assertEquals(sum, 15);
     }
 
+    public void testFlags() {
+        assertTrue(LongStream.range(1, 10).boxed().spliterator()
+                      .hasCharacteristics(Spliterator.SORTED | Spliterator.DISTINCT));
+        assertFalse(LongStream.of(1, 10).boxed().spliterator()
+                      .hasCharacteristics(Spliterator.SORTED));
+        assertFalse(LongStream.of(1, 10).boxed().spliterator()
+                      .hasCharacteristics(Spliterator.DISTINCT));
+
+        assertTrue(LongStream.range(1, 10).asDoubleStream().spliterator()
+                      .hasCharacteristics(Spliterator.SORTED));
+        assertFalse(LongStream.range(1, 10).asDoubleStream().spliterator()
+                      .hasCharacteristics(Spliterator.DISTINCT));
+        assertFalse(LongStream.of(1, 10).asDoubleStream().spliterator()
+                      .hasCharacteristics(Spliterator.SORTED));
+    }
+
     public void testToArray() {
         {
             long[] array =  LongStream.range(1, 10).map(i -> i * 2).toArray();
@@ -115,6 +139,30 @@
         }
     }
 
+    public void testSortDistinct() {
+        {
+            long[] range = LongStream.range(0, 10).toArray();
+
+            assertEquals(LongStream.range(0, 10).sorted().distinct().toArray(), range);
+            assertEquals(LongStream.range(0, 10).parallel().sorted().distinct().toArray(), range);
+
+            long[] data = {5, 3, 1, 1, 5, 3, 9, 2, 9, 1, 0, 8};
+            long[] expected = {0, 1, 2, 3, 5, 8, 9};
+            assertEquals(LongStream.of(data).sorted().distinct().toArray(), expected);
+            assertEquals(LongStream.of(data).parallel().sorted().distinct().toArray(), expected);
+        }
+
+        {
+            long[] input = new Random().longs(100, -10, 10).map(x -> x+Long.MAX_VALUE).toArray();
+
+            TreeSet<Double> doubles = new TreeSet<>();
+            for(long i : input) doubles.add((double)i);
+            double[] expectedDoubles = doubles.stream().mapToDouble(Double::doubleValue).toArray();
+            assertEquals(LongStream.of(input).sorted().distinct().asDoubleStream()
+                         .sorted().distinct().toArray(), expectedDoubles);
+        }
+    }
+
     public void testSortSort() {
         Random r = new Random();
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/plugins/tiff/MultiPageImageTIFFFieldTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,378 @@
+/*
+ * Copyright (c) 2016, 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
+ * @ignore  8148454
+ * @bug     8152183 8148454
+ * @author  a.stepanov
+ * @summary check that TIFFields are derived properly for multi-page tiff
+ * @run     main MultiPageImageTIFFFieldTest
+ */
+
+import java.awt.*;
+import java.awt.color.*;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import javax.imageio.*;
+import javax.imageio.metadata.*;
+import javax.imageio.stream.*;
+import javax.imageio.plugins.tiff.*;
+
+
+public class MultiPageImageTIFFFieldTest {
+
+    private final static String FILENAME = "test.tiff";
+    private final static int W1 = 20, H1 = 40, W2 = 100, H2 = 15;
+    private final static Color C1 = Color.BLACK, C2 = Color.RED;
+
+    private final static int N_WIDTH  = BaselineTIFFTagSet.TAG_IMAGE_WIDTH;
+    private final static int N_HEIGHT = BaselineTIFFTagSet.TAG_IMAGE_LENGTH;
+
+    private static final String DESCRIPTION_1[] = {"Description-1", "abc ABC"};
+    private static final String DESCRIPTION_2[] = {"Description-2", "1-2-3"};
+    private final static int N_DESCRIPTION =
+        BaselineTIFFTagSet.TAG_IMAGE_DESCRIPTION;
+
+    private final static String EXIF_DATA_1[] = {"2001:01:01 00:00:01"};
+    private final static String EXIF_DATA_2[] = {"2002:02:02 00:00:02"};
+    private final static int N_EXIF = ExifTIFFTagSet.TAG_DATE_TIME_ORIGINAL;
+
+    private final static String GPS_DATA[] = {
+        ExifGPSTagSet.STATUS_MEASUREMENT_IN_PROGRESS};
+    private final static int N_GPS = ExifGPSTagSet.TAG_GPS_STATUS;
+
+    private final static short FAX_DATA =
+        FaxTIFFTagSet.CLEAN_FAX_DATA_ERRORS_UNCORRECTED;
+    private final static int N_FAX = FaxTIFFTagSet.TAG_CLEAN_FAX_DATA;
+
+    private static final byte[] ICC_PROFILE_2 =
+        ICC_ProfileRGB.getInstance(ColorSpace.CS_sRGB).getData();
+    private static final int N_ICC = BaselineTIFFTagSet.TAG_ICC_PROFILE;
+
+    private static final int N_BPS = BaselineTIFFTagSet.TAG_BITS_PER_SAMPLE;
+
+    private static final int
+        COMPRESSION_1 = BaselineTIFFTagSet.COMPRESSION_DEFLATE,
+        COMPRESSION_2 = BaselineTIFFTagSet.COMPRESSION_LZW;
+    private static final int N_COMPRESSION = BaselineTIFFTagSet.TAG_COMPRESSION;
+
+    private static final int
+        GRAY_1 = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO,
+        GRAY_2 = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO,
+        RGB    = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_RGB;
+
+    private static final int N_PHOTO =
+        BaselineTIFFTagSet.TAG_PHOTOMETRIC_INTERPRETATION;
+
+    private ImageWriter getTIFFWriter() {
+
+        java.util.Iterator<ImageWriter> writers =
+            ImageIO.getImageWritersByFormatName("TIFF");
+        if (!writers.hasNext()) {
+            throw new RuntimeException("No writers available for TIFF format");
+        }
+        return writers.next();
+    }
+
+    private ImageReader getTIFFReader() {
+
+        java.util.Iterator<ImageReader> readers =
+            ImageIO.getImageReadersByFormatName("TIFF");
+        if (!readers.hasNext()) {
+            throw new RuntimeException("No readers available for TIFF format");
+        }
+        return readers.next();
+    }
+
+    private void addASCIIField(TIFFDirectory d,
+                               String        name,
+                               String        data[],
+                               int           num) {
+
+        d.addTIFFField(new TIFFField(
+            new TIFFTag(name, num, 1 << TIFFTag.TIFF_ASCII),
+                TIFFTag.TIFF_ASCII, data.length, data));
+    }
+
+    private void checkASCIIField(TIFFDirectory d,
+                                 String        what,
+                                 String        data[],
+                                 int           num) {
+
+        String notFound = what + " field was not found";
+        check(d.containsTIFFField(num), notFound);
+        TIFFField f = d.getTIFFField(num);
+        check(f.getType() == TIFFTag.TIFF_ASCII, "field type != ASCII");
+        check(f.getCount() == data.length, "invalid " + what + " data count");
+        for (int i = 0; i < data.length; i++) {
+            check(f.getValueAsString(i).equals(data[i]),
+                "invalid " + what + " data");
+        }
+    }
+
+    private void writeImage() throws Exception {
+
+        OutputStream s = new BufferedOutputStream(new FileOutputStream(FILENAME));
+        try (ImageOutputStream ios = ImageIO.createImageOutputStream(s)) {
+
+            ImageWriter writer = getTIFFWriter();
+            writer.setOutput(ios);
+
+            BufferedImage img1 =
+                new BufferedImage(W1, H1, BufferedImage.TYPE_BYTE_GRAY);
+            Graphics g = img1.getGraphics();
+            g.setColor(C1);
+            g.fillRect(0, 0, W1, H1);
+            g.dispose();
+
+            BufferedImage img2 =
+                new BufferedImage(W2, H2, BufferedImage.TYPE_INT_RGB);
+            g = img2.getGraphics();
+            g.setColor(C2);
+            g.fillRect(0, 0, W2, H2);
+            g.dispose();
+
+            ImageWriteParam param1 = writer.getDefaultWriteParam();
+            param1.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+            param1.setCompressionType("Deflate");
+            param1.setCompressionQuality(0.5f);
+
+            ImageWriteParam param2 = writer.getDefaultWriteParam();
+            param2.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+            param2.setCompressionType("LZW");
+            param2.setCompressionQuality(0.5f);
+
+            IIOMetadata
+                md1 = writer.getDefaultImageMetadata(
+                    new ImageTypeSpecifier(img1), param1),
+                md2 = writer.getDefaultImageMetadata(
+                    new ImageTypeSpecifier(img2), param2);
+
+            TIFFDirectory
+                dir1 = TIFFDirectory.createFromMetadata(md1),
+                dir2 = TIFFDirectory.createFromMetadata(md2);
+
+            addASCIIField(dir1, "ImageDescription", DESCRIPTION_1, N_DESCRIPTION);
+            addASCIIField(dir2, "ImageDescription", DESCRIPTION_2, N_DESCRIPTION);
+
+            addASCIIField(dir1, "GPSStatus", GPS_DATA, N_GPS);
+            addASCIIField(dir2, "GPSStatus", GPS_DATA, N_GPS);
+
+            addASCIIField(dir1, "DateTimeOriginal", EXIF_DATA_1, N_EXIF);
+            addASCIIField(dir2, "DateTimeOriginal", EXIF_DATA_2, N_EXIF);
+
+            TIFFTag faxTag = new TIFFTag(
+                "CleanFaxData", N_FAX, 1 << TIFFTag.TIFF_SHORT);
+            dir1.addTIFFField(new TIFFField(faxTag, FAX_DATA));
+            dir2.addTIFFField(new TIFFField(faxTag, FAX_DATA));
+
+            dir2.addTIFFField(new TIFFField(
+                new TIFFTag("ICC Profile", N_ICC, 1 << TIFFTag.TIFF_UNDEFINED),
+                TIFFTag.TIFF_UNDEFINED, ICC_PROFILE_2.length, ICC_PROFILE_2));
+
+            writer.prepareWriteSequence(null);
+            writer.writeToSequence(
+                new IIOImage(img1, null, dir1.getAsMetadata()), param1);
+            writer.writeToSequence(
+                new IIOImage(img2, null, dir2.getAsMetadata()), param2);
+            writer.endWriteSequence();
+
+            ios.flush();
+            writer.dispose();
+        }
+        s.close();
+    }
+
+    private void checkBufferedImages(BufferedImage im1, BufferedImage im2) {
+
+        check(im1.getWidth()  == W1, "invalid width for image 1");
+        check(im1.getHeight() == H1, "invalid height for image 1");
+        check(im2.getWidth()  == W2, "invalid width for image 2");
+        check(im2.getHeight() == H2, "invalid height for image 2");
+
+        Color
+            c1 = new Color(im1.getRGB(W1 / 2, H1 / 2)),
+            c2 = new Color(im2.getRGB(W2 / 2, H2 / 2));
+
+        check(c1.equals(C1), "invalid image 1 color");
+        check(c2.equals(C2), "invalid image 2 color");
+    }
+
+    private void readAndCheckImage() throws Exception {
+
+        ImageReader reader = getTIFFReader();
+
+        ImageInputStream s = ImageIO.createImageInputStream(new File(FILENAME));
+        reader.setInput(s, false, true);
+
+        int ni = reader.getNumImages(true);
+        check(ni == 2, "invalid number of images");
+
+        // check TIFFImageReadParam for multipage image
+        TIFFImageReadParam
+            param1 = new TIFFImageReadParam(), param2 = new TIFFImageReadParam();
+
+        param1.addAllowedTagSet(ExifTIFFTagSet.getInstance());
+        param1.addAllowedTagSet(ExifGPSTagSet.getInstance());
+
+        param2.addAllowedTagSet(ExifTIFFTagSet.getInstance());
+        param2.addAllowedTagSet(GeoTIFFTagSet.getInstance());
+
+        // FaxTIFFTagSet is allowed by default
+        param2.removeAllowedTagSet(FaxTIFFTagSet.getInstance());
+
+
+        // read images and metadata
+        IIOImage i1 = reader.readAll(0, param1), i2 = reader.readAll(1, param2);
+        BufferedImage
+            bi1 = (BufferedImage) i1.getRenderedImage(),
+            bi2 = (BufferedImage) i2.getRenderedImage();
+
+        // check rendered images, just in case
+        checkBufferedImages(bi1, bi2);
+
+        TIFFDirectory
+            dir1 = TIFFDirectory.createFromMetadata(i1.getMetadata()),
+            dir2 = TIFFDirectory.createFromMetadata(i2.getMetadata());
+
+        // check ASCII fields
+        checkASCIIField(
+            dir1, "image 1 description", DESCRIPTION_1, N_DESCRIPTION);
+        checkASCIIField(
+            dir2, "image 2 description", DESCRIPTION_2, N_DESCRIPTION);
+
+        checkASCIIField(dir1, "image 1 datetime", EXIF_DATA_1, N_EXIF);
+        checkASCIIField(dir2, "image 2 datetime", EXIF_DATA_2, N_EXIF);
+
+        // check sizes
+        TIFFField f = dir1.getTIFFField(N_WIDTH);
+        check((f.getCount() == 1) && (f.getAsInt(0) == W1),
+            "invalid width field for image 1");
+        f = dir2.getTIFFField(N_WIDTH);
+        check((f.getCount() == 1) && (f.getAsInt(0) == W2),
+            "invalid width field for image 2");
+
+        f = dir1.getTIFFField(N_HEIGHT);
+        check((f.getCount() == 1) && (f.getAsInt(0) == H1),
+            "invalid height field for image 1");
+        f = dir2.getTIFFField(N_HEIGHT);
+        check((f.getCount() == 1) && (f.getAsInt(0) == H2),
+            "invalid height field for image 2");
+
+        // check fax data
+        check(dir1.containsTIFFField(N_FAX), "image 2 TIFF directory " +
+            "must contain clean fax data");
+        f = dir1.getTIFFField(N_FAX);
+        check(
+            (f.getCount() == 1) && f.isIntegral() && (f.getAsInt(0) == FAX_DATA),
+            "invalid clean fax data");
+
+        check(!dir2.containsTIFFField(N_FAX), "image 2 TIFF directory " +
+            "must not contain fax fields");
+
+        // check GPS data
+        checkASCIIField(dir1, "GPS status", GPS_DATA, N_GPS);
+
+        check(!dir2.containsTIFFField(N_GPS), "image 2 TIFF directory " +
+            "must not contain GPS fields");
+
+        // check ICC profile data
+        check(!dir1.containsTIFFField(N_ICC), "image 1 TIFF directory "
+            + "must not contain ICC Profile field");
+        check(dir2.containsTIFFField(N_ICC), "image 2 TIFF directory "
+            + "must contain ICC Profile field");
+
+        f = dir2.getTIFFField(N_ICC);
+        check(f.getType() == TIFFTag.TIFF_UNDEFINED,
+            "invalid ICC profile field type");
+        int cnt = f.getCount();
+        byte icc[] = f.getAsBytes();
+        check((cnt == ICC_PROFILE_2.length) && (cnt == icc.length),
+                "invalid ICC profile");
+        for (int i = 0; i < cnt; i++) {
+            check(icc[i] == ICC_PROFILE_2[i], "invalid ICC profile data");
+        }
+
+        // check component sizes
+        check(dir1.getTIFFField(N_BPS).isIntegral() &&
+              dir2.getTIFFField(N_BPS).isIntegral(),
+              "invalid bits per sample type");
+        int sz1[] = bi1.getColorModel().getComponentSize(),
+            sz2[] = bi2.getColorModel().getComponentSize(),
+            bps1[] = dir1.getTIFFField(N_BPS).getAsInts(),
+            bps2[] = dir2.getTIFFField(N_BPS).getAsInts();
+
+        check((bps1.length == sz1.length) && (bps2.length == sz2.length),
+            "invalid component size count");
+
+        for (int i = 0; i < bps1.length; i++) {
+            check(bps1[i] == sz1[i], "image 1: invalid bits per sample data");
+        }
+
+        for (int i = 0; i < bps2.length; i++) {
+            check(bps2[i] == sz2[i], "image 2: invalid bits per sample data");
+        }
+
+        // check compression data
+        check(dir1.containsTIFFField(N_COMPRESSION) &&
+              dir2.containsTIFFField(N_COMPRESSION),
+              "compression info lost");
+        f = dir1.getTIFFField(N_COMPRESSION);
+        check(f.isIntegral() && (f.getCount() == 1) &&
+            (f.getAsInt(0) == COMPRESSION_1), "invalid image 1 compression data");
+
+        f = dir2.getTIFFField(N_COMPRESSION);
+        check(f.isIntegral() && (f.getCount() == 1) &&
+            (f.getAsInt(0) == COMPRESSION_2), "invalid image 2 compression data");
+
+        // check photometric interpretation
+        f = dir1.getTIFFField(N_PHOTO);
+        check(f.isIntegral() && (f.getCount() == 1) &&
+            ((f.getAsInt(0) == GRAY_1) || (f.getAsInt(0) == GRAY_2)),
+            "invalid photometric interpretation for image 1");
+
+        f = dir2.getTIFFField(N_PHOTO);
+        check(f.isIntegral() && (f.getCount() == 1) && (f.getAsInt(0) == RGB),
+            "invalid photometric interpretation for image 2");
+    }
+
+    public void run() {
+
+        try {
+            writeImage();
+            readAndCheckImage();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private void check(boolean ok, String msg) {
+
+        if (!ok) { throw new RuntimeException(msg); }
+    }
+
+    public static void main(String[] args) {
+        (new MultiPageImageTIFFFieldTest()).run();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/plugins/tiff/TIFFDirectoryTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 2016, 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     8149028
+ * @author  a.stepanov
+ * @summary some simple checks for TIFFDirectory
+ * @run     main TIFFDirectoryTest
+ */
+
+import java.util.List;
+import java.util.ArrayList;
+import javax.imageio.metadata.*;
+import javax.imageio.plugins.tiff.*;
+
+
+public class TIFFDirectoryTest {
+
+    private static void check(boolean ok, String msg) {
+        if (!ok) { throw new RuntimeException(msg); }
+    }
+
+    private void run() {
+
+        int type = TIFFTag.TIFF_LONG, dt = 1 << type;
+        int n0 = 1000, n1 = 1001, n2 = 1002, n3 = 1003;
+
+        TIFFTag tag1 = new TIFFTag(Integer.toString(n1), n1, dt);
+        TIFFTag tag2 = new TIFFTag(Integer.toString(n2), n2, dt);
+        TIFFTag tag3 = new TIFFTag(Integer.toString(n3), n3, dt);
+        TIFFTag parent = new TIFFTag(Integer.toString(n0), n0, dt);
+
+        // tag sets array must not be null
+        boolean ok = false;
+        try { new TIFFDirectory(null, parent); }
+        catch (NullPointerException e) { ok = true; }
+        check(ok, "can construct TIFFDirectory with null tagsets array");
+
+        // but can be empty
+        TIFFTagSet emptySets[] = {};
+        TIFFDirectory d = new TIFFDirectory(emptySets, parent);
+        check(d.getTagSets().length == 0, "invalid number of tag sets");
+        check(d.getParentTag().getName().equals(Integer.toString(n0)) &&
+             (d.getParentTag().getNumber() == n0), "invalid parent tag");
+
+
+        // add tags
+        List<TIFFTag> tags = new ArrayList<>();
+        tags.add(tag1);
+        tags.add(tag2);
+        TIFFTagSet ts1 = new TIFFTagSet(tags);
+
+        tags.clear();
+        tags.add(tag3);
+        TIFFTagSet ts2 = new TIFFTagSet(tags);
+
+        TIFFTagSet sets[] = {ts1, ts2};
+        d = new TIFFDirectory(sets, parent);
+
+        check(d.getTagSets().length == sets.length, "invalid number of tag sets");
+
+        // check getTag()
+        for (int i = n1; i <= n3; i++) {
+            TIFFTag t = d.getTag(i);
+            check(t.getNumber() == i, "invalid tag number");
+            check(t.getName().equals(Integer.toString(i)), "invalid tag name");
+            check(t.getDataTypes() == dt, "invalid tag data types");
+        }
+
+        TIFFDirectory d2;
+        try { d2 = d.clone(); }
+        catch (CloneNotSupportedException e) { throw new RuntimeException(e); }
+
+        // check removeTagSet()
+        d.removeTagSet(ts2);
+        check(d.getTagSets().length == 1, "invalid number of tag sets");
+        check(d.getTagSets()[0].getTag(n1).getName().equals(Integer.toString(n1)),
+            "invalid tag name");
+        check(d.getTagSets()[0].getTag(n2).getName().equals(Integer.toString(n2)),
+            "invalid tag name");
+
+        d.removeTagSet(ts1);
+        check(d.getTagSets().length == 0, "invalid number of tag sets");
+
+        // check cloned data
+        check(d2.getTagSets().length == sets.length,
+            "invalid number of tag sets");
+        TIFFTagSet sets2[] = d2.getTagSets();
+        check(sets2.length == sets.length, "invalid number of tag sets");
+        check(
+            (sets2[0].getTag(Integer.toString(n1)).getNumber() == n1) &&
+            (sets2[0].getTag(Integer.toString(n2)).getNumber() == n2) &&
+            (sets2[0].getTag(Integer.toString(n0)) == null) &&
+            (sets2[1].getTag(Integer.toString(n3)).getNumber() == n3) &&
+            (sets2[1].getTag(Integer.toString(n0)) == null), "invalid data");
+
+        check(
+            (sets2[0].getTag(Integer.toString(n1)).getDataTypes() == dt) &&
+            (sets2[0].getTag(Integer.toString(n2)).getDataTypes() == dt) &&
+            (sets2[1].getTag(Integer.toString(n3)).getDataTypes() == dt),
+            "invalid data type");
+
+        // must not be able to call removeTagSet with null argument
+        ok = false;
+        try { d.removeTagSet(null); }
+        catch (NullPointerException e) { ok = true; }
+        check(ok, "must not be able to use null as an argument for remove");
+
+        // check parent tag
+        check( d.getParentTag().getName().equals(Integer.toString(n0)) &&
+              d2.getParentTag().getName().equals(Integer.toString(n0)),
+            "invalid parent tag name");
+
+        check(( d.getParentTag().getNumber() == n0) &&
+              (d2.getParentTag().getNumber() == n0),
+            "invalid parent tag number");
+
+        check(( d.getParentTag().getDataTypes() == dt) &&
+              (d2.getParentTag().getDataTypes() == dt),
+            "invalid parent data type");
+
+        d.addTagSet(ts1);
+        d.addTagSet(ts2);
+
+        // add the same tag set twice and check that nothing changed
+        d.addTagSet(ts2);
+
+        check(d.getTagSets().length == 2, "invalid number of tag sets");
+
+        // check field operations
+        check(d.getNumTIFFFields() == 0, "invalid TIFFFields number");
+        check(d.getTIFFField(Integer.MAX_VALUE) == null,
+            "must return null TIFFField");
+
+        long offset = 4L;
+        long a[] = {Long.MIN_VALUE, 0, Long.MAX_VALUE};
+        int v = 100500;
+        TIFFField
+                f1 = new TIFFField(tag1, type, offset, d),
+                f2 = new TIFFField(tag2, v),
+                f3 = new TIFFField(tag3, type, a.length, a);
+
+        d.addTIFFField(f1);
+        d.addTIFFField(f2);
+        d.addTIFFField(f3);
+
+        check(d.containsTIFFField(n1) &&
+              d.containsTIFFField(n2) &&
+              d.containsTIFFField(n3) &&
+             !d.containsTIFFField(n0), "invalid containsTIFFField() results");
+
+        check(d.getTIFFField(n0) == null, "can get unadded field");
+
+        check(d.getNumTIFFFields() == 3, "invalid TIFFFields number");
+
+        check(d.getTIFFField(n1).getCount() == 1, "invalid TIFFField count");
+        check(d.getTIFFField(n1).getAsLong(0) == offset, "invalid offset");
+
+        check(d.getTIFFField(n2).getCount() == 1, "invalid TIFFField count");
+        check(d.getTIFFField(n2).getAsInt(0) == v, "invalid TIFFField value");
+
+        check(d.getTIFFField(n3).getCount() == a.length,
+            "invalid TIFFField count");
+        for (int i = 0; i < a.length; ++i) {
+            check(d.getTIFFField(n3).getAsLong(i) == a[i],
+                "invalid TIFFField value");
+        }
+
+        TIFFField nested = d.getTIFFField(n1).getDirectory().getTIFFField(n1);
+        check(nested.getTag().getNumber() == n1, "invalid tag number");
+        check(nested.getCount() == 1, "invalid field count");
+        check(nested.getAsLong(0) == offset, "invalid offset");
+
+        // check that the field is overwritten correctly
+        int v2 = 1 << 16;
+        d.addTIFFField(new TIFFField(tag3, v2));
+        check(d.getTIFFField(n3).getCount() == 1, "invalid TIFFField count");
+        check(d.getTIFFField(n3).getAsInt(0)== v2, "invalid TIFFField value");
+        check(d.getNumTIFFFields() == 3, "invalid TIFFFields number");
+
+        // check removeTIFFField()
+        d.removeTIFFField(n3);
+        check(d.getNumTIFFFields() == 2, "invalid TIFFFields number");
+        check(d.getTIFFField(n3) == null, "can get removed field");
+
+        d.removeTIFFFields();
+        check((d.getTIFFField(n1) == null) && (d.getTIFFField(n2) == null),
+            "can get removed field");
+        check((d.getNumTIFFFields() == 0) && (d.getTIFFFields().length == 0),
+            "invalid TIFFFields number");
+
+        // check that array returned by getTIFFFields() is sorted
+        // by tag number (as it stated in the docs)
+        d.addTIFFField(f3);
+        d.addTIFFField(f1);
+        d.addTIFFField(f2);
+
+        TIFFField fa[] = d.getTIFFFields();
+        check(fa.length == 3, "invalid number of fields");
+        check((fa[0].getTagNumber() == n1) &&
+              (fa[1].getTagNumber() == n2) &&
+              (fa[2].getTagNumber() == n3),
+            "array of the fields must be sorted by tag number");
+
+        d.removeTIFFFields();
+        d.addTIFFField(f2);
+
+        // test getAsMetaData / createFromMetadata
+        try {
+            d2 = TIFFDirectory.createFromMetadata(d.getAsMetadata());
+        } catch (IIOInvalidTreeException e) {
+            throw new RuntimeException(e);
+        }
+
+        // check new data
+        check(d2.getTagSets().length == sets.length,
+            "invalid number of tag sets");
+        sets2 = d2.getTagSets();
+        check(sets2.length == sets.length, "invalid number of tag sets");
+        check(
+            (sets2[0].getTag(Integer.toString(n1)).getNumber() == n1) &&
+            (sets2[0].getTag(Integer.toString(n2)).getNumber() == n2) &&
+            (sets2[0].getTag(Integer.toString(n0)) == null) &&
+            (sets2[1].getTag(Integer.toString(n3)).getNumber() == n3) &&
+            (sets2[1].getTag(Integer.toString(n0)) == null), "invalid data");
+
+        check(
+            (sets2[0].getTag(Integer.toString(n1)).getDataTypes() == dt) &&
+            (sets2[0].getTag(Integer.toString(n2)).getDataTypes() == dt) &&
+            (sets2[1].getTag(Integer.toString(n3)).getDataTypes() == dt),
+            "invalid data type");
+
+        check(!d2.containsTIFFField(n1) &&
+               d2.containsTIFFField(n2) &&
+              !d2.containsTIFFField(n3), "invalid containsTIFFField() results");
+        check(d2.getTIFFField(n2).getCount()  == 1, "invalid TIFFField count");
+        check(d2.getTIFFField(n2).getAsInt(0) == v, "invalid TIFFField value");
+
+        check((d2.getParentTag().getNumber() == n0) &&
+               d2.getParentTag().getName().equals(Integer.toString(n0)),
+               "invalid parent tag");
+    }
+
+    public static void main(String[] args) { (new TIFFDirectoryTest()).run(); }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/plugins/tiff/TIFFDirectoryWriteReadTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2016, 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     8149028
+ * @author  a.stepanov
+ * @summary a simple write-read test for TIFFDirectory
+ * @run     main TIFFDirectoryWriteReadTest
+ */
+
+import java.awt.*;
+import java.awt.color.*;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import javax.imageio.*;
+import javax.imageio.metadata.*;
+import javax.imageio.stream.*;
+import javax.imageio.plugins.tiff.*;
+
+
+public class TIFFDirectoryWriteReadTest {
+
+    private final static String FILENAME = "test.tiff";
+    private final static int SZ = 100;
+    private final static Color C = Color.RED;
+
+    private static final String COPYRIGHT[] = {"Copyright 123ABC.."};
+    private static final String DESCRIPTION[] = {"Test Image", "Description"};
+    private static final String SOFTWARE[] = {"test", "software", "123"};
+
+    private static final long RES_X[][] = {{2, 1}}, RES_Y[][] = {{1, 1}};
+
+    private static final byte[] ICC_PROFILE =
+        ICC_ProfileRGB.getInstance(ColorSpace.CS_sRGB).getData();
+
+
+    private ImageWriter getTIFFWriter() {
+
+        java.util.Iterator<ImageWriter> writers =
+            ImageIO.getImageWritersByFormatName("TIFF");
+        if (!writers.hasNext()) {
+            throw new RuntimeException("No writers available for TIFF format");
+        }
+        return writers.next();
+    }
+
+    private ImageReader getTIFFReader() {
+
+        java.util.Iterator<ImageReader> readers =
+            ImageIO.getImageReadersByFormatName("TIFF");
+        if (!readers.hasNext()) {
+            throw new RuntimeException("No readers available for TIFF format");
+        }
+        return readers.next();
+    }
+
+    private void addASCIIField(TIFFDirectory d,
+                               String        name,
+                               String        data[],
+                               int           num) {
+
+        d.addTIFFField(new TIFFField(
+            new TIFFTag(name, num, 1 << TIFFTag.TIFF_ASCII),
+                TIFFTag.TIFF_ASCII, data.length, data));
+    }
+
+    private void checkASCIIField(TIFFDirectory d,
+                                 String        what,
+                                 String        data[],
+                                 int           num) {
+
+        String notFound = what + " field was not found";
+        check(d.containsTIFFField(num), notFound);
+        TIFFField f = d.getTIFFField(num);
+        check(f.getType() == TIFFTag.TIFF_ASCII, "field type != ASCII");
+        check(f.getCount() == data.length, "invalid " + what + " data count");
+        for (int i = 0; i < data.length; i++) {
+            check(f.getValueAsString(i).equals(data[i]),
+                "invalid " + what + " data");
+        }
+    }
+
+    private void writeImage() throws Exception {
+
+        OutputStream s = new BufferedOutputStream(new FileOutputStream(FILENAME));
+        try (ImageOutputStream ios = ImageIO.createImageOutputStream(s)) {
+
+            ImageWriter writer = getTIFFWriter();
+            writer.setOutput(ios);
+
+            BufferedImage img = new BufferedImage(
+                SZ, SZ, BufferedImage.TYPE_INT_RGB);
+            Graphics g = img.getGraphics();
+            g.setColor(C);
+            g.fillRect(0, 0, SZ, SZ);
+            g.dispose();
+
+            IIOMetadata metadata = writer.getDefaultImageMetadata(
+                new ImageTypeSpecifier(img), writer.getDefaultWriteParam());
+
+            TIFFDirectory dir = TIFFDirectory.createFromMetadata(metadata);
+
+            addASCIIField(dir, "Copyright",
+                COPYRIGHT, BaselineTIFFTagSet.TAG_COPYRIGHT);
+
+            addASCIIField(dir, "ImageDescription",
+                DESCRIPTION, BaselineTIFFTagSet.TAG_IMAGE_DESCRIPTION);
+
+            addASCIIField(dir, "Software",
+                SOFTWARE, BaselineTIFFTagSet.TAG_SOFTWARE);
+
+            dir.addTIFFField(new TIFFField(
+                new TIFFTag("XResolution", BaselineTIFFTagSet.TAG_X_RESOLUTION,
+                1 << TIFFTag.TIFF_RATIONAL), TIFFTag.TIFF_RATIONAL, 1, RES_X));
+            dir.addTIFFField(new TIFFField(
+                new TIFFTag("YResolution", BaselineTIFFTagSet.TAG_Y_RESOLUTION,
+                1 << TIFFTag.TIFF_RATIONAL), TIFFTag.TIFF_RATIONAL, 1, RES_Y));
+
+            dir.addTIFFField(new TIFFField(
+            new TIFFTag("ICC Profile", BaselineTIFFTagSet.TAG_ICC_PROFILE,
+                1 << TIFFTag.TIFF_UNDEFINED),
+                TIFFTag.TIFF_UNDEFINED, ICC_PROFILE.length, ICC_PROFILE));
+
+            IIOMetadata data = dir.getAsMetadata();
+            writer.write(new IIOImage(img, null, data));
+
+            ios.flush();
+            writer.dispose();
+        }
+        s.close();
+    }
+
+
+
+    private void readAndCheckImage() throws Exception {
+
+        ImageReader reader = getTIFFReader();
+
+        ImageInputStream s = ImageIO.createImageInputStream(new File(FILENAME));
+        reader.setInput(s);
+
+        int ni = reader.getNumImages(true);
+        check(ni == 1, "invalid number of images");
+
+        // check image
+        BufferedImage img = reader.read(0);
+        check(img.getWidth() == SZ && img.getHeight() == SZ,
+            "invalid image size");
+
+        Color c = new Color(img.getRGB(SZ / 2, SZ / 2));
+        check(C.equals(c), "invalid image color");
+
+        IIOMetadata metadata = reader.readAll(0, null).getMetadata();
+        TIFFDirectory dir = TIFFDirectory.createFromMetadata(metadata);
+
+        reader.dispose();
+        s.close();
+
+        // ===== perform tag checks =====
+
+        checkASCIIField(dir, "copyright", COPYRIGHT,
+            BaselineTIFFTagSet.TAG_COPYRIGHT);
+
+        checkASCIIField(dir, "description", DESCRIPTION,
+            BaselineTIFFTagSet.TAG_IMAGE_DESCRIPTION);
+
+        checkASCIIField(dir, "software", SOFTWARE,
+            BaselineTIFFTagSet.TAG_SOFTWARE);
+
+        TIFFField f = dir.getTIFFField(BaselineTIFFTagSet.TAG_IMAGE_WIDTH);
+        check(f.getCount() == 1, "invalid width field count");
+        int w = f.getAsInt(0);
+        check(w == SZ, "invalid width");
+
+        f = dir.getTIFFField(BaselineTIFFTagSet.TAG_IMAGE_LENGTH);
+        check(f.getCount() == 1, "invalid height field count");
+        int h = f.getAsInt(0);
+        check(h == SZ, "invalid height");
+
+        f = dir.getTIFFField(BaselineTIFFTagSet.TAG_BITS_PER_SAMPLE);
+        // RGB: 3 x 8 bits for R, G and B components
+        int bps[] = f.getAsInts();
+        check((f.getCount() == 3) && (bps.length == 3), "invalid BPS count");
+        for (int b: bps) { check(b == 8, "invalid bits per sample"); }
+
+        // RGB: PhotometricInterpretation = 2
+        f = dir.getTIFFField(BaselineTIFFTagSet.TAG_PHOTOMETRIC_INTERPRETATION);
+        check(f.getCount() == 1, "invalid count");
+        check(f.getAsInt(0) == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_RGB,
+            "invalid photometric interpretation value");
+
+        String rat = " resolution must be rational";
+        f = dir.getTIFFField(BaselineTIFFTagSet.TAG_X_RESOLUTION);
+        check(f.getType() == TIFFTag.TIFF_RATIONAL, "x" + rat);
+        check(f.getCount() == 1 &&
+              f.getAsInt(0) == (int) (RES_X[0][0] / RES_X[0][1]),
+              "invalid x resolution");
+
+        f = dir.getTIFFField(BaselineTIFFTagSet.TAG_Y_RESOLUTION);
+        check(f.getType() == TIFFTag.TIFF_RATIONAL, "y" + rat);
+        check(f.getCount() == 1 &&
+              f.getAsInt(0) == (int) (RES_Y[0][0] / RES_Y[0][1]),
+              "invalid y resolution");
+
+        f = dir.getTIFFField(BaselineTIFFTagSet.TAG_ICC_PROFILE);
+        check(f.getType() == TIFFTag.TIFF_UNDEFINED,
+            "invalid ICC profile field type");
+        int cnt = f.getCount();
+        byte icc[] = f.getAsBytes();
+        check((cnt == ICC_PROFILE.length) && (cnt == icc.length),
+                "invalid ICC profile");
+        for (int i = 0; i < cnt; i++) {
+            check(icc[i] == ICC_PROFILE[i], "invalid ICC profile");
+        }
+    }
+
+    public void run() {
+
+        try {
+            writeImage();
+            readAndCheckImage();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+
+    }
+
+    private void check(boolean ok, String msg) {
+        if (!ok) { throw new RuntimeException(msg); }
+    }
+
+    public static void main(String[] args) {
+        (new TIFFDirectoryWriteReadTest()).run();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/plugins/tiff/TIFFFieldTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,502 @@
+/*
+ * Copyright (c) 2016, 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     8152183
+ * @author  a.stepanov
+ * @summary Some checks for TIFFField methods
+ * @run     main TIFFFieldTest
+ */
+
+import java.util.List;
+import java.util.ArrayList;
+import javax.imageio.metadata.IIOMetadataNode;
+import javax.imageio.plugins.tiff.*;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+public class TIFFFieldTest {
+
+    private final static String NAME = "tag"; // tag name
+    private final static int    NUM  = 12345; // tag number
+    private final static int MIN_TYPE = TIFFTag.MIN_DATATYPE;
+    private final static int MAX_TYPE = TIFFTag.MAX_DATATYPE;
+    private final static String CONSTRUCT = "can construct TIFFField with ";
+
+    private void check(boolean ok, String msg) {
+        if (!ok) { throw new RuntimeException(msg); }
+    }
+
+    private void testConstructors() {
+
+        // test constructors
+
+        TIFFTag tag = new TIFFTag(
+            NAME, NUM, 1 << TIFFTag.TIFF_SHORT | 1 << TIFFTag.TIFF_LONG);
+        TIFFField f;
+
+        // constructor: TIFFField(tag, value)
+        boolean ok = false;
+        try { new TIFFField(null, 0); }
+        catch (NullPointerException e) { ok = true; }
+        check(ok, CONSTRUCT + "null tag");
+
+        ok = false;
+        try { new TIFFField(tag, -1); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, CONSTRUCT + "invalid count");
+
+        // check value type recognition
+        int v = 1 << 16;
+        f = new TIFFField(tag, v - 1);
+        check(f.getType() == TIFFTag.TIFF_SHORT, "must be treated as short");
+        check(f.isIntegral(), "must be integral");
+        f = new TIFFField(tag, v);
+        check(f.getType() == TIFFTag.TIFF_LONG, "must be treated as long");
+
+        // other checks
+        check(f.getAsLongs().length == 1, "invalid long[] size");
+        check(f.isIntegral(), "must be integral");
+        check((f.getDirectory() == null) && !f.hasDirectory(),
+            "must not have directory");
+        check(f.getValueAsString(0).equals(String.valueOf(v)),
+            "invalid string representation of value");
+        check(f.getTag().getNumber() == f.getTagNumber(),
+            "invalid tag number");
+        check(f.getCount() == 1, "invalid count");
+        check(f.getTagNumber() == NUM, "invalid tag number");
+
+        // constructor: TIFFField(tag, type, count)
+        int type = TIFFTag.TIFF_SHORT;
+
+        ok = false;
+        try { new TIFFField(null, type, 1); }
+        catch (NullPointerException e) { ok = true; }
+        check(ok, CONSTRUCT + "null tag");
+
+        ok = false;
+        try { new TIFFField(tag, MAX_TYPE + 1, 1); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, CONSTRUCT + "invalid type tag");
+
+        // check that count == 1 for TIFF_IFD_POINTER
+        ok = false;
+        try { new TIFFField(tag, TIFFTag.TIFF_IFD_POINTER, 0); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, "only count = 1 should be allowed for IFDPointer");
+
+        ok = false;
+        try { new TIFFField(tag, TIFFTag.TIFF_IFD_POINTER, 2); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, "only count = 1 should be allowed for IFDPointer");
+
+        // check that count == 0 is not allowed for TIFF_RATIONAL, TIFF_SRATIONAL
+        // (see fix for JDK-8149120)
+        ok = false;
+        try { new TIFFField(tag, TIFFTag.TIFF_RATIONAL, 0); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, "count = 0 should not be allowed for Rational");
+
+        ok = false;
+        try { new TIFFField(tag, TIFFTag.TIFF_SRATIONAL, 0); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, "count = 0 should not be allowed for SRational");
+
+        ok = false;
+        try { new TIFFField(tag, type, -1); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, CONSTRUCT + "with invalid data count");
+
+        f = new TIFFField(tag, type, 0);
+        check(f.getCount() == 0, "invalid count");
+        check(!f.hasDirectory(), "must not have directory");
+
+        // constructor: TIFFField(tag, type, count, data)
+        double a[] = {0.1, 0.2, 0.3};
+        ok = false;
+        try { new TIFFField(null, TIFFTag.TIFF_DOUBLE, a.length, a); }
+        catch (NullPointerException e) { ok = true; }
+        check(ok, CONSTRUCT + "null tag");
+
+        ok = false;
+        try { new TIFFField(tag, type, a.length - 1, a); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, CONSTRUCT + "invalid data count");
+
+        String a2[] = {"one", "two"};
+        ok = false;
+        try { new TIFFField(tag, type, 2, a2); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, CONSTRUCT + "invalid data type");
+        check((f.getDirectory() == null) && !f.hasDirectory(),
+            "must not have directory");
+
+        // constructor: TIFFField(tag, type, offset, dir)
+        List<TIFFTag> tags = new ArrayList<>();
+        tags.add(tag);
+        TIFFTagSet sets[] = {new TIFFTagSet(tags)};
+        TIFFDirectory dir = new TIFFDirectory(sets, null);
+
+        ok = false;
+        try { new TIFFField(null, type, 4L, dir); }
+        catch (NullPointerException e) { ok = true; }
+        check(ok, CONSTRUCT + "null tag");
+
+        ok = false;
+        try { new TIFFField(tag, type, 0L, dir); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, CONSTRUCT + "non-positive offset");
+
+        long offset = 4;
+
+        for (int t = MIN_TYPE; t <= MAX_TYPE; t++) {
+
+            tag = new TIFFTag(NAME, NUM, 1 << t);
+
+            // only TIFF_LONG and TIFF_IFD_POINTER types are allowed
+            if (t == TIFFTag.TIFF_LONG || t == TIFFTag.TIFF_IFD_POINTER) {
+
+                f = new TIFFField(tag, t, offset, dir);
+                check(f.hasDirectory(), "must have directory");
+
+                check(f.getDirectory().getTag(NUM).getName().equals(NAME),
+                    "invalid tag name");
+
+                check(f.getCount() == 1, "invalid count");
+                check(f.getAsLong(0) == offset, "invalid offset");
+            } else {
+                ok = false;
+                try { new TIFFField(tag, t, offset, dir); }
+                catch (IllegalArgumentException e) { ok = true; }
+                check(ok, CONSTRUCT + "invalid data type");
+            }
+        }
+
+        type = TIFFTag.TIFF_IFD_POINTER;
+        tag = new TIFFTag(NAME, NUM, 1 << type);
+        ok = false;
+        try { new TIFFField(tag, type, offset, null); }
+        catch (NullPointerException e) { ok = true; }
+        check(ok, CONSTRUCT + "null TIFFDirectory");
+
+        type = TIFFTag.TIFF_LONG;
+        tag = new TIFFTag(NAME, NUM, 1 << type);
+        ok = false;
+        try { new TIFFField(tag, type, offset, null); }
+        catch (NullPointerException e) { ok = true; }
+        check(ok, CONSTRUCT + "null TIFFDirectory");
+    }
+
+    private void testTypes() {
+
+        // test getTypeName(), getTypeByName() methods
+
+        boolean ok = false;
+        try { TIFFField.getTypeName(MIN_TYPE - 1); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, "invalid data type number used");
+
+        ok = false;
+        try { TIFFField.getTypeName(MAX_TYPE + 1); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, "invalid data type number used");
+
+        for (int type = MIN_TYPE; type <= MAX_TYPE; type++) {
+            String name = TIFFField.getTypeName(type);
+            check(TIFFField.getTypeByName(name) == type, "invalid type");
+        }
+
+        for (int type = MIN_TYPE; type <= MAX_TYPE; type++) {
+
+            TIFFTag tag = new TIFFTag(NAME, NUM, 1 << type);
+            TIFFField f = new TIFFField(tag, type, 1);
+            check(f.getType() == type, "invalid type");
+
+            // check that invalid data types can not be used
+            for (int type2 = MIN_TYPE; type2 <= MAX_TYPE; ++type2) {
+                if (type2 != type) {
+                    ok = false;
+                    try { new TIFFField(tag, type2, 1); } // invalid type
+                    catch (IllegalArgumentException e) { ok = true; }
+                    check(ok, "invalid type was successfully set");
+                }
+            }
+        }
+    }
+
+    private void testGetAs() {
+
+        // test getAs...() methods
+
+        int type = TIFFTag.TIFF_SHORT;
+        TIFFTag tag = new TIFFTag(NAME, NUM, 1 << TIFFTag.TIFF_SHORT);
+
+        short v = 123;
+        TIFFField f = new TIFFField(tag, v);
+
+        check(f.getAsInt(0)    ==    (int) v, "invalid int value");
+        check(f.getAsLong(0)   ==   (long) v, "invalid long value");
+        check(f.getAsFloat(0)  ==  (float) v, "invalid float value");
+        check(f.getAsDouble(0) == (double) v, "invalid double value");
+        check(f.getValueAsString(0).equals(Short.toString(v)),
+            "invalid string representation");
+
+        check(f.getAsInts().length == 1, "inavlid array size");
+        check((int) v == f.getAsInts()[0], "invalid int value");
+
+        float fa[] = {0.01f, 1.01f};
+        type = TIFFTag.TIFF_FLOAT;
+        f = new TIFFField(
+            new TIFFTag(NAME, NUM, 1 << type), type, fa.length, fa);
+        check(f.getCount() == fa.length, "invalid count");
+        float fa2[] = f.getAsFloats();
+        check(fa2.length == fa.length, "invalid array size");
+
+        for (int i = 0; i < fa.length; i++) {
+            check(fa2[i] == fa[i], "invalid value");
+            check(f.getAsDouble(i) == fa[i], "invalid value");
+            check(f.getAsInt(i) == (int) fa[i], "invalid value"); // cast to int
+            check(f.getValueAsString(i).equals(Float.toString(fa[i])),
+            "invalid string representation");
+        }
+
+        byte ba[] = {-1, -10, -100};
+        type = TIFFTag.TIFF_BYTE;
+        f = new TIFFField(
+            new TIFFTag(NAME, NUM, 1 << type), type, ba.length, ba);
+        check(f.getCount() == ba.length, "invalid count");
+        byte ba2[] = f.getAsBytes();
+        check(ba2.length == ba.length, "invalid count");
+
+        for (int i = 0; i < ba.length; i++) {
+            check(ba[i] == ba2[i], "invalid value");
+            check(ba[i] == (byte) f.getAsDouble(i), "invalid value");
+            check(ba[i] == (byte) f.getAsLong(i),   "invalid value");
+
+            int unsigned = ba[i] & 0xff;
+            check(f.getAsInt(i) == unsigned, "must be treated as unsigned");
+        }
+
+        char ca[] = {'a', 'z', 0xffff};
+        type = TIFFTag.TIFF_SHORT;
+        f = new TIFFField(
+            new TIFFTag(NAME, NUM, 1 << type), type, ca.length, ca);
+        check(f.getCount() == ca.length, "invalid count");
+        char ca2[] = f.getAsChars();
+        check(ba2.length == ba.length, "invalid count");
+
+        for (int i = 0; i < ca.length; i++) {
+            check(ca[i] == ca2[i], "invalid value");
+            check(ca[i] == (char) f.getAsDouble(i), "invalid value");
+            check(ca[i] == (char) f.getAsLong(i), "invalid value");
+            check(ca[i] == (char) f.getAsInt(i), "invalid value");
+        }
+
+        type = TIFFTag.TIFF_DOUBLE;
+        double da[] = {0.1, 0.2, 0.3};
+        f = new TIFFField(
+            new TIFFTag(NAME, NUM, 1 << type), type, da.length, da);
+        check(!f.isIntegral(), "isIntegral must be false");
+
+        double da2[] = f.getAsDoubles();
+        check(f.getData() instanceof double[], "invalid data type");
+        double da3[] = (double[]) f.getData();
+        check((da.length == da2.length) &&
+              (da.length == da2.length) &&
+              (da.length == f.getCount()),
+               "invalid data count");
+        for (int i = 0; i < da.length; ++i) {
+            check(da[i] == da2[i], "invalid data");
+            check(da[i] == da3[i], "invalid data");
+        }
+
+        boolean ok = false;
+        try { f.getAsShorts(); }
+        catch (ClassCastException e) { ok = true; }
+        check(ok, "invalid data cast");
+
+        ok = false;
+        try { f.getAsRationals(); }
+        catch (ClassCastException e) { ok = true; }
+        check(ok, "invalid data cast");
+
+        ok = false;
+        try { TIFFField.createArrayForType(TIFFTag.MIN_DATATYPE - 1, 1); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, "can create array with invalid datatype");
+
+        ok = false;
+        try { TIFFField.createArrayForType(TIFFTag.MAX_DATATYPE + 1, 1); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, "can create array with invalid datatype");
+
+        ok = false;
+        try { TIFFField.createArrayForType(TIFFTag.TIFF_FLOAT, -1); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, "can create array with negative count");
+
+        int n = 3;
+        Object
+            RA  = TIFFField.createArrayForType(TIFFTag.TIFF_RATIONAL,  n),
+            SRA = TIFFField.createArrayForType(TIFFTag.TIFF_SRATIONAL, n);
+        check(RA  instanceof long[][], "invalid data type");
+        check(SRA instanceof  int[][], "invalid data type");
+
+        long ra[][] = (long[][]) RA;
+        int sra[][] = (int[][]) SRA;
+        check((ra.length == n) && (sra.length == n), "invalid data size");
+        for (int i = 0; i < n; i++) {
+            check((ra[i].length == 2) && (sra[i].length == 2),
+                "invalid data size");
+            ra[i][0]  =  1;  ra[i][1]  = 5 + i;
+            sra[i][0] = -1;  sra[i][1] = 5 + i;
+        }
+
+        type = TIFFTag.TIFF_RATIONAL;
+        TIFFField f1 = new TIFFField(
+            new TIFFTag(NAME, NUM, 1 << type), type, n, ra);
+        type = TIFFTag.TIFF_SRATIONAL;
+        TIFFField f2 = new TIFFField(
+            new TIFFTag(NAME, NUM, 1 << type), type, n, sra);
+
+        check((f1.getCount() == ra.length) && (f2.getCount() == sra.length),
+            "invalid data count");
+
+        check(f1.getAsRationals().length  == n, "invalid data count");
+        check(f2.getAsSRationals().length == n, "invalid data count");
+        for (int i = 0; i < n; i++) {
+            long r[] = f1.getAsRational(i);
+            check(r.length == 2, "invalid data format");
+            check((r[0] == 1) && (r[1] == i + 5), "invalid data");
+
+            int sr[] = f2.getAsSRational(i);
+            check(sr.length == 2, "invalid data format");
+            check((sr[0] == -1) && (sr[1] == i + 5), "invalid data");
+
+            // check string representation
+            String s = Long.toString(r[0]) + "/" + Long.toString(r[1]);
+            check(s.equals(f1.getValueAsString(i)),
+                "invalid string representation");
+
+            s = Integer.toString(sr[0]) + "/" + Integer.toString(sr[1]);
+            check(s.equals(f2.getValueAsString(i)),
+                "invalid string representation");
+
+            // see the documentation for getAsInt:
+            // TIFF_SRATIONAL or TIFF_RATIONAL format are evaluated
+            // by dividing the numerator into the denominator using
+            // double-precision arithmetic and then casting to int
+            check(f1.getAsInt(i) == (int)(r[0] / r[1]),
+                "invalid result for getAsInt");
+            check(f2.getAsInt(i) == (int)(r[0] / r[1]),
+                "invalid result for getAsInt");
+        }
+
+        ok = false;
+        try { f1.getAsRational(ra.length); }
+        catch (ArrayIndexOutOfBoundsException e) { ok = true; }
+        check(ok, "invalid index");
+
+        String sa[] = {"-1.e-25", "22", "-1.23E5"};
+        type = TIFFTag.TIFF_ASCII;
+        f = new TIFFField(
+            new TIFFTag(NAME, NUM, 1 << type), type, sa.length, sa);
+
+        // test clone() method
+        TIFFField cloned = null;
+        try { cloned = f.clone(); } catch (CloneNotSupportedException e) {
+            throw new RuntimeException(e);
+        }
+
+        check(f.getCount() == cloned.getCount(), "invalid cloned field count");
+
+        check(f.getCount() == sa.length, "invalid data count");
+        for (int i = 0; i < sa.length; i++) {
+            check(sa[i].equals(f.getAsString(i)), "invalid data");
+            // see docs: "data in TIFF_ASCII format will be parsed as by
+            // the Double.parseDouble method, with the result cast to int"
+            check(f.getAsInt(i) ==
+                (int) Double.parseDouble(sa[i]), "invalid data");
+            check(f.getAsDouble(i) == Double.parseDouble(sa[i]), "invalid data");
+
+            check(sa[i].equals(cloned.getAsString(i)), "invalid cloned data");
+        }
+    }
+
+    private void testCreateFromNode() {
+
+        int type = TIFFTag.TIFF_LONG;
+
+        List<TIFFTag> tags = new ArrayList<>();
+        int v = 1234567;
+        TIFFTag tag = new TIFFTag(NAME, NUM, 1 << type);
+        tags.add(tag);
+        TIFFTagSet ts = new TIFFTagSet(tags);
+
+        boolean ok = false;
+        try { TIFFField.createFromMetadataNode(ts, null); }
+        catch (NullPointerException e) { ok = true; }
+        check(ok, "can create TIFFField from a null node");
+
+        TIFFField f = new TIFFField(tag, v);
+        Node node = f.getAsNativeNode();
+        check(node.getNodeName().equals(f.getClass().getSimpleName()),
+            "invalid node name");
+
+        NamedNodeMap attrs = node.getAttributes();
+        for (int i = 0; i < attrs.getLength(); i++) {
+            String an = attrs.item(i).getNodeName().toLowerCase();
+            String av = attrs.item(i).getNodeValue();
+            if (an.contains("name")) {
+                check(av.equals(NAME), "invalid tag name");
+            } else if (an.contains("number")) {
+                check(av.equals(Integer.toString(NUM)), "invalid tag number");
+            }
+        }
+
+        // invalid node
+        IIOMetadataNode nok = new IIOMetadataNode("NOK");
+
+        ok = false;
+        try { TIFFField.createFromMetadataNode(ts, nok); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, CONSTRUCT + "invalid node name");
+
+        TIFFField f2 = TIFFField.createFromMetadataNode(ts, node);
+        check(f2.getType() == type, "invalid type");
+        check(f2.getTagNumber() == NUM, "invalid tag number");
+        check(f2.getTag().getName().equals(NAME), "invalid tag name");
+        check(f2.getCount()  == 1, "invalid count");
+        check(f2.getAsInt(0) == v, "invalid value");
+    }
+
+    public static void main(String[] args) {
+
+        TIFFFieldTest test = new TIFFFieldTest();
+        test.testConstructors();
+        test.testCreateFromNode();
+        test.testTypes();
+        test.testGetAs();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/plugins/tiff/TIFFImageReadParamTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2016, 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     8149028
+ * @author  a.stepanov
+ * @summary check TIFFDirectory manipulation
+ *          by means of TIFFImageReadParam
+ * @run     main TIFFImageReadParamTest
+ */
+
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import javax.imageio.*;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.plugins.tiff.*;
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.ImageOutputStream;
+
+public class TIFFImageReadParamTest {
+
+    private final static String FILENAME = "test.tiff";
+    private final static int SZ = 100;
+    private final static Color C = Color.RED;
+
+    private final static String GEO_DATA = "test params";
+    private final static int GEO_N = GeoTIFFTagSet.TAG_GEO_ASCII_PARAMS;
+
+    private final static String EXIF_DATA = "2000:01:01 00:00:01";
+    private final static int EXIF_N = ExifTIFFTagSet.TAG_DATE_TIME_ORIGINAL;
+
+    private final static String GPS_DATA =
+        ExifGPSTagSet.STATUS_MEASUREMENT_IN_PROGRESS;
+    private final static int GPS_N = ExifGPSTagSet.TAG_GPS_STATUS;
+
+    private final static short FAX_DATA =
+        FaxTIFFTagSet.CLEAN_FAX_DATA_ERRORS_UNCORRECTED;
+    private final static int FAX_N = FaxTIFFTagSet.TAG_CLEAN_FAX_DATA;
+
+    private ImageWriter getTIFFWriter() {
+
+        java.util.Iterator<ImageWriter> writers =
+            ImageIO.getImageWritersByFormatName("TIFF");
+        if (!writers.hasNext()) {
+            throw new RuntimeException("No writers available for TIFF format");
+        }
+        return writers.next();
+    }
+
+    private ImageReader getTIFFReader() {
+
+        java.util.Iterator<ImageReader> readers =
+            ImageIO.getImageReadersByFormatName("TIFF");
+        if (!readers.hasNext()) {
+            throw new RuntimeException("No readers available for TIFF format");
+        }
+        return readers.next();
+    }
+
+    private void check(boolean ok, String msg) {
+        if (!ok) { throw new RuntimeException(msg); }
+    }
+
+    private void addASCIIField(TIFFDirectory d,
+                               String        name,
+                               String        data,
+                               int           num) {
+
+        String a[] = {data};
+        d.addTIFFField(new TIFFField(
+            new TIFFTag(name, num, 1 << TIFFTag.TIFF_ASCII),
+                TIFFTag.TIFF_ASCII, 1, a));
+    }
+
+    private void checkASCIIValue(TIFFDirectory d,
+                                 String        what,
+                                 String        data,
+                                 int           num) {
+
+        TIFFField f = d.getTIFFField(num);
+        check(f.getType() == TIFFTag.TIFF_ASCII, "field type != ASCII");
+        check(f.getCount() == 1, "invalid " + what + " data count");
+        check(f.getValueAsString(0).equals(data),
+            "invalid " + what + " data");
+    }
+
+
+    private void writeImage() throws Exception {
+
+        OutputStream s = new BufferedOutputStream(new FileOutputStream(FILENAME));
+        try (ImageOutputStream ios = ImageIO.createImageOutputStream(s)) {
+            ImageWriter writer = getTIFFWriter();
+            writer.setOutput(ios);
+
+            BufferedImage img =
+                new BufferedImage(SZ, SZ, BufferedImage.TYPE_INT_RGB);
+            Graphics g = img.getGraphics();
+            g.setColor(C);
+            g.fillRect(0, 0, SZ, SZ);
+            g.dispose();
+
+            IIOMetadata metadata = writer.getDefaultImageMetadata(
+                new ImageTypeSpecifier(img), writer.getDefaultWriteParam());
+
+            TIFFDirectory dir = TIFFDirectory.createFromMetadata(metadata);
+
+            // add some extension tags
+            addASCIIField(dir, "GeoAsciiParamsTag", GEO_DATA, GEO_N);
+            addASCIIField(dir, "DateTimeOriginal", EXIF_DATA, EXIF_N);
+            addASCIIField(dir, "GPSStatus", GPS_DATA, GPS_N);
+
+            dir.addTIFFField(new TIFFField(new TIFFTag(
+                "CleanFaxData", FAX_N, 1 << TIFFTag.TIFF_SHORT), FAX_DATA));
+
+            IIOMetadata data = dir.getAsMetadata();
+
+            writer.write(new IIOImage(img, null, data));
+
+            ios.flush();
+            writer.dispose();
+        }
+    }
+
+    private void checkImage(BufferedImage img) {
+
+        check(img.getWidth() == SZ, "invalid image width");
+        check(img.getHeight() == SZ, "invalid image height");
+        Color c = new Color(img.getRGB(SZ / 2, SZ / 2));
+        check(c.equals(C), "invalid image color");
+    }
+
+    private TIFFDirectory getDir(TIFFTagSet[] add,
+                                 TIFFTagSet[] remove) throws Exception {
+
+        ImageReader reader = getTIFFReader();
+
+        ImageInputStream s = ImageIO.createImageInputStream(new File(FILENAME));
+        reader.setInput(s, false, true);
+
+        int ni = reader.getNumImages(true);
+        check(ni == 1, "invalid number of images: " + ni);
+
+        TIFFImageReadParam param = new TIFFImageReadParam();
+        for (TIFFTagSet ts: add) { param.addAllowedTagSet(ts); }
+        for (TIFFTagSet ts: remove) { param.removeAllowedTagSet(ts); }
+
+        IIOImage img = reader.readAll(0, param);
+
+        // just in case, check image
+        checkImage((BufferedImage) img.getRenderedImage());
+
+        IIOMetadata metadata = img.getMetadata();
+        TIFFDirectory dir = TIFFDirectory.createFromMetadata(metadata);
+
+        reader.dispose();
+        s.close();
+
+        return dir;
+    }
+
+    private void simpleChecks() {
+
+        TIFFImageReadParam param = new TIFFImageReadParam();
+
+        java.util.List<TIFFTagSet> allowed = param.getAllowedTagSets();
+
+        // see docs
+        check(allowed.contains(BaselineTIFFTagSet.getInstance()),
+            "must contain BaselineTIFFTagSet");
+        check(allowed.contains(FaxTIFFTagSet.getInstance()),
+            "must contain FaxTIFFTagSet");
+        check(allowed.contains(ExifParentTIFFTagSet.getInstance()),
+            "must contain ExifParentTIFFTagSet");
+        check(allowed.contains(GeoTIFFTagSet.getInstance()),
+            "must contain GeoTIFFTagSet");
+
+        TIFFTagSet gps = ExifGPSTagSet.getInstance();
+        param.addAllowedTagSet(gps);
+        check(param.getAllowedTagSets().contains(gps),
+            "must contain ExifGPSTagSet");
+
+        param.removeAllowedTagSet(gps);
+        check(!param.getAllowedTagSets().contains(gps),
+            "must not contain ExifGPSTagSet");
+
+        // check that repeating remove goes properly
+        param.removeAllowedTagSet(gps);
+
+        boolean ok = false;
+        try { param.addAllowedTagSet(null); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, "must not be able to add null tag set");
+
+        ok = false;
+        try { param.removeAllowedTagSet(null); }
+        catch (IllegalArgumentException e) { ok = true; }
+        check(ok, "must not be able to remove null tag set");
+    }
+
+    private void run() {
+
+        simpleChecks();
+
+        try {
+
+            writeImage();
+
+            TIFFTagSet
+                empty[] = {},
+                geo[]   = {  GeoTIFFTagSet.getInstance() },
+                exif[]  = { ExifTIFFTagSet.getInstance() },
+                gps[]   = {  ExifGPSTagSet.getInstance() },
+                fax[]   = {  FaxTIFFTagSet.getInstance() };
+
+            // default param state
+            TIFFDirectory dir = getDir(empty, empty);
+            // Geo and Fax are default allowed tag sets
+            check(dir.containsTIFFField(GEO_N), "must contain Geo field");
+            checkASCIIValue(dir, "Geo", GEO_DATA, GEO_N);
+            check(dir.containsTIFFField(FAX_N), "must contain Fax field");
+            check(
+                (dir.getTIFFField(FAX_N).getCount() == 1) &&
+                (dir.getTIFFField(FAX_N).getAsInt(0) == FAX_DATA),
+                "invalid Fax field value");
+
+            // corresponding tag sets are non-default
+            check(!dir.containsTIFFField(EXIF_N), "must not contain Geo field");
+            check(!dir.containsTIFFField(GPS_N), "must not contain GPS field");
+
+            // remove Fax
+            dir = getDir(empty, fax);
+            check(!dir.containsTIFFField(FAX_N), "must not contain Fax field");
+
+            // add EXIF, remove Geo
+            dir = getDir(exif, geo);
+            check(dir.containsTIFFField(EXIF_N), "must contain EXIF field");
+            checkASCIIValue(dir, "EXIF", EXIF_DATA, EXIF_N);
+            check(!dir.containsTIFFField(GEO_N), "must not contain Geo field");
+
+            // add GPS
+            dir = getDir(gps, empty);
+            check(dir.containsTIFFField(GPS_N), "must contain GPS field");
+            checkASCIIValue(dir, "GPS", GPS_DATA, GPS_N);
+
+        } catch (Exception e) { throw new RuntimeException(e); }
+    }
+
+    public static void main(String[] args) {
+        (new TIFFImageReadParamTest()).run();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/stream/NullStreamCheckTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2016, 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     8044289
+ * @summary Test verifies that when some of the read() and write() methods
+ *          are not able to get stream from createImageInputStream() and
+ *          createImageOutputStream() are we doing null check for stream
+ *          and throwing IOException as per specification.
+ * @run     main NullStreamCheckTest
+ */
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import javax.imageio.ImageIO;
+import javax.imageio.spi.IIORegistry;
+import javax.imageio.spi.ImageInputStreamSpi;
+import javax.imageio.spi.ImageOutputStreamSpi;
+
+public class NullStreamCheckTest {
+
+    // get ImageIORegistry default instance.
+    private static final IIORegistry localRegistry = IIORegistry.
+            getDefaultInstance();
+    // stream variables needed for input and output.
+    static LocalOutputStream outputStream = new LocalOutputStream();
+    static LocalInputStream inputStream = new LocalInputStream();
+
+    static final int width = 50, height = 50;
+
+    // input and output BufferedImage needed while read and write.
+    static BufferedImage inputImage = new BufferedImage(width, height,
+            BufferedImage.TYPE_INT_ARGB);
+
+    // creates test file needed for read and write in local directory.
+    private static File createTestFile(String name) throws IOException {
+        String sep = System.getProperty("file.separator");
+        String dir = System.getProperty("test.src", ".");
+        String filePath = dir+sep;
+        File directory = new File(filePath);
+        File tmpTestFile = File.createTempFile(name, ".png", directory);
+        directory.delete();
+        return tmpTestFile;
+    }
+
+    /* if we catch expected IOException message return
+     * false otherwise return true.
+     */
+    private static boolean verifyOutputExceptionMessage(IOException ex) {
+        String message = ex.getMessage();
+        return (!message.equals("Can't create an ImageOutputStream!"));
+    }
+
+    /* if we catch expected IOException message return
+     * false otherwise return true.
+     */
+    private static boolean verifyInputExceptionMessage(IOException ex) {
+        String message = ex.getMessage();
+        return (!message.equals("Can't create an ImageInputStream!"));
+    }
+
+    private static void verifyFileWrite() throws IOException {
+        File outputTestFile = createTestFile("outputTestFile");
+        try {
+            ImageIO.write(inputImage, "png", outputTestFile);
+        } catch (IOException ex) {
+            if (verifyOutputExceptionMessage(ex))
+                throw ex;
+        } finally {
+            outputTestFile.delete();
+        }
+    }
+
+    private static void verifyStreamWrite() throws IOException {
+        try {
+            ImageIO.write(inputImage, "png", outputStream);
+        } catch (IOException ex) {
+            if (verifyOutputExceptionMessage(ex))
+                throw ex;
+        } finally {
+            try {
+                outputStream.close();
+            } catch (IOException ex) {
+                throw ex;
+            }
+        }
+    }
+
+    private static void verifyFileRead() throws IOException {
+        File inputTestFile = createTestFile("inputTestFile");
+        try {
+            ImageIO.read(inputTestFile);
+        } catch (IOException ex) {
+            if (verifyInputExceptionMessage(ex))
+                throw ex;
+        } finally {
+            inputTestFile.delete();
+        }
+    }
+
+    private static void verifyStreamRead() throws IOException {
+        try {
+            ImageIO.read(inputStream);
+        } catch (IOException ex) {
+            if (verifyInputExceptionMessage(ex))
+                throw ex;
+        } finally {
+            try {
+                inputStream.close();
+            } catch (IOException ex) {
+                throw ex;
+            }
+        }
+    }
+
+    private static void verifyUrlRead() throws IOException {
+        URL url;
+        File inputTestUrlFile = createTestFile("inputTestFile");
+        try {
+            try {
+                url = inputTestUrlFile.toURI().toURL();
+            } catch (MalformedURLException ex) {
+                throw ex;
+            }
+
+            try {
+                ImageIO.read(url);
+            } catch (IOException ex) {
+                if (verifyInputExceptionMessage(ex))
+                    throw ex;
+            }
+        } finally {
+            inputTestUrlFile.delete();
+        }
+    }
+
+    public static void main(String[] args) throws IOException,
+                                                  MalformedURLException {
+
+        /* deregister ImageOutputStreamSpi so that we creatImageOutputStream
+         * returns null while writing.
+         */
+        localRegistry.deregisterAll(ImageOutputStreamSpi.class);
+        /* verify possible ImageIO.write() scenario's for null stream output
+         * from createImageOutputStream() API in ImageIO class.
+         */
+        verifyFileWrite();
+        verifyStreamWrite();
+
+        /* deregister ImageInputStreamSpi so that we creatImageInputStream
+         * returns null while reading.
+         */
+        localRegistry.deregisterAll(ImageInputStreamSpi.class);
+        /* verify possible ImageIO.read() scenario's for null stream output
+         * from createImageInputStream API in ImageIO class.
+         */
+        verifyFileRead();
+        verifyStreamRead();
+        verifyUrlRead();
+    }
+
+    static class LocalOutputStream extends OutputStream {
+
+        @Override
+        public void write(int i) throws IOException {
+        }
+    }
+
+    static class LocalInputStream extends InputStream {
+
+        @Override
+        public int read() throws IOException {
+            return 0;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/ServerName/BestEffortOnLazyConnected.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,337 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
+/**
+ * @test
+ * @bug 8144566
+ * @summary Custom HostnameVerifier disables SNI extension
+ * @run main/othervm BestEffortOnLazyConnected
+ */
+
+import java.io.*;
+import java.nio.*;
+import java.nio.channels.*;
+import java.util.*;
+import java.net.*;
+import javax.net.ssl.*;
+
+public class BestEffortOnLazyConnected {
+
+    /*
+     * =============================================================
+     * Set the various variables needed for the tests, then
+     * specify what tests to run on each side.
+     */
+
+    /*
+     * Should we run the client or server in a separate thread?
+     * Both sides can throw exceptions, but do you have a preference
+     * as to which side should be the main thread.
+     */
+    private static final boolean separateServerThread = true;
+
+    /*
+     * Where do we find the keystores?
+     */
+    private static final String pathToStores = "../etc";
+    private static final String keyStoreFile = "keystore";
+    private static final String trustStoreFile = "truststore";
+    private static final String passwd = "passphrase";
+
+    /*
+     * Is the server ready to serve?
+     */
+    private static volatile boolean serverReady = false;
+
+    /*
+     * Turn on SSL debugging?
+     */
+    private static final boolean debug = false;
+
+    /*
+     * the fully qualified domain name of localhost
+     */
+    private static String hostname = null;
+
+    /*
+     * If the client or server is doing some kind of object creation
+     * that the other side depends on, and that thread prematurely
+     * exits, you may experience a hang.  The test harness will
+     * terminate all hung threads after its timeout has expired,
+     * currently 3 minutes by default, but you might try to be
+     * smart about it....
+     */
+
+    /*
+     * Define the server side of the test.
+     *
+     * If the server prematurely exits, serverReady will be set to true
+     * to avoid infinite hangs.
+     */
+    private void doServerSide() throws Exception {
+        SSLServerSocketFactory sslssf =
+            (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
+        try (SSLServerSocket sslServerSocket =
+                (SSLServerSocket) sslssf.createServerSocket(serverPort)) {
+
+            serverPort = sslServerSocket.getLocalPort();
+
+            /*
+             * Signal Client, we're ready for his connect.
+             */
+            serverReady = true;
+
+            try (SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept()) {
+                InputStream sslIS = sslSocket.getInputStream();
+                OutputStream sslOS = sslSocket.getOutputStream();
+
+                sslIS.read();
+                sslOS.write(85);
+                sslOS.flush();
+
+                ExtendedSSLSession session =
+                        (ExtendedSSLSession)sslSocket.getSession();
+                if (session.getRequestedServerNames().isEmpty()) {
+                    throw new Exception("No expected Server Name Indication");
+                }
+            }
+        }
+    }
+
+    /*
+     * Define the client side of the test.
+     *
+     * If the server prematurely exits, serverReady will be set to true
+     * to avoid infinite hangs.
+     */
+    private void doClientSide() throws Exception {
+
+        /*
+         * Wait for server to get started.
+         */
+        while (!serverReady) {
+            Thread.sleep(50);
+        }
+
+        SSLSocketFactory sslsf =
+            (SSLSocketFactory) SSLSocketFactory.getDefault();
+
+        try (SSLSocket sslSocket = (SSLSocket)sslsf.createSocket()) {
+
+            sslSocket.connect(new InetSocketAddress(hostname, serverPort), 0);
+
+            InputStream sslIS = sslSocket.getInputStream();
+            OutputStream sslOS = sslSocket.getOutputStream();
+
+            sslOS.write(280);
+            sslOS.flush();
+            sslIS.read();
+        }
+    }
+
+
+    /*
+     * =============================================================
+     * The remainder is just support stuff
+     */
+
+    // use any free port by default
+    private volatile int serverPort = 0;
+
+    private volatile Exception serverException = null;
+    private volatile Exception clientException = null;
+
+    public static void main(String[] args) throws Exception {
+        String keyFilename =
+            System.getProperty("test.src", ".") + "/" + pathToStores +
+                "/" + keyStoreFile;
+        String trustFilename =
+            System.getProperty("test.src", ".") + "/" + pathToStores +
+                "/" + trustStoreFile;
+
+        System.setProperty("javax.net.ssl.keyStore", keyFilename);
+        System.setProperty("javax.net.ssl.keyStorePassword", passwd);
+        System.setProperty("javax.net.ssl.trustStore", trustFilename);
+        System.setProperty("javax.net.ssl.trustStorePassword", passwd);
+
+        if (debug) {
+            System.setProperty("javax.net.debug", "all");
+        }
+
+        try {
+            hostname = InetAddress.getLocalHost().getCanonicalHostName();
+        } catch (UnknownHostException uhe) {
+            System.out.println(
+                "Ignore the test as the local hostname cannot be determined");
+
+            return;
+        }
+
+        System.out.println(
+                "The fully qualified domain name of the local host is " +
+                hostname);
+        // Ignore the test if the hostname does not sound like a domain name.
+        if ((hostname == null) || hostname.isEmpty() ||
+                hostname.startsWith("localhost") ||
+                Character.isDigit(hostname.charAt(hostname.length() - 1))) {
+
+            System.out.println("Ignore the test as the local hostname " +
+                    "cannot be determined as fully qualified domain name");
+
+            return;
+        }
+
+        /*
+         * Start the tests.
+         */
+        new BestEffortOnLazyConnected();
+    }
+
+    private Thread clientThread = null;
+    private Thread serverThread = null;
+
+    /*
+     * Primary constructor, used to drive remainder of the test.
+     *
+     * Fork off the other side, then do your work.
+     */
+    BestEffortOnLazyConnected() throws Exception {
+        try {
+            if (separateServerThread) {
+                startServer(true);
+                startClient(false);
+            } else {
+                startClient(true);
+                startServer(false);
+            }
+        } catch (Exception e) {
+            // swallow for now.  Show later
+        }
+
+        /*
+         * Wait for other side to close down.
+         */
+        if (separateServerThread) {
+            serverThread.join();
+        } else {
+            clientThread.join();
+        }
+
+        /*
+         * When we get here, the test is pretty much over.
+         * Which side threw the error?
+         */
+        Exception local;
+        Exception remote;
+        String whichRemote;
+
+        if (separateServerThread) {
+            remote = serverException;
+            local = clientException;
+            whichRemote = "server";
+        } else {
+            remote = clientException;
+            local = serverException;
+            whichRemote = "client";
+        }
+
+        /*
+         * If both failed, return the curthread's exception, but also
+         * print the remote side Exception
+         */
+        if ((local != null) && (remote != null)) {
+            System.out.println(whichRemote + " also threw:");
+            remote.printStackTrace();
+            System.out.println();
+            throw local;
+        }
+
+        if (remote != null) {
+            throw remote;
+        }
+
+        if (local != null) {
+            throw local;
+        }
+    }
+
+    private void startServer(boolean newThread) throws Exception {
+        if (newThread) {
+            serverThread = new Thread() {
+                public void run() {
+                    try {
+                        doServerSide();
+                    } catch (Exception e) {
+                        /*
+                         * Our server thread just died.
+                         *
+                         * Release the client, if not active already...
+                         */
+                        System.err.println("Server died...");
+                        serverReady = true;
+                        serverException = e;
+                    }
+                }
+            };
+            serverThread.start();
+        } else {
+            try {
+                doServerSide();
+            } catch (Exception e) {
+                serverException = e;
+            } finally {
+                serverReady = true;
+            }
+        }
+    }
+
+    private void startClient(boolean newThread) throws Exception {
+        if (newThread) {
+            clientThread = new Thread() {
+                public void run() {
+                    try {
+                        doClientSide();
+                    } catch (Exception e) {
+                        /*
+                         * Our client thread just died.
+                         */
+                        System.err.println("Client died...");
+                        clientException = e;
+                    }
+                }
+            };
+            clientThread.start();
+        } else {
+            try {
+                doClientSide();
+            } catch (Exception e) {
+                clientException = e;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/AudioFloatConverter/Bits16ToFromFloatArray.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2016, 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.Arrays;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioFormat.Encoding;
+
+import com.sun.media.sound.AudioFloatConverter;
+
+import static javax.sound.sampled.AudioFormat.Encoding.*;
+
+/**
+ * @test
+ * @bug 8152501
+ * @modules java.desktop/com.sun.media.sound
+ */
+public final class Bits16ToFromFloatArray {
+
+    private static final int SIZE = 16;
+
+    private static final float[] FLOATS = {-1.0f, 0, 1.0f};
+
+    private static short MID_U = (short) (Short.MAX_VALUE + 1);
+    private static short MAX_U = -1;
+
+    // BIG ENDIAN
+    private static final byte[] SIGNED_BIG = {
+            (byte) (Short.MIN_VALUE >> 8), (byte) (Short.MIN_VALUE & 0xff), 0,
+            0, (byte) (Short.MAX_VALUE >> 8), (byte) (Short.MAX_VALUE & 0xff)
+    };
+
+    private static final byte[] UNSIGNED_BIG = {
+            0, 0, (byte) (MID_U >> 8), (byte) (MID_U & 0xff),
+            (byte) (MAX_U >> 8), (byte) (MAX_U >> 8)
+    };
+
+    // LITTLE ENDIAN
+    private static final byte[] SIGNED_LITTLE = {
+            (byte) (Short.MIN_VALUE & 0xff), (byte) (Short.MIN_VALUE >> 8), 0,
+            0, (byte) (Short.MAX_VALUE & 0xff), (byte) (Short.MAX_VALUE >> 8)
+    };
+
+    private static final byte[] UNSIGNED_LITTLE = {
+            0, 0, (byte) (MID_U & 0xff), (byte) (MID_U >> 8),
+            (byte) (MAX_U >> 8), (byte) (MAX_U >> 8)
+    };
+
+    public static void main(final String[] args) {
+        test(PCM_UNSIGNED, UNSIGNED_BIG, true);
+        test(PCM_UNSIGNED, UNSIGNED_LITTLE, false);
+        test(PCM_SIGNED, SIGNED_LITTLE, false);
+        test(PCM_SIGNED, SIGNED_BIG, true);
+    }
+
+    private static void test(final Encoding enc, final byte[] expected,
+                             boolean end) {
+        System.err.println("enc = " + enc);
+        AudioFormat af = new AudioFormat(enc, 44100, SIZE, 1, SIZE / 8, 44100,
+                                         end);
+        byte[] bytes = new byte[FLOATS.length * af.getFrameSize()];
+        AudioFloatConverter conv = AudioFloatConverter.getConverter(af);
+
+        conv.toByteArray(FLOATS, bytes);
+
+        if (!Arrays.equals(bytes, expected)) {
+            System.err.println("Actual: " + Arrays.toString(bytes));
+            System.err.println("Expected: " + Arrays.toString(expected));
+            throw new RuntimeException();
+        }
+
+        float[] floats = new float[bytes.length / af.getFrameSize()];
+        conv.toFloatArray(bytes, floats);
+
+        if (!Arrays.equals(floats, FLOATS)) {
+            System.err.println("Actual: " + Arrays.toString(floats));
+            System.err.println("Expected: " + Arrays.toString(FLOATS));
+            throw new RuntimeException();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/AudioFloatConverter/Bits24ToFromFloatArray.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2016, 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.Arrays;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioFormat.Encoding;
+
+import com.sun.media.sound.AudioFloatConverter;
+
+import static javax.sound.sampled.AudioFormat.Encoding.PCM_SIGNED;
+import static javax.sound.sampled.AudioFormat.Encoding.PCM_UNSIGNED;
+
+/**
+ * @test
+ * @bug 8152501
+ * @modules java.desktop/com.sun.media.sound
+ */
+public final class Bits24ToFromFloatArray {
+
+    private static final int SIZE = 24;
+
+    private static final float[] FLOATS = {-1.0f, 0, 1.0f};
+
+    private static int MIN_S = -8_388_608;
+    private static int MAX_S = 8_388_607;
+
+    private static int MID_U = 0xFFFFFF / 2 + 1;
+    private static int MAX_U = 0xFFFFFF;
+
+    // BIG ENDIAN
+    private static final byte[] SIGNED_BIG = {
+            (byte) ((MIN_S >> 16) & 0xff),
+            (byte) ((MIN_S >> 8) & 0xff),
+            (byte) ((MIN_S >> 0) & 0xff),
+            0, 0, 0,
+            (byte) ((MAX_S >> 16) & 0xff),
+            (byte) ((MAX_S >> 8) & 0xff),
+            (byte) ((MAX_S >> 0) & 0xff),
+    };
+
+    private static final byte[] UNSIGNED_BIG = {
+            0, 0, 0,
+            (byte) ((MID_U >> 16) & 0xff),
+            (byte) ((MID_U >> 8) & 0xff),
+            (byte) ((MID_U >> 0) & 0xff),
+            (byte) ((MAX_U >> 16) & 0xff),
+            (byte) ((MAX_U >> 8) & 0xff),
+            (byte) ((MAX_U >> 0) & 0xff),
+
+    };
+
+    // LITTLE ENDIAN
+    private static final byte[] SIGNED_LITTLE = {
+            (byte) ((MIN_S >> 0) & 0xff),
+            (byte) ((MIN_S >> 8) & 0xff),
+            (byte) ((MIN_S >> 16) & 0xff),
+            0, 0, 0,
+            (byte) ((MAX_S >> 0) & 0xff),
+            (byte) ((MAX_S >> 8) & 0xff),
+            (byte) ((MAX_S >> 16) & 0xff),
+            };
+
+    private static final byte[] UNSIGNED_LITTLE = {
+            0, 0, 0,
+            (byte) ((MID_U >> 0) & 0xff),
+            (byte) ((MID_U >> 8) & 0xff),
+            (byte) ((MID_U >> 16) & 0xff),
+            (byte) ((MAX_U >> 0) & 0xff),
+            (byte) ((MAX_U >> 8) & 0xff),
+            (byte) ((MAX_U >> 16) & 0xff),
+            };
+
+    public static void main(final String[] args) {
+        test(PCM_UNSIGNED, UNSIGNED_BIG, true);
+        test(PCM_UNSIGNED, UNSIGNED_LITTLE, false);
+        test(PCM_SIGNED, SIGNED_LITTLE, false);
+        test(PCM_SIGNED, SIGNED_BIG, true);
+    }
+
+    private static void test(final Encoding enc, final byte[] expected,
+                             boolean end) {
+        System.err.println(enc);
+        AudioFormat af = new AudioFormat(enc, 44100, SIZE, 1, SIZE / 8, 44100,
+                                         end);
+        byte[] bytes = new byte[FLOATS.length * af.getFrameSize()];
+        AudioFloatConverter conv = AudioFloatConverter.getConverter(af);
+
+        conv.toByteArray(FLOATS, bytes);
+
+        if (!Arrays.equals(bytes, expected)) {
+            System.err.println("Actual: " + Arrays.toString(bytes));
+            System.err.println("Expected: " + Arrays.toString(expected));
+            throw new RuntimeException();
+        }
+
+        float[] floats = new float[bytes.length / af.getFrameSize()];
+        conv.toFloatArray(bytes, floats);
+
+        if (!Arrays.equals(floats, FLOATS)) {
+            System.err.println("Actual: " + Arrays.toString(floats));
+            System.err.println("Expected: " + Arrays.toString(FLOATS));
+            throw new RuntimeException();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/AudioFloatConverter/Bits32ToFromFloatArray.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2016, 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.Arrays;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioFormat.Encoding;
+
+import com.sun.media.sound.AudioFloatConverter;
+
+import static javax.sound.sampled.AudioFormat.Encoding.PCM_SIGNED;
+import static javax.sound.sampled.AudioFormat.Encoding.PCM_UNSIGNED;
+
+/**
+ * @test
+ * @bug 8152501
+ * @modules java.desktop/com.sun.media.sound
+ */
+public final class Bits32ToFromFloatArray {
+
+    private static final int SIZE = 32;
+
+    private static final float[] FLOATS = {-1.0f, 0, 1.0f};
+
+    private static int MID_U = (int) (Integer.MAX_VALUE + 1);
+    private static int MAX_U = -1;
+
+    // BIG ENDIAN
+    private static final byte[] SIGNED_BIG = {
+            (byte) ((Integer.MIN_VALUE >> 24) & 0xff),
+            (byte) ((Integer.MIN_VALUE >> 16) & 0xff),
+            (byte) ((Integer.MIN_VALUE >> 8) & 0xff),
+            (byte) ((Integer.MIN_VALUE >> 0) & 0xff),
+            0, 0, 0, 0,
+            (byte) ((Integer.MAX_VALUE >> 24) & 0xff),
+            (byte) ((Integer.MAX_VALUE >> 16) & 0xff),
+            (byte) ((Integer.MAX_VALUE >> 8) & 0xff),
+            (byte) ((Integer.MAX_VALUE >> 0) & 0xff),
+    };
+
+    private static final byte[] UNSIGNED_BIG = {
+            0, 0, 0, 0,
+            (byte) ((MID_U >> 24) & 0xff),
+            (byte) ((MID_U >> 16) & 0xff),
+            (byte) ((MID_U >> 8) & 0xff),
+            (byte) ((MID_U >> 0) & 0xff),
+            (byte) ((MAX_U >> 24) & 0xff),
+            (byte) ((MAX_U >> 16) & 0xff),
+            (byte) ((MAX_U >> 8) & 0xff),
+            (byte) ((MAX_U >> 0) & 0xff),
+
+    };
+
+    // LITTLE ENDIAN
+    private static final byte[] SIGNED_LITTLE = {
+            (byte) ((Integer.MIN_VALUE >> 0) & 0xff),
+            (byte) ((Integer.MIN_VALUE >> 8) & 0xff),
+            (byte) ((Integer.MIN_VALUE >> 16) & 0xff),
+            (byte) ((Integer.MIN_VALUE >> 24) & 0xff),
+            0, 0, 0, 0,
+            (byte) ((Integer.MAX_VALUE >> 0) & 0xff),
+            (byte) ((Integer.MAX_VALUE >> 8) & 0xff),
+            (byte) ((Integer.MAX_VALUE >> 16) & 0xff),
+            (byte) ((Integer.MAX_VALUE >> 24) & 0xff),
+            };
+
+    private static final byte[] UNSIGNED_LITTLE = {
+            0, 0, 0, 0,
+            (byte) ((MID_U >> 0) & 0xff),
+            (byte) ((MID_U >> 8) & 0xff),
+            (byte) ((MID_U >> 16) & 0xff),
+            (byte) ((MID_U >> 24) & 0xff),
+            (byte) ((MAX_U >> 0) & 0xff),
+            (byte) ((MAX_U >> 8) & 0xff),
+            (byte) ((MAX_U >> 16) & 0xff),
+            (byte) ((MAX_U >> 24) & 0xff),
+            };
+
+    public static void main(final String[] args) {
+        test(PCM_UNSIGNED, UNSIGNED_BIG, true);
+        test(PCM_UNSIGNED, UNSIGNED_LITTLE, false);
+        test(PCM_SIGNED, SIGNED_LITTLE, false);
+        test(PCM_SIGNED, SIGNED_BIG, true);
+    }
+
+    private static void test(final Encoding enc, final byte[] expected,
+                             boolean end) {
+        AudioFormat af = new AudioFormat(enc, 44100, SIZE, 1, SIZE / 8, 44100,
+                                         end);
+        byte[] bytes = new byte[FLOATS.length * af.getFrameSize()];
+        AudioFloatConverter conv = AudioFloatConverter.getConverter(af);
+
+        conv.toByteArray(FLOATS, bytes);
+
+        if (!Arrays.equals(bytes, expected)) {
+            System.err.println("Actual: " + Arrays.toString(bytes));
+            System.err.println("Expected: " + Arrays.toString(expected));
+            throw new RuntimeException();
+        }
+
+        float[] floats = new float[bytes.length / af.getFrameSize()];
+        conv.toFloatArray(bytes, floats);
+
+        if (!Arrays.equals(floats, FLOATS)) {
+            System.err.println("Actual: " + Arrays.toString(floats));
+            System.err.println("Expected: " + Arrays.toString(FLOATS));
+            throw new RuntimeException();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/AudioFloatConverter/Bits64ToFromFloatArray.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2016, 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.Arrays;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioFormat.Encoding;
+
+import com.sun.media.sound.AudioFloatConverter;
+
+import static javax.sound.sampled.AudioFormat.Encoding.PCM_SIGNED;
+import static javax.sound.sampled.AudioFormat.Encoding.PCM_UNSIGNED;
+
+/**
+ * @test
+ * @bug 8152501
+ * @modules java.desktop/com.sun.media.sound
+ */
+public final class Bits64ToFromFloatArray {
+
+    private static final int SIZE = 64;
+
+    private static final float[] FLOATS = {-1.0f, 0, 1.0f};
+
+    private static long MID_U = (long) (Long.MAX_VALUE + 1);
+    private static long MAX_U = -1;
+
+    // BIG ENDIAN
+    private static final byte[] SIGNED_BIG = {
+            (byte) ((Long.MIN_VALUE >> 56) & 0xff),
+            (byte) ((Long.MIN_VALUE >> 48) & 0xff),
+            (byte) ((Long.MIN_VALUE >> 40) & 0xff),
+            (byte) ((Long.MIN_VALUE >> 32) & 0xff),
+            0, 0, 0, 0, // current javasound impl will ignore this
+            0, 0, 0, 0,
+            0, 0, 0, 0,
+            (byte) ((Long.MAX_VALUE >> 56) & 0xff),
+            (byte) ((Long.MAX_VALUE >> 48) & 0xff),
+            (byte) ((Long.MAX_VALUE >> 40) & 0xff),
+            (byte) ((Long.MAX_VALUE >> 32) & 0xff),
+            0, 0, 0, 0, // current javasound impl will ignore this
+    };
+
+    private static final byte[] UNSIGNED_BIG = {
+            0, 0, 0, 0,
+            0, 0, 0, 0,
+            (byte) ((MID_U >> 56) & 0xff),
+            (byte) ((MID_U >> 48) & 0xff),
+            (byte) ((MID_U >> 40) & 0xff),
+            (byte) ((MID_U >> 32) & 0xff),
+            0, 0, 0, 0, // current javasound impl will ignore this
+            (byte) ((MAX_U >> 56) & 0xff),
+            (byte) ((MAX_U >> 48) & 0xff),
+            (byte) ((MAX_U >> 40) & 0xff),
+            (byte) ((MAX_U >> 32) & 0xff),
+            0, 0, 0, 0, // current javasound impl will ignore this
+    };
+
+    // LITTLE ENDIAN
+    private static final byte[] SIGNED_LITTLE = {
+            0, 0, 0, 0, // current javasound impl will ignore this
+            (byte) ((Long.MIN_VALUE >> 32) & 0xff),
+            (byte) ((Long.MIN_VALUE >> 40) & 0xff),
+            (byte) ((Long.MIN_VALUE >> 48) & 0xff),
+            (byte) ((Long.MIN_VALUE >> 56) & 0xff),
+            0, 0, 0, 0,
+            0, 0, 0, 0,
+            0, 0, 0, 0, // current javasound impl will ignore this
+            (byte) ((Long.MAX_VALUE >> 32) & 0xff),
+            (byte) ((Long.MAX_VALUE >> 40) & 0xff),
+            (byte) ((Long.MAX_VALUE >> 48) & 0xff),
+            (byte) ((Long.MAX_VALUE >> 56) & 0xff),
+            };
+
+    private static final byte[] UNSIGNED_LITTLE = {
+            0, 0, 0, 0,
+            0, 0, 0, 0,
+            0, 0, 0, 0, // current javasound impl will ignore this
+            (byte) ((MID_U >> 32) & 0xff),
+            (byte) ((MID_U >> 40) & 0xff),
+            (byte) ((MID_U >> 48) & 0xff),
+            (byte) ((MID_U >> 56) & 0xff),
+            0, 0, 0, 0, // current javasound impl will ignore this
+            (byte) ((MAX_U >> 32) & 0xff),
+            (byte) ((MAX_U >> 40) & 0xff),
+            (byte) ((MAX_U >> 48) & 0xff),
+            (byte) ((MAX_U >> 56) & 0xff),
+            };
+
+    public static void main(final String[] args) {
+        test(PCM_UNSIGNED, UNSIGNED_BIG, true);
+        test(PCM_UNSIGNED, UNSIGNED_LITTLE, false);
+        test(PCM_SIGNED, SIGNED_LITTLE, false);
+        test(PCM_SIGNED, SIGNED_BIG, true);
+    }
+
+    private static void test(final Encoding enc, final byte[] expected,
+                             boolean end) {
+        System.err.println(enc);
+        AudioFormat af = new AudioFormat(enc, 44100, SIZE, 1, SIZE / 8, 44100,
+                                         end);
+        byte[] bytes = new byte[FLOATS.length * af.getFrameSize()];
+        AudioFloatConverter conv = AudioFloatConverter.getConverter(af);
+
+        conv.toByteArray(FLOATS, bytes);
+
+        if (!Arrays.equals(bytes, expected)) {
+            System.err.println("Actual:   " + Arrays.toString(bytes));
+            System.err.println("Expected: " + Arrays.toString(expected));
+            throw new RuntimeException();
+        }
+
+        float[] floats = new float[bytes.length / af.getFrameSize()];
+        conv.toFloatArray(bytes, floats);
+
+        if (!Arrays.equals(floats, FLOATS)) {
+            System.err.println("Actual: " + Arrays.toString(floats));
+            System.err.println("Expected: " + Arrays.toString(FLOATS));
+            throw new RuntimeException();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/Gervill/AudioFloatConverter/Bits8ToFromFloatArray.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2016, 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.Arrays;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioFormat.Encoding;
+
+import com.sun.media.sound.AudioFloatConverter;
+
+import static javax.sound.sampled.AudioFormat.Encoding.*;
+
+/**
+ * @test
+ * @bug 8152501
+ * @modules java.desktop/com.sun.media.sound
+ */
+public final class Bits8ToFromFloatArray {
+
+    private static final int SIZE = 8;
+
+    private static final float[] FLOATS = {-1.0f, 0, 1.0f};
+
+    private static final byte[] SIGNED = {Byte.MIN_VALUE, 0, Byte.MAX_VALUE};
+
+    private static final byte[] UNSIGNED = {
+            0, (byte) (Byte.MAX_VALUE + 1), (byte) -1
+    };
+
+    public static void main(final String[] args) {
+        test(PCM_UNSIGNED, UNSIGNED);
+        test(PCM_SIGNED, SIGNED);
+    }
+
+    private static void test(final Encoding enc, final byte[] expected) {
+        AudioFormat af = new AudioFormat(enc, 44100, SIZE, 1, SIZE / 8, 44100,
+                                         true);
+        byte[] bytes = new byte[FLOATS.length * af.getFrameSize()];
+        AudioFloatConverter conv = AudioFloatConverter.getConverter(af);
+
+        conv.toByteArray(FLOATS, bytes);
+
+        if (!Arrays.equals(bytes, expected)) {
+            System.err.println("Actual: " + Arrays.toString(bytes));
+            System.err.println("Expected: " + Arrays.toString(expected));
+            throw new RuntimeException();
+        }
+
+        float[] floats = new float[bytes.length / af.getFrameSize()];
+        conv.toFloatArray(bytes, floats);
+
+        if (!Arrays.equals(floats, FLOATS)) {
+            System.err.println("Actual: " + Arrays.toString(floats));
+            System.err.println("Expected: " + Arrays.toString(FLOATS));
+            throw new RuntimeException();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/ClientProperty/UIClientPropertyKeyTest/UIClientPropertyKeyTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.EventQueue;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.SwingUtilities;
+import javax.swing.UIClientPropertyKey;
+import javax.swing.UIManager;
+import javax.swing.UnsupportedLookAndFeelException;
+
+import static javax.swing.UIManager.getInstalledLookAndFeels;
+
+/**
+ * @test
+ * @bug 8141544
+ */
+public final class UIClientPropertyKeyTest {
+
+    private static Object key = new UIClientPropertyKey() {
+    };
+
+    public static void main(final String[] args) throws Exception {
+        EventQueue.invokeAndWait(UIClientPropertyKeyTest::testSetUI);
+        EventQueue.invokeAndWait(UIClientPropertyKeyTest::testSerialization);
+    }
+
+    /**
+     * UIClientPropertyKey should be removed after deserialization.
+     */
+    private static void testSerialization() {
+        JComponent comp = new JButton();
+        comp.putClientProperty("key1", "value1");
+        comp.putClientProperty(key, "value2");
+
+        comp = serializeDeserialize(comp);
+
+        validate(comp);
+    }
+
+    /**
+     * UIClientPropertyKey should be removed on updateUI().
+     */
+    private static void testSetUI() {
+        JComponent comp = new JButton();
+        comp.putClientProperty("key1", "value1");
+        for (final UIManager.LookAndFeelInfo laf : getInstalledLookAndFeels()) {
+            comp.putClientProperty(key, "value2");
+            setLookAndFeel(laf);
+            SwingUtilities.updateComponentTreeUI(comp);
+            validate(comp);
+        }
+    }
+
+    private static void validate(JComponent comp) {
+        Object value = comp.getClientProperty("key1");
+        if (!value.equals("value1")) {
+            throw new RuntimeException("Incorrect value: " + value);
+        }
+        value = comp.getClientProperty(key);
+        if (value != null) {
+            throw new RuntimeException("Incorrect value: " + value);
+        }
+    }
+
+    private static void setLookAndFeel(final UIManager.LookAndFeelInfo laf) {
+        try {
+            UIManager.setLookAndFeel(laf.getClassName());
+            System.out.println("LookAndFeel: " + laf.getClassName());
+        } catch (ClassNotFoundException | InstantiationException |
+                UnsupportedLookAndFeelException | IllegalAccessException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static JComponent serializeDeserialize(JComponent comp) {
+        try {
+            ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+            ObjectOutputStream out = new ObjectOutputStream(byteOut);
+            out.writeObject(comp);
+            out.close();
+            return (JComponent) new ObjectInputStream(new ByteArrayInputStream(
+                    byteOut.toByteArray())).readObject();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JButton/PressedButtonRightClickTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+import java.awt.AWTException;
+import java.awt.BorderLayout;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.event.InputEvent;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+
+/*
+ * @test
+ * @bug  8049069
+ * @summary Tests whether right mouse click releases a pressed JButton
+ */
+
+public class PressedButtonRightClickTest {
+
+    private static Robot testRobot;
+    private static JFrame myFrame;
+    private static JButton myButton;
+
+    public static void main(String[] args) throws Throwable {
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+
+            @Override
+            public void run() {
+                constructTestUI();
+            }
+        });
+
+        try {
+            testRobot = new Robot();
+        } catch (AWTException ex) {
+            throw new RuntimeException("Exception in Robot creation");
+        }
+
+        testRobot.waitForIdle();
+
+        // Method performing auto test operation
+        test();
+
+        disposeTestUI();
+    }
+
+    private static void test() {
+        Point loc = myFrame.getLocationOnScreen();
+
+        testRobot.mouseMove((loc.x + 100), (loc.y + 100));
+
+        // Press the left mouse button
+        testRobot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+        myButton.setText("Left button pressed");
+        testRobot.delay(1000);
+
+        // Press the right mouse button
+        testRobot.mousePress(InputEvent.BUTTON3_DOWN_MASK);
+        myButton.setText("Left button pressed + Right button pressed");
+        testRobot.delay(1000);
+
+        // Release the right mouse button
+        testRobot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK);
+        myButton.setText("Right button released");
+        testRobot.delay(1000);
+
+        // Test whether the button is still pressed
+        if (myButton.getModel().isPressed() == false) {
+            disposeTestUI();
+            throw new RuntimeException("Test Failed!");
+        }
+    }
+
+    private static void disposeTestUI() {
+        myFrame.setVisible(false);
+        myFrame.dispose();
+    }
+
+    public static void constructTestUI() {
+        myFrame = new JFrame();
+        myFrame.setLayout(new BorderLayout());
+        myButton = new JButton("Whatever");
+        myFrame.add(myButton, BorderLayout.CENTER);
+        myFrame.setSize(400, 300);
+        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        myFrame.setVisible(true);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JEditorPane/5076514/bug5076514.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016, 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 5076514 8025430
+   @summary Tests if SecurityManager.checkPermission()
+                  used for clipboard access with permission 'accessClipboard'
+   @run main bug5076514
+*/
+
+import java.security.Permission;
+import javax.swing.JEditorPane;
+
+public class bug5076514 {
+    private final static String ACCESS_CLIPBOARD = "accessClipboard";
+    private static boolean isCheckPermissionCalled = false;
+
+    public static void main(String[] args) {
+        System.setSecurityManager(new MySecurityManager());
+        JEditorPane editor = new JEditorPane();
+        editor.copy();
+        if (!isCheckPermissionCalled) {
+            throw new RuntimeException("JEditorPane's clipboard operations "
+                    + "didn't call SecurityManager.checkPermission() with "
+                    + "permission 'accessClipboard' when there is a security"
+                    + " manager installed");
+        }
+    }
+
+    private static class MySecurityManager extends SecurityManager {
+        @Override
+        public void checkPermission(Permission perm) {
+            if (ACCESS_CLIPBOARD.equals(perm.getName())) {
+                isCheckPermissionCalled = true;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JFileChooser/DeserializedJFileChooser/DeserializedJFileChooserTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2016, 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 8146301
+ * @summary Enter key does not work in a deserialized JFileChooser.
+ * @run main DeserializedJFileChooserTest
+ */
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.KeyEvent;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+public class DeserializedJFileChooserTest {
+
+    private static int state = -1;
+    private static JFileChooser deserialized;
+
+    public static void main(String[] args) throws Exception {
+        SwingUtilities.invokeLater( () -> {
+            try {
+                JFileChooser jfc = new JFileChooser();
+                ByteArrayOutputStream bos = new ByteArrayOutputStream();
+                ObjectOutputStream oos = new ObjectOutputStream(bos);
+                oos.writeObject(jfc);
+                oos.close();
+                ByteArrayInputStream bis =
+                        new ByteArrayInputStream(bos.toByteArray());
+                ObjectInputStream ois = new ObjectInputStream(bis);
+                deserialized = (JFileChooser) ois.readObject();
+                state = deserialized.showOpenDialog(null);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        });
+        Robot robot = new Robot();
+        robot.setAutoDelay(50);
+        robot.waitForIdle();
+        robot.keyPress(KeyEvent.VK_A);
+        robot.keyRelease(KeyEvent.VK_A);
+        robot.keyPress(KeyEvent.VK_ENTER);
+        robot.keyRelease(KeyEvent.VK_ENTER);
+        robot.waitForIdle();
+        robot.delay(1000);
+        if (state != JFileChooser.APPROVE_OPTION) {
+            deserialized.cancelSelection();
+            throw new RuntimeException("Failed");
+        }
+    }
+}
--- a/jdk/test/javax/swing/JFileChooser/ShellFolderQueries/ShellFolderQueriesTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/javax/swing/JFileChooser/ShellFolderQueries/ShellFolderQueriesTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -30,7 +30,6 @@
  * @run main ShellFolderQueriesTest
  */
 
-import sun.awt.OSInfo;
 
 import javax.swing.filechooser.FileSystemView;
 import java.io.File;
@@ -50,7 +49,8 @@
     static String scriptEnd = "\"\noShellLink.WindowStyle = 1\noShellLink.Save";
 
     public static void main(String[] args) throws Exception {
-        if(OSInfo.getOSType() == OSInfo.OSType.WINDOWS) {
+        if(System.getProperty("os.name").toLowerCase().contains("windows")) {
+            System.out.println("Windows detected: will run shortcut test");
             testGet();
             testLink();
         } else {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JInternalFrame/DockIconRepaint/DockIconRepaint.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Color;
+import java.awt.EventQueue;
+import java.awt.Graphics;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.beans.PropertyVetoException;
+
+import javax.swing.JDesktopPane;
+import javax.swing.JFrame;
+import javax.swing.JInternalFrame;
+import javax.swing.JPanel;
+
+/**
+ * @test
+ * @bug 8144166
+ * @requires (os.family == "mac")
+ */
+public final class DockIconRepaint {
+
+    private static volatile Color color;
+
+    private static JFrame frame;
+
+    private static JInternalFrame jif;
+
+    private static Robot robot;
+
+    private static Point iconLoc;
+
+    private static Rectangle iconBounds;
+
+    public static void main(final String[] args) throws Exception {
+        robot = new Robot();
+        EventQueue.invokeAndWait(DockIconRepaint::createUI);
+        try {
+            robot.waitForIdle();
+            color = Color.BLUE;
+            test();
+            color = Color.RED;
+            test();
+            color = Color.GREEN;
+            test();
+        } finally {
+            frame.dispose();
+        }
+    }
+
+    private static void test() throws Exception {
+        // maximize the frame to force repaint
+        EventQueue.invokeAndWait(() -> {
+            try {
+                jif.setIcon(false);
+                jif.setMaximum(true);
+            } catch (PropertyVetoException e) {
+                throw new RuntimeException(e);
+            }
+        });
+        robot.waitForIdle();
+        Thread.sleep(1000);
+        // minimize the frame to dock, the icon should be up2date
+        EventQueue.invokeAndWait(() -> {
+            try {
+                jif.setIcon(true);
+            } catch (PropertyVetoException e) {
+                throw new RuntimeException(e);
+            }
+            iconLoc = jif.getDesktopIcon().getLocationOnScreen();
+            iconBounds = jif.getDesktopIcon().getBounds();
+        });
+        robot.waitForIdle();
+        Thread.sleep(1000);
+
+        final Color c = robot.getPixelColor(iconLoc.x + iconBounds.width / 2,
+                                            iconLoc.y + iconBounds.height / 2);
+        if (c.getRGB() != color.getRGB()) {
+            System.err.println("Exp: " + Integer.toHexString(color.getRGB()));
+            System.err.println("Actual: " + Integer.toHexString(c.getRGB()));
+            throw new RuntimeException("Wrong color.");
+        }
+    }
+
+    private static void createUI() {
+        frame = new JFrame();
+        frame.setUndecorated(true);
+        frame.setSize(300, 300);
+        frame.setLocationRelativeTo(null);
+        final JDesktopPane pane = new JDesktopPane();
+        final JPanel panel = new JPanel() {
+            @Override
+            protected void paintComponent(Graphics g) {
+                g.setColor(color);
+                g.fillRect(0, 0, getWidth(), getHeight());
+            }
+        };
+        jif = new JInternalFrame();
+        jif.add(panel);
+        jif.setVisible(true);
+        jif.setSize(300, 300);
+        pane.add(jif);
+        frame.add(pane);
+        frame.setVisible(true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JPopupMenu/6949414/JPopupMenuEndlessLoopTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+import javax.swing.MenuElement;
+import javax.swing.MenuSelectionManager;
+import javax.swing.SwingUtilities;
+
+/**
+ * @test
+ * @bug 6949414 6424606
+ * @summary JMenu.buildMenuElementArray() endless loop
+ * @run main/timeout=5 JPopupMenuEndlessLoopTest
+ */
+public class JPopupMenuEndlessLoopTest {
+
+    public static void main(String[] args) throws Exception {
+        SwingUtilities.invokeAndWait(() -> {
+
+            JPopupMenu popup = new JPopupMenu("Popup Menu");
+            JMenu menu = new JMenu("Menu");
+            menu.add(new JMenuItem("Menu Item"));
+            popup.add(menu);
+            menu.doClick();
+            MenuElement[] elems = MenuSelectionManager
+                    .defaultManager().getSelectedPath();
+
+            if (elems == null || elems.length == 0) {
+                throw new RuntimeException("Empty Selection");
+            }
+
+            if (elems[0] != popup || elems[1] != menu) {
+                throw new RuntimeException("Necessary menus are not selected!");
+            }
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JTabbedPane/8137169/ScrollableTabbedPaneTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2016, 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 8137169
+ * @summary verifies TabbedScrollPane minimum height for all Look and Feels
+ * @library ../../regtesthelpers
+ * @build Util
+ * @run main ScrollableTabbedPaneTest
+ */
+
+import java.awt.Robot;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JTabbedPane;
+import javax.swing.SwingConstants;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.UnsupportedLookAndFeelException;
+
+public class ScrollableTabbedPaneTest {
+
+    private static JFrame frame;
+    private static JTabbedPane pane;
+    private static Robot robot;
+    private static volatile String errorString = "";
+
+    public static void main(String[] args) throws Exception {
+        robot = new Robot();
+        robot.delay(1000);
+        UIManager.LookAndFeelInfo[] lookAndFeelArray
+                = UIManager.getInstalledLookAndFeels();
+        for (UIManager.LookAndFeelInfo lookAndFeelItem : lookAndFeelArray) {
+            executeCase(lookAndFeelItem.getClassName(),
+                        lookAndFeelItem.getName());
+        }
+        if (!"".equals(errorString)) {
+            throw new RuntimeException("Error Log:\n" + errorString);
+        }
+    }
+
+    private static void executeCase(String lookAndFeelString, String shortLAF)
+            throws Exception {
+        if (tryLookAndFeel(lookAndFeelString)) {
+            createUI(shortLAF);
+            stepsToExecute(shortLAF);
+
+            createLeftUI(shortLAF);
+            stepsToExecute(shortLAF);
+
+            createRightUI(shortLAF);
+            stepsToExecute(shortLAF);
+        }
+    }
+
+    private static void stepsToExecute(String shortLAF) throws Exception {
+        robot.delay(100);
+        runTestCase(shortLAF);
+        robot.delay(1000);
+        cleanUp();
+        robot.delay(1000);
+    }
+
+    private static boolean tryLookAndFeel(String lookAndFeelString)
+            throws Exception {
+        try {
+            UIManager.setLookAndFeel(
+                    lookAndFeelString);
+
+        } catch (UnsupportedLookAndFeelException
+                | ClassNotFoundException
+                | InstantiationException
+                | IllegalAccessException e) {
+            return false;
+        }
+        return true;
+    }
+
+    private static void cleanUp() throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                frame.dispose();
+            }
+        });
+    }
+
+    private static void createUI(final String shortLAF)
+            throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                frame = new JFrame(shortLAF);
+                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+                frame.setVisible(true);
+                pane = new JTabbedPane();
+                pane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
+                frame.add(pane);
+                frame.setSize(500, 500);
+            }
+        });
+    }
+    private static void createLeftUI(final String shortLAF)
+            throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                frame = new JFrame(shortLAF);
+                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+                frame.setVisible(true);
+                pane = new JTabbedPane();
+                pane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
+                pane.setTabPlacement(SwingConstants.LEFT);
+                frame.add(pane);
+                frame.setSize(500, 500);
+            }
+        });
+    }
+
+    private static void createRightUI(final String shortLAF)
+            throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                frame = new JFrame(shortLAF);
+                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+                frame.setVisible(true);
+                pane = new JTabbedPane();
+                pane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
+                pane.setTabPlacement(SwingConstants.RIGHT);
+                frame.add(pane);
+                frame.setSize(500, 500);
+            }
+        });
+    }
+
+    private static void runTestCase(String shortLAF) throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                int i = 0;
+                int value= 0;
+                do {
+                    String title = "Tab" + (i + 1);
+                    pane.addTab(title, new JPanel());
+                    int tempValue = pane.getMinimumSize().height;
+                    if(value==0) {
+                        value = tempValue;
+                    }
+                    if(value != tempValue) {
+                        String error = "[" + shortLAF
+                            + "]: [Error]: TabbedScrollPane fails";
+                    errorString += error;
+                    }
+
+                    ++i;
+                } while (i < 10);
+            }
+        });
+    }
+}
+
--- a/jdk/test/javax/swing/LookAndFeel/6439354/TitledBorderTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/javax/swing/LookAndFeel/6439354/TitledBorderTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -23,7 +23,7 @@
 
  /*
  * @test
- * @bug 6439354
+ * @bug 8153056 8152647 6439354
  * @summary Verify TitleBorder appearance Color/Visibility for WLAF
  * @requires (os.family == "windows")
  * @run main/manual TitledBorderTest
@@ -33,6 +33,7 @@
 import java.awt.GridBagLayout;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
+import java.util.concurrent.CountDownLatch;
 import javax.swing.BorderFactory;
 import javax.swing.JButton;
 import javax.swing.JFrame;
@@ -41,7 +42,26 @@
 import javax.swing.SwingUtilities;
 import javax.swing.UIManager;
 
-public class TitledBorderTest implements ActionListener {
+public class TitledBorderTest {
+
+    public static void main(String args[]) throws Exception {
+        final CountDownLatch latch = new CountDownLatch(1);
+
+        TitledBorder test = new TitledBorder(latch);
+        Thread T1 = new Thread(test);
+        T1.start();
+
+        // wait for latch to complete
+        latch.await();
+
+        if (test.testResult == false) {
+            throw new RuntimeException("User Clicked Fail!"
+                    + " TitledBorder Not Valid");
+        }
+    }
+}
+
+class TitledBorder implements Runnable {
 
     private static GridBagLayout layout;
     private static JPanel mainControlPanel;
@@ -50,88 +70,98 @@
     private static JButton passButton;
     private static JButton failButton;
     private static JFrame mainFrame;
+    private final CountDownLatch latch;
+    public boolean testResult = false;
 
-    public static void main(String[] args) throws Exception {
-        TitledBorderTest titledBorderTest = new TitledBorderTest();
+    public TitledBorder(CountDownLatch latch) throws Exception {
+        this.latch = latch;
     }
 
-    public TitledBorderTest() throws Exception {
-        createUI();
+    @Override
+    public void run() {
+
+        try {
+            createUI();
+        } catch (Exception ex) {
+            if (mainFrame != null) {
+                mainFrame.dispose();
+            }
+            latch.countDown();
+            throw new RuntimeException("createUI Failed: " + ex.getMessage());
+        }
+
     }
 
     public final void createUI() throws Exception {
 
         UIManager.setLookAndFeel("com.sun.java.swing.plaf."
                 + "windows.WindowsLookAndFeel");
-
-        SwingUtilities.invokeAndWait(() -> {
-
-            mainFrame = new JFrame("Window LAF TitledBorder Test");
-            layout = new GridBagLayout();
-            mainControlPanel = new JPanel(layout);
-            resultButtonPanel = new JPanel(layout);
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                mainFrame = new JFrame("Window LAF TitledBorder Test");
+                layout = new GridBagLayout();
+                mainControlPanel = new JPanel(layout);
+                resultButtonPanel = new JPanel(layout);
 
-            GridBagConstraints gbc = new GridBagConstraints();
-            String instructions
-                    = "INSTRUCTIONS:"
-                    + "\n set Windows Theme to HighContrast#1."
-                    + "\n (ControlPanel->Personalization->High Contrast#1)"
-                    + "\n If Titled Border(Border Line) is visible then test"
-                    + " passes else failed.";
+                GridBagConstraints gbc = new GridBagConstraints();
+                String instructions
+                        = "INSTRUCTIONS:"
+                        + "\n set Windows Theme to HighContrast#1."
+                        + "\n (ControlPanel->Personalization->High Contrast#1)"
+                        + "\n If Titled Border(Border Line) is visible then test"
+                        + " passes else failed.";
 
-            instructionTextArea = new JTextArea();
-            instructionTextArea.setText(instructions);
-            instructionTextArea.setEnabled(false);
-            instructionTextArea.setDisabledTextColor(Color.black);
-            instructionTextArea.setBackground(Color.white);
+                instructionTextArea = new JTextArea();
+                instructionTextArea.setText(instructions);
+                instructionTextArea.setEnabled(false);
+                instructionTextArea.setDisabledTextColor(Color.black);
+                instructionTextArea.setBackground(Color.white);
 
-            gbc.gridx = 0;
-            gbc.gridy = 0;
-            gbc.fill = GridBagConstraints.HORIZONTAL;
-            mainControlPanel.add(instructionTextArea, gbc);
+                gbc.gridx = 0;
+                gbc.gridy = 0;
+                gbc.fill = GridBagConstraints.HORIZONTAL;
+                mainControlPanel.add(instructionTextArea, gbc);
 
-            mainControlPanel.setBorder(BorderFactory.
-                    createTitledBorder("Titled Border"));
+                mainControlPanel.setBorder(BorderFactory.
+                        createTitledBorder("Titled Border"));
 
-            passButton = new JButton("Pass");
-            passButton.setActionCommand("Pass");
-            passButton.addActionListener(TitledBorderTest.this);
-            failButton = new JButton("Fail");
-            failButton.setActionCommand("Fail");
-            failButton.addActionListener(TitledBorderTest.this);
-            gbc.gridx = 0;
-            gbc.gridy = 0;
-            resultButtonPanel.add(passButton, gbc);
-            gbc.gridx = 1;
-            gbc.gridy = 0;
-            resultButtonPanel.add(failButton, gbc);
+                passButton = new JButton("Pass");
+                passButton.setActionCommand("Pass");
+                passButton.addActionListener((ActionEvent e) -> {
+                    System.out.println("Pass Button pressed!");
+                    testResult = true;
+                    mainFrame.dispose();
+                    latch.countDown();
 
-            gbc.gridx = 0;
-            gbc.gridy = 1;
-            mainControlPanel.add(resultButtonPanel, gbc);
+                });
+                failButton = new JButton("Fail");
+                failButton.setActionCommand("Fail");
+                failButton.addActionListener(new ActionListener() {
+                    @Override
+                    public void actionPerformed(ActionEvent e) {
+                        System.out.println("Fail Button pressed!");
+                        testResult = false;
+                        mainFrame.dispose();
+                        latch.countDown();
+                    }
+                });
+                gbc.gridx = 0;
+                gbc.gridy = 0;
+                resultButtonPanel.add(passButton, gbc);
+                gbc.gridx = 1;
+                gbc.gridy = 0;
+                resultButtonPanel.add(failButton, gbc);
 
-            mainFrame.add(mainControlPanel);
-            mainFrame.pack();
-            mainFrame.setVisible(true);
+                gbc.gridx = 0;
+                gbc.gridy = 1;
+                mainControlPanel.add(resultButtonPanel, gbc);
+
+                mainFrame.add(mainControlPanel);
+                mainFrame.pack();
+                mainFrame.setVisible(true);
+            }
         });
+
     }
-
-    @Override
-    public void actionPerformed(ActionEvent evt) {
-        if (evt.getSource() instanceof JButton) {
-            JButton btn = (JButton) evt.getSource();
-            cleanUp();
-            switch (btn.getActionCommand()) {
-                case "Pass":
-                    break;
-                case "Fail":
-                    throw new AssertionError("User Clicked Fail!");
-            }
-        }
-    }
-
-    private static void cleanUp() {
-        mainFrame.dispose();
-    }
-
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/LookAndFeel/6897701/JMenuItemsTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2016, 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 6897701
+ * @summary Verify JMenu and JMenuItem Disabled state for Nimbus LAF
+ * @run main JMenuItemsTest
+ */
+import java.awt.Color;
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+
+public class JMenuItemsTest {
+
+    private static JFrame mainFrame;
+    private static JMenu disabledMenu;
+    private static JMenuItem disabledMenuItem;
+
+    public JMenuItemsTest() {
+        createUI();
+    }
+
+    private void createUI() {
+
+        mainFrame = new JFrame("Test");
+
+        disabledMenu = new JMenu("Disabled Menu");
+        disabledMenu.setForeground(Color.BLUE);
+        disabledMenu.setEnabled(false);
+
+        disabledMenuItem = new JMenuItem("Disabled MenuItem");
+        disabledMenuItem.setForeground(Color.BLUE);
+        disabledMenuItem.setEnabled(false);
+
+        JMenuBar menuBar = new JMenuBar();
+        menuBar = new JMenuBar();
+        menuBar.add(disabledMenu);
+        menuBar.add(disabledMenuItem);
+
+        mainFrame.add(menuBar);
+        mainFrame.pack();
+        mainFrame.setVisible(true);
+    }
+
+    private void dispose() {
+        mainFrame.dispose();
+    }
+
+    private void testDisabledStateOfJMenu() {
+
+        // Test disabled JMenu state
+        Rectangle rect = disabledMenu.getBounds();
+        BufferedImage image = new BufferedImage(rect.width, rect.height,
+                BufferedImage.TYPE_INT_ARGB);
+        disabledMenu.paint(image.getGraphics());
+        int y = image.getHeight() / 2;
+        for (int x = 0; x < image.getWidth(); x++) {
+            Color c = new Color(image.getRGB(x, y));
+            if (c.equals(Color.BLUE)) {
+                dispose();
+                throw new RuntimeException("JMenu Disabled"
+                        + " State not Valid.");
+            }
+        }
+
+    }
+
+    private void testDisabledStateOfJMenuItem() {
+
+        // Test disabled JMenuItem state
+        Rectangle rect = disabledMenuItem.getBounds();
+        BufferedImage image = new BufferedImage(rect.width, rect.height,
+                BufferedImage.TYPE_INT_ARGB);
+        disabledMenuItem.paint(image.getGraphics());
+        int y = image.getHeight() / 2;
+        for (int x = 0; x < image.getWidth(); x++) {
+            Color c = new Color(image.getRGB(x, y));
+            if (c.equals(Color.BLUE)) {
+                dispose();
+                throw new RuntimeException("JMenuItem Disabled"
+                        + " State not Valid.");
+            }
+        }
+
+    }
+
+    public static void main(String[] args) throws Exception {
+        UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
+        SwingUtilities.invokeAndWait(() -> {
+
+            try {
+                JMenuItemsTest obj = new JMenuItemsTest();
+                obj.testDisabledStateOfJMenu();
+                obj.testDisabledStateOfJMenuItem();
+                obj.dispose();
+
+            } catch (Exception ex) {
+                throw ex;
+            }
+
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/text/html/CSS/ColorValue/RGBColorValueTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8149631
+ * @summary rgb(...) CSS color values are not parsed properly
+ * @run main RGBColorValueTest
+ */
+
+import javax.swing.text.AttributeSet;
+import javax.swing.text.html.StyleSheet;
+
+import static javax.swing.text.html.CSS.Attribute.*;
+
+public class RGBColorValueTest {
+
+    public static void main(String[] args) {
+        StyleSheet styleSheet = new StyleSheet();
+        AttributeSet attributeSet = styleSheet.
+             getDeclaration("border-color: rgb(1, 2, 3)    rgb(1, 2, 4);");
+        if (!attributeSet.getAttribute(BORDER_TOP_COLOR).toString()
+                                                  .equals("rgb(1, 2, 3)") ||
+            !attributeSet.getAttribute(BORDER_BOTTOM_COLOR).toString()
+                                                  .equals("rgb(1, 2, 3)") ||
+            !attributeSet.getAttribute(BORDER_RIGHT_COLOR).toString()
+                                                  .equals("rgb(1, 2, 4)") ||
+            !attributeSet.getAttribute(BORDER_LEFT_COLOR).toString()
+                                                  .equals("rgb(1, 2, 4)") ) {
+            throw new RuntimeException("Failed");
+        }
+    }
+}
--- a/jdk/test/javax/swing/undo/UndoManager/AbstractDocumentUndoConcurrentTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/javax/swing/undo/UndoManager/AbstractDocumentUndoConcurrentTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, 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
@@ -104,8 +104,12 @@
                     e.printStackTrace();
                 }
                 for (int i = 0; i < 1000; i++) {
-                    undoManager.undoOrRedo();
-                    undoManager.undo();
+                    if(undoManager.canUndoOrRedo()) {
+                        undoManager.undoOrRedo();
+                    }
+                    if(undoManager.canUndo()) {
+                        undoManager.undo();
+                    }
                 }
                 System.out.println("t3 done");
             }
--- a/jdk/test/jdk/internal/jrtfs/WithSecurityManager.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/jdk/internal/jrtfs/WithSecurityManager.java	Thu Apr 28 23:08:16 2016 -0700
@@ -31,6 +31,7 @@
 import java.nio.file.FileSystems;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.util.Collections;
 
 public class WithSecurityManager {
     public static void main(String[] args) throws Exception {
@@ -61,7 +62,7 @@
 
         // check FileSystems.newFileSystem
         try {
-            FileSystems.newFileSystem(URI.create("jrt:/"), null);
+            FileSystems.newFileSystem(URI.create("jrt:/"), Collections.emptyMap());
             if (!allow) throw new RuntimeException("access not expected");
         } catch (SecurityException se) {
             if (allow)
--- a/jdk/test/jdk/internal/jrtfs/remote/Main.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/jdk/internal/jrtfs/remote/Main.java	Thu Apr 28 23:08:16 2016 -0700
@@ -30,6 +30,7 @@
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.util.Collections;
 import java.util.stream.Stream;
 
 /**
@@ -69,11 +70,12 @@
     private static FileSystem createFsWithURLClassloader(String javaHome) throws IOException{
         URL url = Paths.get(javaHome, "jrt-fs.jar").toUri().toURL();
         URLClassLoader loader = new URLClassLoader(new URL[] { url });
-        return FileSystems.newFileSystem(URI.create("jrt:/"), null, loader);
+        return FileSystems.newFileSystem(URI.create("jrt:/"),
+                                                    Collections.emptyMap(),
+                                                    loader);
     }
 
     private static FileSystem createFsByInstalledProvider() throws IOException {
         return FileSystems.getFileSystem(URI.create("jrt:/"));
     }
 }
-
--- a/jdk/test/jdk/internal/jrtfs/remote/RemoteRuntimeImageTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/jdk/internal/jrtfs/remote/RemoteRuntimeImageTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8141609
+ * @bug 8141609 8154403
  * @summary Verify JDK 8 can use jrt-fs.jar to work with jrt file system.
  * @run main RemoteRuntimeImageTest
  */
@@ -63,7 +63,6 @@
 
         String java = jdk8Path.resolve("bin/java").toAbsolutePath().toString();
         String javac = jdk8Path.resolve("bin/javac").toAbsolutePath().toString();
-
         Files.createDirectories(Paths.get(".", CLASSES_DIR));
         String jrtJar = Paths.get(TEST_JAVAHOME, JRTFS_JAR).toAbsolutePath().toString();
 
@@ -121,4 +120,3 @@
         return version.startsWith("\"1.8");
     }
 }
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/net/SocketFlow/SocketFlowBasic.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2016, 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 8765432
+ * @summary Basic test for SocketFlow API
+ * @run testng SocketFlowBasic
+ */
+
+import jdk.net.SocketFlow;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import static jdk.net.SocketFlow.*;
+import static org.testng.Assert.*;
+
+public class SocketFlowBasic {
+
+    @DataProvider
+    public Object[][] validPriorities() {
+        return new Object[][] { {HIGH_PRIORITY}, {NORMAL_PRIORITY} };
+    }
+
+    @Test(dataProvider = "validPriorities")
+    public void priority(long validPriority) {
+        SocketFlow flow = SocketFlow.create();
+        flow.bandwidth(validPriority);
+        long bandwidth = flow.bandwidth();
+        assertTrue(bandwidth == validPriority, "Expected " + validPriority + ", got" + bandwidth);
+    }
+
+    @DataProvider
+    public Object[][] invalidPriorities() {
+        return new Object[][] { {HIGH_PRIORITY+10}, {NORMAL_PRIORITY-10000} };
+    }
+
+    @Test(dataProvider = "invalidPriorities", expectedExceptions = IllegalArgumentException.class)
+    public void priority(int invalidPriority) {
+        SocketFlow flow = SocketFlow.create();
+        flow.priority(invalidPriority);
+    }
+
+    @DataProvider
+    public Object[][] positiveBandwidth() {
+        return new Object[][] { {0}, {100}, {Integer.MAX_VALUE}, {Long.MAX_VALUE} };
+    }
+
+    @Test(dataProvider = "positiveBandwidth")
+    public void bandwidth(long posBandwidth) {
+        SocketFlow flow = SocketFlow.create();
+        flow.bandwidth(posBandwidth);
+        long bandwidth = flow.bandwidth();
+        assertTrue(bandwidth == posBandwidth, "Expected " + posBandwidth + ", got" + bandwidth);
+    }
+
+
+    @DataProvider
+    public Object[][] negativeBandwidth() {
+        return new Object[][] { {-1}, {-100}, {Integer.MIN_VALUE}, {Long.MIN_VALUE} };
+    }
+
+    @Test(dataProvider = "negativeBandwidth", expectedExceptions = IllegalArgumentException.class)
+    public void invalidBandwidth(long negBandwidth) {
+        SocketFlow flow = SocketFlow.create();
+        flow.bandwidth(negBandwidth);
+    }
+
+    @Test
+    public void status() {
+        SocketFlow flow = SocketFlow.create();
+        assertTrue(flow.status() == Status.NO_STATUS);
+    }
+}
--- a/jdk/test/jdk/net/Sockets/Test.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/jdk/net/Sockets/Test.java	Thu Apr 28 23:08:16 2016 -0700
@@ -23,8 +23,9 @@
 
 /*
  * @test
- * @bug 8032808
- * @run main/othervm -Xcheck:jni Test
+ * @bug 8032808 8044773
+ * @modules jdk.net
+ * @run main/othervm -Xcheck:jni Test success
  * @run main/othervm/policy=policy.fail -Xcheck:jni Test fail
  * @run main/othervm/policy=policy.success -Xcheck:jni Test success
  */
@@ -35,15 +36,13 @@
 import java.util.concurrent.*;
 import java.util.Set;
 import jdk.net.*;
+import static java.lang.System.out;
 
 public class Test {
 
-    static boolean security;
-    static boolean success;
+    interface Runner { void run() throws Exception; }
 
-    interface Runner {
-        public void run() throws Exception;
-    }
+    static boolean expectSuccess;
 
     public static void main(String[] args) throws Exception {
 
@@ -52,95 +51,107 @@
 
         Sockets.supportedOptions(Socket.class);
 
-        security = System.getSecurityManager() != null;
-        success = security && args[0].equals("success");
+        expectSuccess = args[0].equals("success");
 
         // Main thing is to check for JNI problems
         // Doesn't matter if current system does not support the option
         // and currently setting the option with the loopback interface
         // doesn't work either
 
-        System.out.println ("Security Manager enabled: " + security);
-        if (security) {
-            System.out.println ("Success expected: " + success);
-        }
+        boolean sm = System.getSecurityManager() != null;
+        out.println("Security Manager enabled: " + sm);
+        out.println("Success expected: " + expectSuccess);
 
-        final SocketFlow flowIn = SocketFlow.create()
-            .bandwidth(1000)
-            .priority(SocketFlow.HIGH_PRIORITY);
+        SocketFlow flowIn = SocketFlow.create()
+                                      .bandwidth(1000)
+                                      .priority(SocketFlow.HIGH_PRIORITY);
 
-        ServerSocket ss = new ServerSocket(0);
-        int tcp_port = ss.getLocalPort();
-        final InetAddress loop = InetAddress.getByName("127.0.0.1");
-        final InetSocketAddress loopad = new InetSocketAddress(loop, tcp_port);
+        try (ServerSocket ss = new ServerSocket(0);
+             DatagramSocket dg = new DatagramSocket(0)) {
 
-        DatagramSocket dg = new DatagramSocket(0);
-        final int udp_port = dg.getLocalPort();
+            int tcp_port = ss.getLocalPort();
+            final InetAddress loop = InetAddress.getByName("127.0.0.1");
+            final InetSocketAddress loopad = new InetSocketAddress(loop, tcp_port);
+
+            final int udp_port = dg.getLocalPort();
 
-        // If option not available, end test
-        Set<SocketOption<?>> options = dg.supportedOptions();
-        if (!options.contains(ExtendedSocketOptions.SO_FLOW_SLA)) {
-            System.out.println("SO_FLOW_SLA not supported");
-            return;
-        }
+            // If option not available, end test
+            Set<SocketOption<?>> options = dg.supportedOptions();
+            if (!options.contains(ExtendedSocketOptions.SO_FLOW_SLA)) {
+                System.out.println("SO_FLOW_SLA not supported");
+                return;
+            }
 
-        final Socket s = new Socket("127.0.0.1", tcp_port);
-        final SocketChannel sc = SocketChannel.open();
-        sc.connect (new InetSocketAddress("127.0.0.1", tcp_port));
+            final Socket s = new Socket("127.0.0.1", tcp_port);
+            final SocketChannel sc = SocketChannel.open();
+            sc.connect(new InetSocketAddress("127.0.0.1", tcp_port));
 
-        doTest(()->{
-            Sockets.setOption(s, ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
-        });
-        doTest(()->{
-            Sockets.getOption(s, ExtendedSocketOptions.SO_FLOW_SLA);
-        });
-        doTest(()->{
-            sc.setOption(ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
-        });
-        doTest(()->{
-            sc.getOption(ExtendedSocketOptions.SO_FLOW_SLA);
-        });
-        doTest(()->{
-            DatagramSocket dg1 = new DatagramSocket(0);
-            dg1.connect(loop, udp_port);
-            Sockets.setOption(dg1, ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
-        });
-        doTest(()->{
-            DatagramChannel dg2 = DatagramChannel.open();
-            dg2.bind(new InetSocketAddress(loop, 0));
-            dg2.connect(new InetSocketAddress(loop, udp_port));
-            dg2.setOption(ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
-        });
-        doTest(()->{
-            MulticastSocket mc1 = new MulticastSocket(0);
-            mc1.connect(loop, udp_port);
-            Sockets.setOption(mc1, ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
-        });
-        doTest(()->{
-            AsynchronousSocketChannel asc = AsynchronousSocketChannel.open();
-            Future<Void> f = asc.connect(loopad);
-            f.get();
-            asc.setOption(ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
-        });
+            doTest("Sockets.setOption Socket", () -> {
+                out.println(flowIn);
+                Sockets.setOption(s, ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
+                out.println(flowIn);
+            });
+            doTest("Sockets.getOption Socket",() -> {
+                Sockets.getOption(s, ExtendedSocketOptions.SO_FLOW_SLA);
+                out.println(flowIn);
+            });
+            doTest("Sockets.setOption SocketChannel",() ->
+                sc.setOption(ExtendedSocketOptions.SO_FLOW_SLA, flowIn)
+            );
+            doTest("Sockets.getOption SocketChannel",() ->
+                sc.getOption(ExtendedSocketOptions.SO_FLOW_SLA)
+            );
+            doTest("Sockets.setOption DatagramSocket",() -> {
+                try (DatagramSocket dg1 = new DatagramSocket(0)) {
+                    dg1.connect(loop, udp_port);
+                    Sockets.setOption(dg1, ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
+                }
+            });
+            doTest("Sockets.setOption DatagramSocket 2", () -> {
+                try (DatagramChannel dg2 = DatagramChannel.open()) {
+                    dg2.bind(new InetSocketAddress(loop, 0));
+                    dg2.connect(new InetSocketAddress(loop, udp_port));
+                    dg2.setOption(ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
+                }
+            });
+            doTest("Sockets.setOption MulticastSocket", () -> {
+                try (MulticastSocket mc1 = new MulticastSocket(0)) {
+                    mc1.connect(loop, udp_port);
+                    Sockets.setOption(mc1, ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
+                }
+            });
+            doTest("Sockets.setOption AsynchronousSocketChannel", () -> {
+                try (AsynchronousSocketChannel asc = AsynchronousSocketChannel.open()) {
+                    Future<Void> f = asc.connect(loopad);
+                    f.get();
+                    asc.setOption(ExtendedSocketOptions.SO_FLOW_SLA, flowIn);
+                }
+            });
+        }
     }
 
-    static void doTest(Runner func) throws Exception {
+    static void doTest(String message, Runner func) throws Exception {
+        out.println(message);
         try {
             func.run();
-            if (security && !success) {
-                throw new RuntimeException("Test failed");
+            if (expectSuccess) {
+                out.println("Completed as expected");
+            } else {
+                throw new RuntimeException("Operation succeeded, but expected SecurityException");
             }
         } catch (SecurityException e) {
-            if (success) {
-                throw new RuntimeException("Test failed");
+            if (expectSuccess) {
+                throw new RuntimeException("Unexpected SecurityException", e);
+            } else {
+                out.println("Caught expected: " + e);
             }
         } catch (UnsupportedOperationException e) {
-            System.out.println (e);
+            System.out.println(e);
         } catch (IOException e) {
             // Probably a permission error, but we're not
             // going to check unless a specific permission exception
             // is defined.
-            System.out.println (e);
+            System.out.println(e);
         }
     }
 }
--- a/jdk/test/sanity/client/SwingSet/src/ButtonDemoScreenshotTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/SwingSet/src/ButtonDemoScreenshotTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -21,6 +21,8 @@
  * questions.
  */
 
+import com.sun.swingset3.demos.button.ButtonDemo;
+import org.jtregext.GuiTestListener;
 import java.awt.Point;
 import java.awt.Robot;
 import java.awt.event.InputEvent;
@@ -32,6 +34,7 @@
 import static org.jemmy2ext.JemmyExt.*;
 import org.testng.annotations.Test;
 import static com.sun.swingset3.demos.button.ButtonDemo.*;
+import org.testng.annotations.Listeners;
 
 /*
  * @test
@@ -41,31 +44,30 @@
  *          image is different from initial button image.
  *
  * @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
  * @library /sanity/client/lib/SwingSet3/src
  * @build org.jemmy2ext.JemmyExt
  * @build com.sun.swingset3.demos.button.ButtonDemo
  * @run testng ButtonDemoScreenshotTest
  */
+@Listeners(GuiTestListener.class)
 public class ButtonDemoScreenshotTest {
 
     private static final int BUTTON_COUNT = 6; // TODO: Decide about "open browser" buttons (value was 8 originally)
 
     @Test
     public void test() throws Exception {
-        captureDebugInfoOnFail(() -> {
-            Robot rob = new Robot();
+        Robot rob = new Robot();
 
-            new ClassReference(com.sun.swingset3.demos.button.ButtonDemo.class.getCanonicalName()).startApplication();
+        new ClassReference(ButtonDemo.class.getCanonicalName()).startApplication();
 
-            JFrameOperator mainFrame = new JFrameOperator(DEMO_TITLE);
-            waitImageIsStill(rob, mainFrame);
+        JFrameOperator mainFrame = new JFrameOperator(DEMO_TITLE);
+        waitImageIsStill(rob, mainFrame);
 
-            // Check all the buttons
-            for (int i = 0; i < BUTTON_COUNT; i++) {
-                checkButton(mainFrame, i, rob);
-            }
-        });
+        // Check all the buttons
+        for (int i = 0; i < BUTTON_COUNT; i++) {
+            checkButton(mainFrame, i, rob);
+        }
     }
 
     public void checkButton(JFrameOperator jfo, int i, Robot rob) {
--- a/jdk/test/sanity/client/SwingSet/src/ButtonDemoTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/SwingSet/src/ButtonDemoTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -21,6 +21,7 @@
  * questions.
  */
 
+import org.jtregext.GuiTestListener;
 import com.sun.swingset3.demos.JHyperlink;
 import com.sun.swingset3.demos.button.ButtonDemo;
 import java.util.concurrent.ArrayBlockingQueue;
@@ -38,7 +39,7 @@
 import static com.sun.swingset3.demos.button.ButtonDemo.*;
 import org.jemmy2ext.JemmyExt;
 import org.jemmy2ext.JemmyExt.MultiThreadedTryCatch;
-import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
+import org.testng.annotations.Listeners;
 
 /*
  * @test
@@ -48,12 +49,13 @@
  *          on buttons before and after click.
  *
  * @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
  * @library /sanity/client/lib/SwingSet3/src
  * @build org.jemmy2ext.JemmyExt
  * @build com.sun.swingset3.demos.button.ButtonDemo
  * @run testng ButtonDemoTest
  */
+@Listeners(GuiTestListener.class)
 public class ButtonDemoTest {
 
     private static final String[] BUTTON_TEXT_AFTER = {
@@ -92,34 +94,30 @@
     @Test
     public void test() throws Exception {
 
-        captureDebugInfoOnFail(() -> {
-
-            new ClassReference(ButtonDemo.class.getCanonicalName()).startApplication();
+        new ClassReference(ButtonDemo.class.getCanonicalName()).startApplication();
 
-            JFrameOperator mainFrame = new JFrameOperator(DEMO_TITLE);
-            mainFrame.setComparator(EXACT_STRING_COMPARATOR);
-
-            // Check all the buttons
-            for (int i = 0; i < BUTTON_TOOLTIP.length; i++) {
-                String tooltip = BUTTON_TOOLTIP[i];
-
-                JButtonOperator button = new JButtonOperator(mainFrame, new ByToolTipChooser(tooltip));
+        JFrameOperator mainFrame = new JFrameOperator(DEMO_TITLE);
+        mainFrame.setComparator(EXACT_STRING_COMPARATOR);
 
-                assertEquals(BUTTON_TEXT_BEFORE[i], button.getText());
+        // Check all the buttons
+        for (int i = 0; i < BUTTON_TOOLTIP.length; i++) {
+            String tooltip = BUTTON_TOOLTIP[i];
+
+            JButtonOperator button = new JButtonOperator(mainFrame, new ByToolTipChooser(tooltip));
 
-                // Two buttons are hyperlinks, we don't want to click them
-                if (!button.getSource().getClass().equals(JHyperlink.class)) {
-                    checkButton(button);
-                }
+            assertEquals(BUTTON_TEXT_BEFORE[i], button.getText());
 
-                if (BUTTON_TEXT_AFTER.length > i) {
-                    assertEquals(BUTTON_TEXT_AFTER[i], button.getText());
-                } else {
-                    assertEquals(BUTTON_TEXT_BEFORE[i], button.getText());
-                }
+            // Two buttons are hyperlinks, we don't want to click them
+            if (!button.getSource().getClass().equals(JHyperlink.class)) {
+                checkButton(button);
             }
 
-        });
+            if (BUTTON_TEXT_AFTER.length > i) {
+                assertEquals(BUTTON_TEXT_AFTER[i], button.getText());
+            } else {
+                assertEquals(BUTTON_TEXT_BEFORE[i], button.getText());
+            }
+        }
     }
 
     private void checkButton(JButtonOperator button) throws Exception {
--- a/jdk/test/sanity/client/SwingSet/src/ComboBoxDemoTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/SwingSet/src/ComboBoxDemoTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -21,6 +21,7 @@
  * questions.
  */
 
+import org.jtregext.GuiTestListener;
 import com.sun.swingset3.demos.combobox.ComboBoxDemo;
 import static org.testng.AssertJUnit.*;
 import org.testng.annotations.Test;
@@ -28,7 +29,7 @@
 import org.netbeans.jemmy.operators.JComboBoxOperator;
 import org.netbeans.jemmy.operators.JFrameOperator;
 import static com.sun.swingset3.demos.combobox.ComboBoxDemo.*;
-import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
+import org.testng.annotations.Listeners;
 
 /*
  * @test
@@ -37,12 +38,13 @@
  *          each value of each ComboBox.
  *
  * @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
  * @library /sanity/client/lib/SwingSet3/src
  * @build org.jemmy2ext.JemmyExt
  * @build com.sun.swingset3.demos.combobox.ComboBoxDemo
  * @run testng ComboBoxDemoTest
  */
+@Listeners(GuiTestListener.class)
 public class ComboBoxDemoTest {
 
     private static enum ComboBoxInfo {
@@ -61,14 +63,13 @@
 
     @Test
     public void test() throws Exception {
-        captureDebugInfoOnFail(() -> {
-            new ClassReference(ComboBoxDemo.class.getCanonicalName()).startApplication();
+
+        new ClassReference(ComboBoxDemo.class.getCanonicalName()).startApplication();
 
-            JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
-            for (ComboBoxInfo comboBoxInfo : ComboBoxInfo.values()) {
-                comboBoxChecker(frame, comboBoxInfo);
-            }
-        });
+        JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+        for (ComboBoxInfo comboBoxInfo : ComboBoxInfo.values()) {
+            comboBoxChecker(frame, comboBoxInfo);
+        }
     }
 
     private void comboBoxChecker(JFrameOperator jfo, ComboBoxInfo comboBoxInfo) {
--- a/jdk/test/sanity/client/SwingSet/src/ListDemoTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/SwingSet/src/ListDemoTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -21,6 +21,7 @@
  * questions.
  */
 
+import org.jtregext.GuiTestListener;
 import com.sun.swingset3.demos.list.ListDemo;
 import static com.sun.swingset3.demos.list.ListDemo.DEMO_TITLE;
 import static org.testng.AssertJUnit.*;
@@ -30,7 +31,7 @@
 import org.netbeans.jemmy.operators.JCheckBoxOperator;
 import org.netbeans.jemmy.operators.JFrameOperator;
 import org.netbeans.jemmy.operators.JListOperator;
-import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
+import org.testng.annotations.Listeners;
 
 /*
  * @test
@@ -40,64 +41,64 @@
  *          list.
  *
  * @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
  * @library /sanity/client/lib/SwingSet3/src
  * @build org.jemmy2ext.JemmyExt
  * @build com.sun.swingset3.demos.list.ListDemo
  * @run testng ListDemoTest
  */
+@Listeners(GuiTestListener.class)
 public class ListDemoTest {
 
     private static final int CHECKBOX_COUNT = 50;
 
     @Test
     public void test() throws Exception {
-        captureDebugInfoOnFail(() -> {
-            new ClassReference(ListDemo.class.getCanonicalName()).startApplication();
+
+        new ClassReference(ListDemo.class.getCanonicalName()).startApplication();
+
+        JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+        JListOperator listOp = new JListOperator(frame);
+
+        // Check *NO* Prefix and Suffixes Marked
+        for (int i = 0; i < CHECKBOX_COUNT; i++) {
+            JCheckBoxOperator checkBox = getJCheckBoxOperator(frame, i);
+            checkBox.changeSelection(false);
+        }
+        System.out.println("######## Number of Items = " + listOp.getModel().getSize());
+        assertEquals("Select None number of items is correct", 0, listOp.getModel().getSize());
 
-            JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
-            JListOperator listOp = new JListOperator(frame);
+        // Check *ALL* Prefix and Suffixes Marked
+        for (int i = 0; i < CHECKBOX_COUNT; i++) {
+            JCheckBoxOperator checkBox = getJCheckBoxOperator(frame, i);
+            checkBox.changeSelection(true);
+        }
+        System.out.println("######## Number of Items = " + listOp.getModel().getSize());
+        assertEquals("Select All number of items is correct", CHECKBOX_COUNT / 2 * CHECKBOX_COUNT / 2, listOp.getModel().getSize());
 
-            // Check *NO* Prefix and Suffixes Marked
-            for (int i = 0; i < CHECKBOX_COUNT; i++) {
-                JCheckBoxOperator checkBox = getJCheckBoxOperator(frame, i);
+        // Check *ALL* Prefix and *NO* Suffixes Marked
+        for (int i = 0; i < CHECKBOX_COUNT; i++) {
+            JCheckBoxOperator checkBox = getJCheckBoxOperator(frame, i);
+            if (i < CHECKBOX_COUNT / 2) {
+                checkBox.changeSelection(true);
+            } else {
                 checkBox.changeSelection(false);
             }
-            System.out.println("######## Number of Items = " + listOp.getModel().getSize());
-            assertEquals("Select None number of items is correct", 0, listOp.getModel().getSize());
+        }
+        System.out.println("######## Number of Items = " + listOp.getModel().getSize());
+        assertEquals("Select All Prefixes and NO Suffixes number of items is correct", 0, listOp.getModel().getSize());
 
-            // Check *ALL* Prefix and Suffixes Marked
-            for (int i = 0; i < CHECKBOX_COUNT; i++) {
-                JCheckBoxOperator checkBox = getJCheckBoxOperator(frame, i);
+        // Check *NO* Prefix and *ALL* Suffixes Marked
+        for (int i = 0; i < CHECKBOX_COUNT; i++) {
+            JCheckBoxOperator checkBox = getJCheckBoxOperator(frame, i);
+            if (i < CHECKBOX_COUNT / 2) {
+                checkBox.changeSelection(false);
+            } else {
                 checkBox.changeSelection(true);
             }
-            System.out.println("######## Number of Items = " + listOp.getModel().getSize());
-            assertEquals("Select All number of items is correct", CHECKBOX_COUNT / 2 * CHECKBOX_COUNT / 2, listOp.getModel().getSize());
-
-            // Check *ALL* Prefix and *NO* Suffixes Marked
-            for (int i = 0; i < CHECKBOX_COUNT; i++) {
-                JCheckBoxOperator checkBox = getJCheckBoxOperator(frame, i);
-                if (i < CHECKBOX_COUNT / 2) {
-                    checkBox.changeSelection(true);
-                } else {
-                    checkBox.changeSelection(false);
-                }
-            }
-            System.out.println("######## Number of Items = " + listOp.getModel().getSize());
-            assertEquals("Select All Prefixes and NO Suffixes number of items is correct", 0, listOp.getModel().getSize());
-
-            // Check *NO* Prefix and *ALL* Suffixes Marked
-            for (int i = 0; i < CHECKBOX_COUNT; i++) {
-                JCheckBoxOperator checkBox = getJCheckBoxOperator(frame, i);
-                if (i < CHECKBOX_COUNT / 2) {
-                    checkBox.changeSelection(false);
-                } else {
-                    checkBox.changeSelection(true);
-                }
-            }
-            System.out.println("######## Number of Items = " + listOp.getModel().getSize());
-            assertEquals("Select NO Prefixes and All Suffixes number of items is correct", 0, listOp.getModel().getSize());
-        });
+        }
+        System.out.println("######## Number of Items = " + listOp.getModel().getSize());
+        assertEquals("Select NO Prefixes and All Suffixes number of items is correct", 0, listOp.getModel().getSize());
     }
 
     private JCheckBoxOperator getJCheckBoxOperator(JFrameOperator frame, int index) {
--- a/jdk/test/sanity/client/SwingSet/src/OptionPaneDemoTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/SwingSet/src/OptionPaneDemoTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -21,10 +21,10 @@
  * questions.
  */
 
+import org.jtregext.GuiTestListener;
 import com.sun.swingset3.demos.optionpane.OptionPaneDemo;
 import static com.sun.swingset3.demos.optionpane.OptionPaneDemo.*;
 import javax.swing.UIManager;
-import static org.jemmy2ext.JemmyExt.*;
 import static org.testng.AssertJUnit.*;
 import org.testng.annotations.Test;
 import org.netbeans.jemmy.ClassReference;
@@ -34,6 +34,7 @@
 import org.netbeans.jemmy.operators.JFrameOperator;
 import org.netbeans.jemmy.operators.JLabelOperator;
 import org.netbeans.jemmy.operators.JTextFieldOperator;
+import org.testng.annotations.Listeners;
 
 
 /*
@@ -43,12 +44,13 @@
  *          and choosing different options in them.
  *
  * @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
  * @library /sanity/client/lib/SwingSet3/src
  * @build org.jemmy2ext.JemmyExt
  * @build com.sun.swingset3.demos.optionpane.OptionPaneDemo
  * @run testng OptionPaneDemoTest
  */
+@Listeners(GuiTestListener.class)
 public class OptionPaneDemoTest {
 
     public static final String SOME_TEXT_TO_TYPE = "I am some text";
@@ -59,21 +61,20 @@
     public static final String TEXT_TO_TYPE = "Hooray! I'm a textField";
     public static final String NO = "No";
     public static final String YES = "Yes";
-    public static final String SELECT_AN__OPTION = UIManager.getString("OptionPane.titleText");
+    public static final String SELECT_AN_OPTION = UIManager.getString("OptionPane.titleText");
 
     @Test
     public void test() throws Exception {
-        captureDebugInfoOnFail(() -> {
-            new ClassReference(OptionPaneDemo.class.getCanonicalName()).startApplication();
 
-            JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+        new ClassReference(OptionPaneDemo.class.getCanonicalName()).startApplication();
+
+        JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
 
-            showInputDialog(frame);
-            showWarningDialog(frame);
-            showMessageDialog(frame);
-            showComponentDialog(frame);
-            showConfirmationDialog(frame);
-        });
+        showInputDialog(frame);
+        showWarningDialog(frame);
+        showMessageDialog(frame);
+        showComponentDialog(frame);
+        showConfirmationDialog(frame);
     }
 
     public void showInputDialog(JFrameOperator jfo) throws Exception {
@@ -286,7 +287,7 @@
         {
             new JButtonOperator(jfo, CONFIRM_BUTTON).pushNoBlock();
 
-            JDialogOperator jdo = new JDialogOperator(SELECT_AN__OPTION);
+            JDialogOperator jdo = new JDialogOperator(SELECT_AN_OPTION);
             new JButtonOperator(jdo, YES).pushNoBlock();
 
             JDialogOperator jdo1 = new JDialogOperator(MESSAGE);
@@ -306,7 +307,7 @@
         {
             new JButtonOperator(jfo, CONFIRM_BUTTON).pushNoBlock();
 
-            JDialogOperator jdo = new JDialogOperator(SELECT_AN__OPTION);
+            JDialogOperator jdo = new JDialogOperator(SELECT_AN_OPTION);
             new JButtonOperator(jdo, NO).pushNoBlock();
 
             JDialogOperator jdo1 = new JDialogOperator(MESSAGE);
@@ -326,7 +327,7 @@
         {
             new JButtonOperator(jfo, CONFIRM_BUTTON).pushNoBlock();
 
-            JDialogOperator jdo = new JDialogOperator(SELECT_AN__OPTION);
+            JDialogOperator jdo = new JDialogOperator(SELECT_AN_OPTION);
 
             assertTrue("Show Confirmation Dialog Cancel Option", jdo.isShowing());
 
--- a/jdk/test/sanity/client/SwingSet/src/ProgressBarDemoTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/SwingSet/src/ProgressBarDemoTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -21,6 +21,7 @@
  * questions.
  */
 
+import org.jtregext.GuiTestListener;
 import com.sun.swingset3.demos.progressbar.ProgressBarDemo;
 import static com.sun.swingset3.demos.progressbar.ProgressBarDemo.*;
 import java.awt.Component;
@@ -31,7 +32,7 @@
 import org.netbeans.jemmy.operators.JButtonOperator;
 import org.netbeans.jemmy.operators.JFrameOperator;
 import org.netbeans.jemmy.operators.JProgressBarOperator;
-import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
+import org.testng.annotations.Listeners;
 
 /*
  * @test
@@ -40,31 +41,31 @@
  *          buttons and checking the progress bar and the buttons state.
  *
  * @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
  * @library /sanity/client/lib/SwingSet3/src
  * @build org.jemmy2ext.JemmyExt
  * @build com.sun.swingset3.demos.progressbar.ProgressBarDemo
  * @run testng ProgressBarDemoTest
  */
+@Listeners(GuiTestListener.class)
 public class ProgressBarDemoTest {
 
     @Test
     public void test() throws Exception {
-        captureDebugInfoOnFail(() -> {
-            new ClassReference(ProgressBarDemo.class.getCanonicalName()).startApplication();
 
-            JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+        new ClassReference(ProgressBarDemo.class.getCanonicalName()).startApplication();
+
+        JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
 
-            JButtonOperator startButton = new JButtonOperator(frame, START_BUTTON);
-            JButtonOperator stopButton = new JButtonOperator(frame, STOP_BUTTON);
-            JProgressBarOperator jpbo = new JProgressBarOperator(frame);
+        JButtonOperator startButton = new JButtonOperator(frame, START_BUTTON);
+        JButtonOperator stopButton = new JButtonOperator(frame, STOP_BUTTON);
+        JProgressBarOperator jpbo = new JProgressBarOperator(frame);
 
-            // Check that progress completes and corect enable/disable of start/stop buttons
-            checkCompleteProgress(frame, startButton, stopButton, jpbo);
+        // Check that progress completes and corect enable/disable of start/stop buttons
+        checkCompleteProgress(frame, startButton, stopButton, jpbo);
 
-            // Check progess bar progression and start/stop button disabled/enabled states
-            checkStartStop(frame, startButton, stopButton, jpbo);
-        });
+        // Check progess bar progression and start/stop button disabled/enabled states
+        checkStartStop(frame, startButton, stopButton, jpbo);
     }
 
     // Check that progress completes and corect enable/disable of start/stop buttons
--- a/jdk/test/sanity/client/SwingSet/src/ScrollPaneDemoTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/SwingSet/src/ScrollPaneDemoTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -21,6 +21,7 @@
  * questions.
  */
 
+import org.jtregext.GuiTestListener;
 import com.sun.swingset3.demos.scrollpane.ScrollPaneDemo;
 import static com.sun.swingset3.demos.scrollpane.ScrollPaneDemo.DEMO_TITLE;
 import static org.testng.AssertJUnit.*;
@@ -28,7 +29,7 @@
 import org.netbeans.jemmy.ClassReference;
 import org.netbeans.jemmy.operators.JFrameOperator;
 import org.netbeans.jemmy.operators.JScrollPaneOperator;
-import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
+import org.testng.annotations.Listeners;
 
 /*
  * @test
@@ -37,73 +38,73 @@
  *          to left and to right and checking scroll bar values.
  *
  * @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
  * @library /sanity/client/lib/SwingSet3/src
  * @build org.jemmy2ext.JemmyExt
  * @build com.sun.swingset3.demos.scrollpane.ScrollPaneDemo
  * @run testng ScrollPaneDemoTest
  */
+@Listeners(GuiTestListener.class)
 public class ScrollPaneDemoTest {
 
     @Test
     public void test() throws Exception {
-        captureDebugInfoOnFail(() -> {
-            new ClassReference(ScrollPaneDemo.class.getName()).startApplication();
+
+        new ClassReference(ScrollPaneDemo.class.getName()).startApplication();
 
-            JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
-            JScrollPaneOperator jspo = new JScrollPaneOperator(frame);
+        JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+        JScrollPaneOperator jspo = new JScrollPaneOperator(frame);
 
-            // Set initial scrollbar positions
-            int initialVerticalValue = jspo.getVerticalScrollBar().getValue();
-            int initialHorizontalValue = jspo.getHorizontalScrollBar().getValue();
+        // Set initial scrollbar positions
+        int initialVerticalValue = jspo.getVerticalScrollBar().getValue();
+        int initialHorizontalValue = jspo.getHorizontalScrollBar().getValue();
 
-            System.out.println("Initial Vertical Value = " + jspo.getVerticalScrollBar().getValue());
-            System.out.println("Initial HoriZontal Value = " + jspo.getHorizontalScrollBar().getValue());
+        System.out.println("Initial Vertical Value = " + jspo.getVerticalScrollBar().getValue());
+        System.out.println("Initial HoriZontal Value = " + jspo.getHorizontalScrollBar().getValue());
 
-            // Check scroll to Bottom
-            {
-                jspo.scrollToBottom();
-                int currentValue = jspo.getVerticalScrollBar().getValue();
-                System.out.println("Final Value = " + currentValue);
-                assertTrue("Scroll to Bottom of Pane "
-                        + "(initialVerticalValue, actual value: " + initialVerticalValue + " "
-                        + "< currentValue, actual value = " + currentValue + ")",
-                        initialVerticalValue < currentValue);
-            }
+        // Check scroll to Bottom
+        {
+            jspo.scrollToBottom();
+            int currentValue = jspo.getVerticalScrollBar().getValue();
+            System.out.println("Final Value = " + currentValue);
+            assertTrue("Scroll to Bottom of Pane "
+                    + "(initialVerticalValue, actual value: " + initialVerticalValue + " "
+                    + "< currentValue, actual value = " + currentValue + ")",
+                    initialVerticalValue < currentValue);
+        }
 
-            // Check scroll to Top
-            {
-                jspo.scrollToTop();
-                int currentValue = jspo.getVerticalScrollBar().getValue();
-                System.out.println("Top Scroll Final Value = " + currentValue);
-                assertTrue("Scroll to Top of Pane "
-                        + "(initialVerticalValue, actual value: " + initialVerticalValue + " "
-                        + "> currentValue, actual value = " + currentValue + ")",
-                        initialVerticalValue > currentValue);
-            }
+        // Check scroll to Top
+        {
+            jspo.scrollToTop();
+            int currentValue = jspo.getVerticalScrollBar().getValue();
+            System.out.println("Top Scroll Final Value = " + currentValue);
+            assertTrue("Scroll to Top of Pane "
+                    + "(initialVerticalValue, actual value: " + initialVerticalValue + " "
+                    + "> currentValue, actual value = " + currentValue + ")",
+                    initialVerticalValue > currentValue);
+        }
 
-            // Check scroll to Left
-            {
-                jspo.scrollToLeft();
-                int currentValue = jspo.getHorizontalScrollBar().getValue();
-                System.out.println("Scroll to Left Final Value = " + currentValue);
-                assertTrue("Scroll to Left of Pane "
-                        + "(initialHorizontalValue, actual value: " + initialHorizontalValue + " "
-                        + "> currentValue, actual value = " + currentValue + ")",
-                        initialHorizontalValue > currentValue);
-            }
+        // Check scroll to Left
+        {
+            jspo.scrollToLeft();
+            int currentValue = jspo.getHorizontalScrollBar().getValue();
+            System.out.println("Scroll to Left Final Value = " + currentValue);
+            assertTrue("Scroll to Left of Pane "
+                    + "(initialHorizontalValue, actual value: " + initialHorizontalValue + " "
+                    + "> currentValue, actual value = " + currentValue + ")",
+                    initialHorizontalValue > currentValue);
+        }
 
-            // Check scroll to Right
-            {
-                jspo.scrollToRight();
-                int currentValue = jspo.getHorizontalScrollBar().getValue();
-                System.out.println("Scroll to Right Final Value = " + currentValue);
-                assertTrue("Scroll to Right of Pane "
-                        + "(initialHorizontalValue, actual value: " + initialHorizontalValue + " "
-                        + "< currentValue, actual value = " + currentValue + ")",
-                        initialHorizontalValue < currentValue);
-            }
-        });
+        // Check scroll to Right
+        {
+            jspo.scrollToRight();
+            int currentValue = jspo.getHorizontalScrollBar().getValue();
+            System.out.println("Scroll to Right Final Value = " + currentValue);
+            assertTrue("Scroll to Right of Pane "
+                    + "(initialHorizontalValue, actual value: " + initialHorizontalValue + " "
+                    + "< currentValue, actual value = " + currentValue + ")",
+                    initialHorizontalValue < currentValue);
+        }
     }
 
 }
--- a/jdk/test/sanity/client/SwingSet/src/SpinnerDemoTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/SwingSet/src/SpinnerDemoTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -21,6 +21,7 @@
  * questions.
  */
 
+import org.jtregext.GuiTestListener;
 import com.sun.swingset3.demos.spinner.SpinnerDemo;
 import static com.sun.swingset3.demos.spinner.SpinnerDemo.DEMO_TITLE;
 import java.text.DecimalFormat;
@@ -30,7 +31,7 @@
 import org.netbeans.jemmy.operators.JFrameOperator;
 import org.netbeans.jemmy.operators.JSpinnerOperator;
 import org.netbeans.jemmy.operators.JTextFieldOperator;
-import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
+import org.testng.annotations.Listeners;
 
 /*
  * @test
@@ -39,12 +40,13 @@
  *          the spinner button and checking text field value.
  *
  * @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
  * @library /sanity/client/lib/SwingSet3/src
  * @build org.jemmy2ext.JemmyExt
  * @build com.sun.swingset3.demos.spinner.SpinnerDemo
  * @run testng SpinnerDemoTest
  */
+@Listeners(GuiTestListener.class)
 public class SpinnerDemoTest {
 
     private static final int SPINNERS_COUNT = 9;
@@ -52,16 +54,14 @@
 
     @Test
     public void test() throws Exception {
-        captureDebugInfoOnFail(() -> {
-            new ClassReference(SpinnerDemo.class.getCanonicalName()).startApplication();
+        new ClassReference(SpinnerDemo.class.getCanonicalName()).startApplication();
 
-            JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+        JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
 
-            // Check changing different spinners
-            for (int i = 0; i < SPINNERS_COUNT; i++) {
-                changeValues(frame, i);
-            }
-        });
+        // Check changing different spinners
+        for (int i = 0; i < SPINNERS_COUNT; i++) {
+            changeValues(frame, i);
+        }
     }
 
     private void changeValues(JFrameOperator jfo, int spinnerIndex) throws Exception {
--- a/jdk/test/sanity/client/SwingSet/src/SplitPaneDemoTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/SwingSet/src/SplitPaneDemoTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -21,6 +21,7 @@
  * questions.
  */
 
+import org.jtregext.GuiTestListener;
 import com.sun.swingset3.demos.splitpane.SplitPaneDemo;
 import static com.sun.swingset3.demos.splitpane.SplitPaneDemo.*;
 import java.awt.event.KeyEvent;
@@ -35,6 +36,7 @@
 import org.netbeans.jemmy.operators.JSplitPaneOperator;
 import org.netbeans.jemmy.operators.JTextFieldOperator;
 import static org.jemmy2ext.JemmyExt.*;
+import org.testng.annotations.Listeners;
 
 /*
  * @test
@@ -44,39 +46,39 @@
  *          and changing the divider orientation.
  *
  * @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
  * @library /sanity/client/lib/SwingSet3/src
  * @build org.jemmy2ext.JemmyExt
  * @build com.sun.swingset3.demos.splitpane.SplitPaneDemo
  * @run testng SplitPaneDemoTest
  */
+@Listeners(GuiTestListener.class)
 public class SplitPaneDemoTest {
 
     @Test
     public void test() throws Exception {
-        captureDebugInfoOnFail(() -> {
-            new ClassReference(SplitPaneDemo.class.getCanonicalName()).startApplication();
 
-            JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+        new ClassReference(SplitPaneDemo.class.getCanonicalName()).startApplication();
+
+        JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
 
-            JSplitPaneOperator splitPane = new JSplitPaneOperator(frame);
+        JSplitPaneOperator splitPane = new JSplitPaneOperator(frame);
 
-            // Toggle OneTouch Expandable
-            checkOneTouch(frame, splitPane, true);
-            checkOneTouch(frame, splitPane, false);
+        // Toggle OneTouch Expandable
+        checkOneTouch(frame, splitPane, true);
+        checkOneTouch(frame, splitPane, false);
 
-            // Check changing divider size to minimum and maximum values
-            changeDividerSize(frame, splitPane, 50);
-            changeDividerSize(frame, splitPane, 6);
+        // Check changing divider size to minimum and maximum values
+        changeDividerSize(frame, splitPane, 50);
+        changeDividerSize(frame, splitPane, 6);
 
-            // Check moving the divider
-            checkDividerMoves(frame, splitPane, false);
-            checkDividerMoves(frame, splitPane, true);
+        // Check moving the divider
+        checkDividerMoves(frame, splitPane, false);
+        checkDividerMoves(frame, splitPane, true);
 
-            // Check different minumum Day/Night sizes
-            changeMinimumSizes(frame, splitPane, 100);
-            changeMinimumSizes(frame, splitPane, 0);
-        });
+        // Check different minumum Day/Night sizes
+        changeMinimumSizes(frame, splitPane, 100);
+        changeMinimumSizes(frame, splitPane, 0);
     }
 
     // Check for different day and night minimum size
--- a/jdk/test/sanity/client/SwingSet/src/TabbedPaneDemoTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/SwingSet/src/TabbedPaneDemoTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -21,6 +21,7 @@
  * questions.
  */
 
+import org.jtregext.GuiTestListener;
 import com.sun.swingset3.demos.tabbedpane.TabbedPaneDemo;
 import static com.sun.swingset3.demos.tabbedpane.TabbedPaneDemo.*;
 import static org.jemmy2ext.JemmyExt.getLabeledContainerOperator;
@@ -31,7 +32,7 @@
 import org.netbeans.jemmy.operators.JFrameOperator;
 import org.netbeans.jemmy.operators.JRadioButtonOperator;
 import org.netbeans.jemmy.operators.JTabbedPaneOperator;
-import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
+import org.testng.annotations.Listeners;
 
 /*
  * @test
@@ -40,25 +41,24 @@
  *          positions, opening each tab and verifying the the tab gets selected.
  *
  * @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
  * @library /sanity/client/lib/SwingSet3/src
  * @build org.jemmy2ext.JemmyExt
  * @build com.sun.swingset3.demos.tabbedpane.TabbedPaneDemo
  * @run testng TabbedPaneDemoTest
  */
+@Listeners(GuiTestListener.class)
 public class TabbedPaneDemoTest {
 
     @Test
     public void test() throws Exception {
-        captureDebugInfoOnFail(() -> {
-            new ClassReference(TabbedPaneDemo.class.getCanonicalName()).startApplication();
+        new ClassReference(TabbedPaneDemo.class.getCanonicalName()).startApplication();
 
-            JFrameOperator mainFrame = new JFrameOperator(DEMO_TITLE);
+        JFrameOperator mainFrame = new JFrameOperator(DEMO_TITLE);
 
-            for (String tp : new String[]{TOP, LEFT, BOTTOM, RIGHT}) {
-                testTabs(mainFrame, tp);
-            }
-        });
+        for (String tp : new String[]{TOP, LEFT, BOTTOM, RIGHT}) {
+            testTabs(mainFrame, tp);
+        }
     }
 
     public void testTabs(JFrameOperator mainFrame, String tabPlacement) throws Exception {
--- a/jdk/test/sanity/client/SwingSet/src/TextFieldDemoTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/SwingSet/src/TextFieldDemoTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -21,6 +21,7 @@
  * questions.
  */
 
+import org.jtregext.GuiTestListener;
 import com.sun.swingset3.demos.textfield.JHistoryTextField;
 import com.sun.swingset3.demos.textfield.TextFieldDemo;
 import static com.sun.swingset3.demos.textfield.TextFieldDemo.*;
@@ -41,6 +42,7 @@
 import org.netbeans.jemmy.operators.JLabelOperator;
 import org.netbeans.jemmy.operators.JPasswordFieldOperator;
 import org.netbeans.jemmy.operators.JTextFieldOperator;
+import org.testng.annotations.Listeners;
 
 /*
  * @test
@@ -49,25 +51,25 @@
  *          checking that app reacts accordingly.
  *
  * @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
  * @library /sanity/client/lib/SwingSet3/src
  * @build org.jemmy2ext.JemmyExt
  * @build com.sun.swingset3.demos.textfield.TextFieldDemo
  * @run testng TextFieldDemoTest
  */
+@Listeners(GuiTestListener.class)
 public class TextFieldDemoTest {
 
     @Test
     public void test() throws Exception {
-        captureDebugInfoOnFail(() -> {
-            new ClassReference(TextFieldDemo.class.getCanonicalName()).startApplication();
 
-            JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+        new ClassReference(TextFieldDemo.class.getCanonicalName()).startApplication();
 
-            historyTextField(frame);
-            dateTextField(frame);
-            passwordField(frame);
-        });
+        JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+
+        historyTextField(frame);
+        dateTextField(frame);
+        passwordField(frame);
     }
 
     private void historyTextField(JFrameOperator jfo) throws Exception {
--- a/jdk/test/sanity/client/SwingSet/src/ToggleButtonDemoTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/SwingSet/src/ToggleButtonDemoTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -21,6 +21,7 @@
  * questions.
  */
 
+import org.jtregext.GuiTestListener;
 import com.sun.swingset3.DemoProperties;
 import com.sun.swingset3.demos.togglebutton.DirectionPanel;
 import com.sun.swingset3.demos.togglebutton.LayoutControlPanel;
@@ -40,7 +41,7 @@
 import org.netbeans.jemmy.operators.JFrameOperator;
 import org.netbeans.jemmy.operators.JRadioButtonOperator;
 import org.netbeans.jemmy.operators.JTabbedPaneOperator;
-import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
+import org.testng.annotations.Listeners;
 
 /*
  * @test
@@ -53,50 +54,49 @@
  *          selected.
  *
  * @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
  * @library /sanity/client/lib/SwingSet3/src
  * @build org.jemmy2ext.JemmyExt
  * @build com.sun.swingset3.demos.togglebutton.ToggleButtonDemo
  * @run testng ToggleButtonDemoTest
  */
+@Listeners(GuiTestListener.class)
 public class ToggleButtonDemoTest {
 
     @Test
     public void test() throws Exception {
-        captureDebugInfoOnFail(() -> {
-            new ClassReference(ToggleButtonDemo.class.getCanonicalName()).startApplication();
+        new ClassReference(ToggleButtonDemo.class.getCanonicalName()).startApplication();
 
-            JFrameOperator mainFrame = new JFrameOperator(ToggleButtonDemo.class.getAnnotation(DemoProperties.class).value());
-            JTabbedPaneOperator tabPane = new JTabbedPaneOperator(mainFrame);
+        JFrameOperator mainFrame = new JFrameOperator(ToggleButtonDemo.class.getAnnotation(DemoProperties.class).value());
+        JTabbedPaneOperator tabPane = new JTabbedPaneOperator(mainFrame);
 
-            // Radio Button Toggles
-            testRadioButtons(getBorderTitledJPanelOperator(mainFrame, TEXT_RADIO_BUTTONS), 3, null);
-            testRadioButtons(getBorderTitledJPanelOperator(mainFrame, IMAGE_RADIO_BUTTONS), 3, null);
-            testRadioButtons(getLabeledContainerOperator(mainFrame, PAD_AMOUNT), 3, (t, i) -> DEFAULT.equals(t));
+        // Radio Button Toggles
+        testRadioButtons(getBorderTitledJPanelOperator(mainFrame, TEXT_RADIO_BUTTONS), 3, null);
+        testRadioButtons(getBorderTitledJPanelOperator(mainFrame, IMAGE_RADIO_BUTTONS), 3, null);
+        testRadioButtons(getLabeledContainerOperator(mainFrame, PAD_AMOUNT), 3, (t, i) -> DEFAULT.equals(t));
 
-            // switch to the Check Boxes Tab
-            tabPane.selectPage(CHECK_BOXES);
+        // switch to the Check Boxes Tab
+        tabPane.selectPage(CHECK_BOXES);
 
-            // Check Box Toggles
-            ContainerOperator<?> textCheckBoxesJPanel = getBorderTitledJPanelOperator(mainFrame, TEXT_CHECKBOXES);
-            testCheckBox(textCheckBoxesJPanel, CHECK1, false);
-            testCheckBox(textCheckBoxesJPanel, CHECK2, false);
-            testCheckBox(textCheckBoxesJPanel, CHECK3, false);
+        // Check Box Toggles
+        ContainerOperator<?> textCheckBoxesJPanel = getBorderTitledJPanelOperator(mainFrame, TEXT_CHECKBOXES);
+        testCheckBox(textCheckBoxesJPanel, CHECK1, false);
+        testCheckBox(textCheckBoxesJPanel, CHECK2, false);
+        testCheckBox(textCheckBoxesJPanel, CHECK3, false);
 
-            ContainerOperator<?> imageCheckBoxesJPanel = getBorderTitledJPanelOperator(mainFrame, IMAGE_CHECKBOXES);
-            testCheckBox(imageCheckBoxesJPanel, CHECK1, false);
-            testCheckBox(imageCheckBoxesJPanel, CHECK2, false);
-            testCheckBox(imageCheckBoxesJPanel, CHECK3, false);
+        ContainerOperator<?> imageCheckBoxesJPanel = getBorderTitledJPanelOperator(mainFrame, IMAGE_CHECKBOXES);
+        testCheckBox(imageCheckBoxesJPanel, CHECK1, false);
+        testCheckBox(imageCheckBoxesJPanel, CHECK2, false);
+        testCheckBox(imageCheckBoxesJPanel, CHECK3, false);
 
-            ContainerOperator<?> displayOptionsContainer = getLabeledContainerOperator(mainFrame, DISPLAY_OPTIONS);
-            testCheckBox(displayOptionsContainer, PAINT_BORDER, false);
-            testCheckBox(displayOptionsContainer, PAINT_FOCUS, true);
-            testCheckBox(displayOptionsContainer, ENABLED, true);
-            testCheckBox(displayOptionsContainer, CONTENT_FILLED, true);
+        ContainerOperator<?> displayOptionsContainer = getLabeledContainerOperator(mainFrame, DISPLAY_OPTIONS);
+        testCheckBox(displayOptionsContainer, PAINT_BORDER, false);
+        testCheckBox(displayOptionsContainer, PAINT_FOCUS, true);
+        testCheckBox(displayOptionsContainer, ENABLED, true);
+        testCheckBox(displayOptionsContainer, CONTENT_FILLED, true);
 
-            // Direction Button Toggles
-            testToggleButtons(mainFrame);
-        });
+        // Direction Button Toggles
+        testToggleButtons(mainFrame);
     }
 
     /**
--- a/jdk/test/sanity/client/SwingSet/src/TreeDemoTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/SwingSet/src/TreeDemoTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -21,6 +21,7 @@
  * questions.
  */
 
+import org.jtregext.GuiTestListener;
 import com.sun.swingset3.demos.tree.TreeDemo;
 import static com.sun.swingset3.demos.tree.TreeDemo.DEMO_TITLE;
 import javax.swing.tree.TreePath;
@@ -29,7 +30,7 @@
 import org.netbeans.jemmy.ClassReference;
 import org.netbeans.jemmy.operators.JFrameOperator;
 import org.netbeans.jemmy.operators.JTreeOperator;
-import static org.jemmy2ext.JemmyExt.captureDebugInfoOnFail;
+import org.testng.annotations.Listeners;
 
 /*
  * @test
@@ -42,67 +43,67 @@
  *          vertically (as ScrollPane allows it).
  *
  * @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
  * @library /sanity/client/lib/SwingSet3/src
  * @build org.jemmy2ext.JemmyExt
  * @build com.sun.swingset3.demos.tree.TreeDemo
  * @run testng TreeDemoTest
  */
+@Listeners(GuiTestListener.class)
 public class TreeDemoTest {
 
     @Test
     public void test() throws Exception {
-        captureDebugInfoOnFail(() -> {
-            new ClassReference(TreeDemo.class.getCanonicalName()).startApplication();
 
-            JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
+        new ClassReference(TreeDemo.class.getCanonicalName()).startApplication();
+
+        JFrameOperator frame = new JFrameOperator(DEMO_TITLE);
 
-            JTreeOperator tree = new JTreeOperator(frame);
+        JTreeOperator tree = new JTreeOperator(frame);
 
-            assertEquals("Initial number of rows in the tree", 4, tree.getRowCount());
+        assertEquals("Initial number of rows in the tree", 4, tree.getRowCount());
 
-            int initialTreeHeight = tree.getHeight();
+        int initialTreeHeight = tree.getHeight();
 
-            // expand all nodes
-            int expandsCount = 0;
-            for (int i = 0; i < tree.getRowCount(); i++) {
-                TreePath tp = tree.getPathForRow(i);
-                if (tree.getChildCount(tp) > 0 && !tree.isExpanded(tp)) {
-                    tree.expandRow(i);
-                    expandsCount++;
-                }
+        // expand all nodes
+        int expandsCount = 0;
+        for (int i = 0; i < tree.getRowCount(); i++) {
+            TreePath tp = tree.getPathForRow(i);
+            if (tree.getChildCount(tp) > 0 && !tree.isExpanded(tp)) {
+                tree.expandRow(i);
+                expandsCount++;
             }
+        }
 
-            assertEquals("Number of rows expanded", 75, expandsCount);
-            assertEquals("Number of rows in the tree after expanding all of them",
-                    616, tree.getRowCount());
+        assertEquals("Number of rows expanded", 75, expandsCount);
+        assertEquals("Number of rows in the tree after expanding all of them",
+                616, tree.getRowCount());
 
-            int expandedTreeHeight = tree.getHeight();
-            assertTrue("Expanded tree height has increased, current "
-                    + expandedTreeHeight + " > initial " + initialTreeHeight,
-                    expandedTreeHeight > initialTreeHeight);
+        int expandedTreeHeight = tree.getHeight();
+        assertTrue("Expanded tree height has increased, current "
+                + expandedTreeHeight + " > initial " + initialTreeHeight,
+                expandedTreeHeight > initialTreeHeight);
 
-            // collapse all nodes
-            int collapsesCount = 0;
-            for (int i = tree.getRowCount() - 1; i >= 0; i--) {
-                TreePath tp = tree.getPathForRow(i);
-                if (tree.getChildCount(tp) > 0 && tree.isExpanded(tp)) {
-                    tree.collapseRow(i);
-                    collapsesCount++;
-                }
+        // collapse all nodes
+        int collapsesCount = 0;
+        for (int i = tree.getRowCount() - 1; i >= 0; i--) {
+            TreePath tp = tree.getPathForRow(i);
+            if (tree.getChildCount(tp) > 0 && tree.isExpanded(tp)) {
+                tree.collapseRow(i);
+                collapsesCount++;
             }
+        }
 
-            assertEquals("Number of rows collapsed", 76, collapsesCount);
-            assertEquals("Number of rows in the tree after collapsing all of them",
-                    1, tree.getRowCount());
+        assertEquals("Number of rows collapsed", 76, collapsesCount);
+        assertEquals("Number of rows in the tree after collapsing all of them",
+                1, tree.getRowCount());
 
-            int collapsedTreeHeight = tree.getHeight();
-            assertTrue("Collpased tree height is not longer than initial, "
-                    + "current " + collapsedTreeHeight + " <= initial "
-                    + initialTreeHeight,
-                    collapsedTreeHeight <= initialTreeHeight);
+        int collapsedTreeHeight = tree.getHeight();
+        assertTrue("Collpased tree height is not longer than initial, "
+                + "current " + collapsedTreeHeight + " <= initial "
+                + initialTreeHeight,
+                collapsedTreeHeight <= initialTreeHeight);
 
-        });
     }
 
 }
--- a/jdk/test/sanity/client/SwingSet/src/WindowDemoTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/SwingSet/src/WindowDemoTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -21,6 +21,7 @@
  * questions.
  */
 
+import org.jtregext.GuiTestListener;
 import com.sun.swingset3.demos.window.WindowDemo;
 import static com.sun.swingset3.demos.window.WindowDemo.*;
 import static org.jemmy2ext.JemmyExt.*;
@@ -31,6 +32,7 @@
 import org.netbeans.jemmy.operators.JFrameOperator;
 import org.netbeans.jemmy.operators.JLabelOperator;
 import org.netbeans.jemmy.operators.WindowOperator;
+import org.testng.annotations.Listeners;
 
 /*
  * @test
@@ -40,37 +42,37 @@
  *          when the "Show JWindow..." button is clicked.
  *
  * @library /sanity/client/lib/jemmy/src
- * @library /sanity/client/lib/Jemmy2Ext/src
+ * @library /sanity/client/lib/Extensions/src
  * @library /sanity/client/lib/SwingSet3/src
  * @build org.jemmy2ext.JemmyExt
  * @build com.sun.swingset3.demos.window.WindowDemo
  * @run testng WindowDemoTest
  */
+@Listeners(GuiTestListener.class)
 public class WindowDemoTest {
 
     @Test
     public void test() throws Exception {
-        captureDebugInfoOnFail(() -> {
-            new ClassReference(WindowDemo.class.getCanonicalName()).startApplication();
+
+        new ClassReference(WindowDemo.class.getCanonicalName()).startApplication();
 
-            JFrameOperator frame = new JFrameOperator();
+        JFrameOperator frame = new JFrameOperator();
 
-            assertEquals("Only one JWindow is shown", 1, getJWindowCount());
+        assertEquals("Only one JWindow is shown", 1, getJWindowCount());
 
-            WindowOperator window = new WindowOperator(getJWindow());
+        WindowOperator window = new WindowOperator(getJWindow());
 
-            assertTrue("JFrame is showing", frame.isShowing());
-            assertFalse("JFrame is not iconified", isIconified(frame));
-            assertTrue("JWindow is showing", window.isShowing());
+        assertTrue("JFrame is showing", frame.isShowing());
+        assertFalse("JFrame is not iconified", isIconified(frame));
+        assertTrue("JWindow is showing", window.isShowing());
 
-            final String labelText = I_HAVE_NO_SYSTEM_BORDER;
-            JLabelOperator jLabelOperator = new JLabelOperator(window, labelText);
-            assertEquals("JWindow contains the label with corresponding text", labelText, jLabelOperator.getText());
+        final String labelText = I_HAVE_NO_SYSTEM_BORDER;
+        JLabelOperator jLabelOperator = new JLabelOperator(window, labelText);
+        assertEquals("JWindow contains the label with corresponding text", labelText, jLabelOperator.getText());
 
-            new JButtonOperator(frame, SHOW_J_WINDOW).push();
+        new JButtonOperator(frame, SHOW_J_WINDOW).push();
 
-            assertEquals("Only one JWindow is shown", 1, getJWindowCount());
-        });
+        assertEquals("Only one JWindow is shown", 1, getJWindowCount());
     }
 
 }
--- a/jdk/test/sanity/client/TEST.ROOT.template	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/TEST.ROOT.template	Thu Apr 28 23:08:16 2016 -0700
@@ -12,7 +12,7 @@
 # A "headful" test requires a graphical environment to meaningfully
 # run. Tests that are not headful are "headless." 
 
-keys=screenshots
+keys=2d dnd i18n intermittent randomness headful
 
 # Tests that must run in othervm mode
 othervm.dirs=sanity/client/SwingSet
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sanity/client/lib/Extensions/src/org/jemmy2ext/JemmyExt.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,613 @@
+/*
+ * Copyright (c) 2015, 2016, 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 org.jemmy2ext;
+
+import java.awt.Component;
+import java.awt.EventQueue;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.Window;
+import java.awt.image.BufferedImage;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Function;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.stream.IntStream;
+import javax.imageio.ImageIO;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import javax.swing.JWindow;
+import javax.swing.border.Border;
+import javax.swing.border.CompoundBorder;
+import javax.swing.border.TitledBorder;
+import org.netbeans.jemmy.ComponentChooser;
+import org.netbeans.jemmy.DefaultCharBindingMap;
+import org.netbeans.jemmy.QueueTool;
+import org.netbeans.jemmy.TimeoutExpiredException;
+import org.netbeans.jemmy.Waitable;
+import org.netbeans.jemmy.Waiter;
+import org.netbeans.jemmy.drivers.scrolling.JSpinnerDriver;
+import org.netbeans.jemmy.image.StrictImageComparator;
+import org.netbeans.jemmy.operators.ComponentOperator;
+import org.netbeans.jemmy.operators.ContainerOperator;
+import org.netbeans.jemmy.operators.FrameOperator;
+import org.netbeans.jemmy.operators.JButtonOperator;
+import org.netbeans.jemmy.operators.JFrameOperator;
+import org.netbeans.jemmy.operators.JLabelOperator;
+import org.netbeans.jemmy.operators.Operator;
+import org.netbeans.jemmy.util.Dumper;
+import org.netbeans.jemmy.util.PNGEncoder;
+import static org.testng.AssertJUnit.*;
+
+/**
+ * This class solves two tasks: 1. It adds functionality that is missing in
+ * Jemmy 2. It references all the Jemmy API that is needed by tests so that they
+ * can just @build JemmyExt class and do not worry about Jemmy
+ *
+ * @author akouznet
+ */
+public class JemmyExt {
+
+    /**
+     * Statically referencing all the classes that are needed by tests so that
+     * they're compiled by jtreg
+     */
+    static final Class<?>[] DEPENDENCIES = {
+        JSpinnerDriver.class,
+        DefaultCharBindingMap.class
+    };
+
+    public static void assertNotBlack(BufferedImage image) {
+        int w = image.getWidth();
+        int h = image.getHeight();
+        try {
+            assertFalse("All pixels are not black", IntStream.range(0, w).parallel().allMatch(x
+                    -> IntStream.range(0, h).allMatch(y -> (image.getRGB(x, y) & 0xffffff) == 0)
+            ));
+        } catch (Throwable t) {
+            save(image, "allPixelsAreBlack.png");
+            throw t;
+        }
+    }
+
+    public static void waitArmed(JButtonOperator button) {
+        button.waitState(new ComponentChooser() {
+
+            @Override
+            public boolean checkComponent(Component comp) {
+                return isArmed(button);
+            }
+
+            @Override
+            public String getDescription() {
+                return "Button is armed";
+            }
+        });
+    }
+
+    public static boolean isArmed(JButtonOperator button) {
+        return button.getQueueTool().invokeSmoothly(new QueueTool.QueueAction<Boolean>("getModel().isArmed()") {
+
+            @Override
+            public Boolean launch() throws Exception {
+                return ((JButton) button.getSource()).getModel().isArmed();
+            }
+        });
+    }
+
+    public static void waitPressed(JButtonOperator button) {
+        button.waitState(new ComponentChooser() {
+
+            @Override
+            public boolean checkComponent(Component comp) {
+                return isPressed(button);
+            }
+
+            @Override
+            public String getDescription() {
+                return "Button is pressed";
+            }
+        });
+    }
+
+    public static boolean isPressed(JButtonOperator button) {
+        return button.getQueueTool().invokeSmoothly(new QueueTool.QueueAction<Boolean>("getModel().isPressed()") {
+
+            @Override
+            public Boolean launch() throws Exception {
+                return ((JButton) button.getSource()).getModel().isPressed();
+            }
+        });
+    }
+
+    public static void assertEquals(String string, StrictImageComparator comparator, BufferedImage expected, BufferedImage actual) {
+        try {
+            assertTrue(string, comparator.compare(expected, actual));
+        } catch (Error err) {
+            save(expected, "expected.png");
+            save(actual, "actual.png");
+            throw err;
+        }
+    }
+
+    public static void assertNotEquals(String string, StrictImageComparator comparator, BufferedImage notExpected, BufferedImage actual) {
+        try {
+            assertFalse(string, comparator.compare(notExpected, actual));
+        } catch (Error err) {
+            save(notExpected, "notExpected.png");
+            save(actual, "actual.png");
+            throw err;
+        }
+    }
+
+    public static void save(BufferedImage image, String filename) {
+        String filepath = filename;
+        try {
+            filepath = new File(filename).getCanonicalPath();
+            System.out.println("Saving screenshot to " + filepath);
+            BufferedOutputStream file = new BufferedOutputStream(new FileOutputStream(filepath));
+            new PNGEncoder(file, PNGEncoder.COLOR_MODE).encode(image);
+        } catch (IOException ioe) {
+            throw new RuntimeException("Failed to save image to " + filepath, ioe);
+        }
+    }
+
+    public static void waitImageIsStill(Robot rob, ComponentOperator operator) {
+        operator.waitState(new ComponentChooser() {
+
+            private BufferedImage previousImage = null;
+            private int index = 0;
+            private final StrictImageComparator sComparator = new StrictImageComparator();
+
+            @Override
+            public boolean checkComponent(Component comp) {
+                BufferedImage currentImage = capture(rob, operator);
+                save(currentImage, "waitImageIsStill" + index + ".png");
+                index++;
+                boolean compareResult = previousImage == null ? false : sComparator.compare(currentImage, previousImage);
+                previousImage = currentImage;
+                return compareResult;
+            }
+
+            @Override
+            public String getDescription() {
+                return "Image of " + operator + " is still";
+            }
+        });
+    }
+
+    private static class ThrowableHolder {
+
+        volatile Throwable t;
+    }
+
+    public static void waitFor(String description, RunnableWithException r) throws Exception {
+        Waiter<Boolean, ThrowableHolder> waiter = new Waiter<>(new Waitable<Boolean, ThrowableHolder>() {
+
+            @Override
+            public Boolean actionProduced(ThrowableHolder obj) {
+                try {
+                    r.run();
+                    return true;
+                } catch (Throwable t) {
+                    obj.t = t;
+                    return null;
+                }
+            }
+
+            @Override
+            public String getDescription() {
+                return description;
+            }
+        });
+        ThrowableHolder th = new ThrowableHolder();
+        try {
+            waiter.waitAction(th);
+        } catch (TimeoutExpiredException tee) {
+            Throwable t = th.t;
+            if (t != null) {
+                t.addSuppressed(tee);
+                if (t instanceof Exception) {
+                    throw (Exception) t;
+                } else if (t instanceof Error) {
+                    throw (Error) t;
+                } else if (t instanceof RuntimeException) {
+                    throw (RuntimeException) t;
+                } else {
+                    throw new IllegalStateException("Unexpected exception type", t);
+                }
+            }
+        }
+    }
+
+    public static BufferedImage capture(Robot rob, ComponentOperator operator) {
+        Rectangle boundary = new Rectangle(operator.getLocationOnScreen(),
+                operator.getSize());
+        return rob.createScreenCapture(boundary);
+    }
+
+    /**
+     * Dispose all AWT/Swing windows causing event thread to stop
+     */
+    public static void disposeAllWindows() {
+        System.out.println("disposeAllWindows");
+        try {
+            EventQueue.invokeAndWait(() -> {
+                Window[] windows = Window.getWindows();
+                for (Window w : windows) {
+                    w.dispose();
+                }
+            });
+        } catch (InterruptedException | InvocationTargetException ex) {
+            Logger.getLogger(JemmyExt.class.getName()).log(Level.SEVERE, "Failed to dispose all windows", ex);
+        }
+    }
+
+    /**
+     * This is a helper class which allows to catch throwables thrown in other
+     * threads and throw them in the main test thread
+     */
+    public static class MultiThreadedTryCatch {
+
+        private final List<Throwable> throwables
+                = Collections.synchronizedList(new ArrayList<>());
+
+        /**
+         * Throws registered throwables. If the list of the registered
+         * throwables is not empty, it re-throws the first throwable in the list
+         * adding all others into its suppressed list. Can be used in any
+         * thread.
+         *
+         * @throws Exception
+         */
+        public void throwRegistered() throws Exception {
+            Throwable root = null;
+            synchronized (throwables) {
+                if (!throwables.isEmpty()) {
+                    root = throwables.remove(0);
+                    while (!throwables.isEmpty()) {
+                        root.addSuppressed(throwables.remove(0));
+                    }
+                }
+            }
+            if (root != null) {
+                if (root instanceof Error) {
+                    throw (Error) root;
+                } else if (root instanceof Exception) {
+                    throw (Exception) root;
+                } else {
+                    throw new AssertionError("Unexpected exception type: " + root.getClass() + " (" + root + ")");
+                }
+            }
+        }
+
+        /**
+         * Registers a throwable and adds it to the list of throwables. Can be
+         * used in any thread.
+         *
+         * @param t
+         */
+        public void register(Throwable t) {
+            t.printStackTrace();
+            throwables.add(t);
+        }
+
+        /**
+         * Registers a throwable and adds it as the first item of the list of
+         * catched throwables.
+         *
+         * @param t
+         */
+        public void registerRoot(Throwable t) {
+            t.printStackTrace();
+            throwables.add(0, t);
+        }
+    }
+
+    /**
+     * Trying to capture as much information as possible. Currently it includes
+     * full dump and a screenshot of the whole screen.
+     */
+    public static void captureAll() {
+        PNGEncoder.captureScreen("failure.png", PNGEncoder.COLOR_MODE);
+        try {
+            Dumper.dumpAll("dumpAll.xml");
+        } catch (FileNotFoundException ex) {
+            Logger.getLogger(JemmyExt.class.getName()).log(Level.SEVERE, null, ex);
+        }
+        captureWindows();
+    }
+
+    /**
+     * Captures each showing window image using Window.paint() method.
+     */
+    private static void captureWindows() {
+        try {
+            EventQueue.invokeAndWait(() -> {
+                Window[] windows = Window.getWindows();
+                int index = 0;
+                for (Window w : windows) {
+                    if (!w.isShowing()) {
+                        continue;
+                    }
+                    BufferedImage img = new BufferedImage(w.getWidth(), w.getHeight(), BufferedImage.TYPE_INT_ARGB);
+                    Graphics g = img.getGraphics();
+                    w.paint(g);
+                    g.dispose();
+
+                    try {
+                        ImageIO.write(img, "png", new File("window" + index++ + ".png"));
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    }
+                }
+            });
+        } catch (InterruptedException | InvocationTargetException ex) {
+            Logger.getLogger(JemmyExt.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+
+    public static interface RunnableWithException {
+
+        public void run() throws Exception;
+    }
+
+    public static void waitIsFocused(JFrameOperator jfo) {
+        jfo.waitState(new ComponentChooser() {
+
+            @Override
+            public boolean checkComponent(Component comp) {
+                return jfo.isFocused();
+            }
+
+            @Override
+            public String getDescription() {
+                return "JFrame is focused";
+            }
+        });
+    }
+
+    public static int getJWindowCount() {
+        return new QueueTool().invokeAndWait(new QueueTool.QueueAction<Integer>(null) {
+
+            @Override
+            public Integer launch() throws Exception {
+                Window[] windows = Window.getWindows();
+                int windowCount = 0;
+                for (Window w : windows) {
+                    if (w.getClass().equals(JWindow.class)) {
+                        windowCount++;
+                    }
+                }
+                return windowCount;
+            }
+        });
+    }
+
+    public static JWindow getJWindow() {
+        return getJWindow(0);
+    }
+
+    public static JWindow getJWindow(int index) {
+        return new QueueTool().invokeAndWait(new QueueTool.QueueAction<JWindow>(null) {
+
+            @Override
+            public JWindow launch() throws Exception {
+                Window[] windows = Window.getWindows();
+                int windowIndex = 0;
+                for (Window w : windows) {
+                    if (w.getClass().equals(JWindow.class)) {
+                        if (windowIndex == index) {
+                            return (JWindow) w;
+                        }
+                        windowIndex++;
+                    }
+                }
+                return null;
+            }
+        });
+    }
+
+    public static boolean isIconified(FrameOperator frameOperator) {
+        return frameOperator.getQueueTool().invokeAndWait(new QueueTool.QueueAction<Boolean>("Frame is iconified") {
+
+            @Override
+            public Boolean launch() throws Exception {
+                return (((Frame) frameOperator.getSource()).getState() & Frame.ICONIFIED) != 0;
+            }
+        });
+    }
+
+    public static final Operator.DefaultStringComparator EXACT_STRING_COMPARATOR
+            = new Operator.DefaultStringComparator(true, true);
+
+    /**
+     * Finds a label with the exact labelText and returns the operator for its
+     * parent container.
+     *
+     * @param container
+     * @param labelText
+     * @return
+     */
+    public static ContainerOperator<?> getLabeledContainerOperator(ContainerOperator<?> container, String labelText) {
+
+        container.setComparator(EXACT_STRING_COMPARATOR);
+
+        JLabelOperator jLabelOperator = new JLabelOperator(container, labelText);
+
+        assert labelText.equals(jLabelOperator.getText());
+
+        return new ContainerOperator<>(jLabelOperator.getParent());
+    }
+
+    /**
+     * Finds a JPanel with exact title text.
+     *
+     * @param container
+     * @param titleText
+     * @return
+     */
+    public static ContainerOperator<?> getBorderTitledJPanelOperator(ContainerOperator<?> container, String titleText) {
+        return new ContainerOperator<>(container, new JPanelByBorderTitleFinder(titleText, EXACT_STRING_COMPARATOR));
+    }
+
+    public static final QueueTool QUEUE_TOOL = new QueueTool();
+
+    /**
+     * Allows to find JPanel by the title text in its border.
+     */
+    public static class JPanelByBorderTitleFinder implements ComponentChooser {
+
+        String titleText;
+        Operator.StringComparator comparator;
+
+        /**
+         * @param titleText title text pattern
+         * @param comparator specifies string comparison algorithm.
+         */
+        public JPanelByBorderTitleFinder(String titleText, Operator.StringComparator comparator) {
+            this.titleText = titleText;
+            this.comparator = comparator;
+        }
+
+        /**
+         * @param titleText title text pattern
+         */
+        public JPanelByBorderTitleFinder(String titleText) {
+            this(titleText, Operator.getDefaultStringComparator());
+        }
+
+        @Override
+        public boolean checkComponent(Component comp) {
+            assert EventQueue.isDispatchThread();
+            if (comp instanceof JPanel) {
+                return checkBorder(((JPanel) comp).getBorder());
+            }
+            return false;
+        }
+
+        public boolean checkBorder(Border border) {
+            if (border instanceof TitledBorder) {
+                String title = ((TitledBorder) border).getTitle();
+                return comparator.equals(title, titleText);
+            } else if (border instanceof CompoundBorder) {
+                CompoundBorder compoundBorder = (CompoundBorder) border;
+                return checkBorder(compoundBorder.getInsideBorder()) || checkBorder(compoundBorder.getOutsideBorder());
+            } else {
+                return false;
+            }
+        }
+
+        @Override
+        public String getDescription() {
+            return ("JPanel with border title text \"" + titleText + "\" with comparator " + comparator);
+        }
+    }
+
+    public static class ByClassSimpleNameChooser implements ComponentChooser {
+
+        private final String className;
+
+        public ByClassSimpleNameChooser(String className) {
+            this.className = className;
+        }
+
+        @Override
+        public boolean checkComponent(Component comp) {
+            return comp.getClass().getSimpleName().equals(className);
+        }
+
+        @Override
+        public String getDescription() {
+            return "Component with the simple class name of " + className;
+        }
+
+    }
+
+    public static class ByClassChooser implements ComponentChooser {
+
+        private final Class<?> clazz;
+
+        public ByClassChooser(Class<?> clazz) {
+            this.clazz = clazz;
+        }
+
+        @Override
+        public boolean checkComponent(Component comp) {
+            return comp.getClass().equals(clazz);
+        }
+
+        @Override
+        public String getDescription() {
+            return "Component with the class of " + clazz;
+        }
+
+    }
+
+    public static class ByToolTipChooser implements ComponentChooser {
+
+        private final String tooltip;
+
+        public ByToolTipChooser(String tooltip) {
+            if (tooltip == null) {
+                throw new NullPointerException("Tooltip cannot be null");
+            }
+            this.tooltip = tooltip;
+        }
+
+        @Override
+        public boolean checkComponent(Component comp) {
+            return (comp instanceof JComponent)
+                    ? tooltip.equals(((JComponent) comp).getToolTipText())
+                    : false;
+        }
+
+        @Override
+        public String getDescription() {
+            return "JComponent with the tooltip '" + tooltip + "'";
+        }
+
+    }
+
+    @SuppressWarnings(value = "unchecked")
+    public static <R, O extends Operator, S extends Component> R getUIValue(O operator, Function<S, R> getter) {
+        return operator.getQueueTool().invokeSmoothly(new QueueTool.QueueAction<R>("getting UI value through the queue using " + getter) {
+
+            @Override
+            public R launch() throws Exception {
+                return getter.apply((S) operator.getSource());
+            }
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sanity/client/lib/Extensions/src/org/jtregext/GuiTestListener.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,72 @@
+package org.jtregext;
+
+/*
+ * Copyright (c) 2016, 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 org.jemmy2ext.JemmyExt;
+import static org.jemmy2ext.JemmyExt.captureAll;
+import org.testng.ITestContext;
+import org.testng.ITestListener;
+import org.testng.ITestResult;
+
+// TODO: Remove this once https://bugs.openjdk.java.net/browse/JDK-8151671 is fixed
+public class GuiTestListener implements ITestListener {
+
+    private void afterTest() {
+        JemmyExt.disposeAllWindows();
+    }
+
+    @Override
+    public void onTestStart(ITestResult result) {
+    }
+
+    @Override
+    public void onTestSuccess(ITestResult result) {
+        System.out.println("TEST PASSED");
+        afterTest();
+    }
+
+    @Override
+    public void onTestFailure(ITestResult result) {
+        captureAll();
+        afterTest();
+    }
+
+    @Override
+    public void onTestSkipped(ITestResult result) {
+    }
+
+    @Override
+    public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
+    }
+
+    @Override
+    public void onStart(ITestContext context) {
+    }
+
+    @Override
+    public void onFinish(ITestContext context) {
+    }
+
+}
--- a/jdk/test/sanity/client/lib/Jemmy2Ext/src/org/jemmy2ext/JemmyExt.java	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,614 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, 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 org.jemmy2ext;
-
-import java.awt.Component;
-import java.awt.EventQueue;
-import java.awt.Frame;
-import java.awt.Graphics;
-import java.awt.Rectangle;
-import java.awt.Robot;
-import java.awt.Window;
-import java.awt.image.BufferedImage;
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.function.Function;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import java.util.stream.IntStream;
-import javax.imageio.ImageIO;
-import javax.swing.JButton;
-import javax.swing.JComponent;
-import javax.swing.JPanel;
-import javax.swing.JWindow;
-import javax.swing.border.Border;
-import javax.swing.border.CompoundBorder;
-import javax.swing.border.TitledBorder;
-import org.netbeans.jemmy.ComponentChooser;
-import org.netbeans.jemmy.DefaultCharBindingMap;
-import org.netbeans.jemmy.QueueTool;
-import org.netbeans.jemmy.TimeoutExpiredException;
-import org.netbeans.jemmy.Waitable;
-import org.netbeans.jemmy.Waiter;
-import org.netbeans.jemmy.drivers.scrolling.JSpinnerDriver;
-import org.netbeans.jemmy.image.StrictImageComparator;
-import org.netbeans.jemmy.operators.ComponentOperator;
-import org.netbeans.jemmy.operators.ContainerOperator;
-import org.netbeans.jemmy.operators.FrameOperator;
-import org.netbeans.jemmy.operators.JButtonOperator;
-import org.netbeans.jemmy.operators.JFrameOperator;
-import org.netbeans.jemmy.operators.JLabelOperator;
-import org.netbeans.jemmy.operators.Operator;
-import org.netbeans.jemmy.util.Dumper;
-import org.netbeans.jemmy.util.PNGEncoder;
-import static org.testng.AssertJUnit.*;
-
-/**
- * This class solves two tasks: 1. It adds functionality that is missing in
- * Jemmy 2. It references all the Jemmy API that is needed by tests so that they
- * can just @build JemmyExt class and do not worry about Jemmy
- *
- * @author akouznet
- */
-public class JemmyExt {
-
-    /**
-     * Statically referencing all the classes that are needed by tests so that
-     * they're compiled by jtreg
-     */
-    static final Class<?>[] DEPENDENCIES = {
-        JSpinnerDriver.class,
-        DefaultCharBindingMap.class
-    };
-
-    public static void assertNotBlack(BufferedImage image) {
-        int w = image.getWidth();
-        int h = image.getHeight();
-        try {
-            assertFalse("All pixels are not black", IntStream.range(0, w).parallel().allMatch(x
-                    -> IntStream.range(0, h).allMatch(y -> (image.getRGB(x, y) & 0xffffff) == 0)
-            ));
-        } catch (Throwable t) {
-            save(image, "allPixelsAreBlack.png");
-            throw t;
-        }
-    }
-
-    public static void waitArmed(JButtonOperator button) {
-        button.waitState(new ComponentChooser() {
-
-            @Override
-            public boolean checkComponent(Component comp) {
-                return isArmed(button);
-            }
-
-            @Override
-            public String getDescription() {
-                return "Button is armed";
-            }
-        });
-    }
-
-    public static boolean isArmed(JButtonOperator button) {
-        return button.getQueueTool().invokeSmoothly(new QueueTool.QueueAction<Boolean>("getModel().isArmed()") {
-
-            @Override
-            public Boolean launch() throws Exception {
-                return ((JButton) button.getSource()).getModel().isArmed();
-            }
-        });
-    }
-
-    public static void waitPressed(JButtonOperator button) {
-        button.waitState(new ComponentChooser() {
-
-            @Override
-            public boolean checkComponent(Component comp) {
-                return isPressed(button);
-            }
-
-            @Override
-            public String getDescription() {
-                return "Button is pressed";
-            }
-        });
-    }
-
-    public static boolean isPressed(JButtonOperator button) {
-        return button.getQueueTool().invokeSmoothly(new QueueTool.QueueAction<Boolean>("getModel().isPressed()") {
-
-            @Override
-            public Boolean launch() throws Exception {
-                return ((JButton) button.getSource()).getModel().isPressed();
-            }
-        });
-    }
-
-    public static void assertEquals(String string, StrictImageComparator comparator, BufferedImage expected, BufferedImage actual) {
-        try {
-            assertTrue(string, comparator.compare(expected, actual));
-        } catch (Error err) {
-            save(expected, "expected.png");
-            save(actual, "actual.png");
-            throw err;
-        }
-    }
-
-    public static void assertNotEquals(String string, StrictImageComparator comparator, BufferedImage notExpected, BufferedImage actual) {
-        try {
-            assertFalse(string, comparator.compare(notExpected, actual));
-        } catch (Error err) {
-            save(notExpected, "notExpected.png");
-            save(actual, "actual.png");
-            throw err;
-        }
-    }
-
-    public static void save(BufferedImage image, String filename) {
-        String filepath = filename;
-        try {
-            filepath = new File(filename).getCanonicalPath();
-            System.out.println("Saving screenshot to " + filepath);
-            BufferedOutputStream file = new BufferedOutputStream(new FileOutputStream(filepath));
-            new PNGEncoder(file, PNGEncoder.COLOR_MODE).encode(image);
-        } catch (IOException ioe) {
-            throw new RuntimeException("Failed to save image to " + filepath, ioe);
-        }
-    }
-
-    public static void waitImageIsStill(Robot rob, ComponentOperator operator) {
-        operator.waitState(new ComponentChooser() {
-
-            private BufferedImage previousImage = null;
-            private int index = 0;
-            private final StrictImageComparator sComparator = new StrictImageComparator();
-
-            @Override
-            public boolean checkComponent(Component comp) {
-                BufferedImage currentImage = capture(rob, operator);
-                save(currentImage, "waitImageIsStill" + index + ".png");
-                index++;
-                boolean compareResult = previousImage == null ? false : sComparator.compare(currentImage, previousImage);
-                previousImage = currentImage;
-                return compareResult;
-            }
-
-            @Override
-            public String getDescription() {
-                return "Image of " + operator + " is still";
-            }
-        });
-    }
-
-    private static class ThrowableHolder {
-
-        volatile Throwable t;
-    }
-
-    public static void waitFor(String description, RunnableWithException r) throws Exception {
-        Waiter<Boolean, ThrowableHolder> waiter = new Waiter<>(new Waitable<Boolean, ThrowableHolder>() {
-
-            @Override
-            public Boolean actionProduced(ThrowableHolder obj) {
-                try {
-                    r.run();
-                    return true;
-                } catch (Throwable t) {
-                    obj.t = t;
-                    return null;
-                }
-            }
-
-            @Override
-            public String getDescription() {
-                return description;
-            }
-        });
-        ThrowableHolder th = new ThrowableHolder();
-        try {
-            waiter.waitAction(th);
-        } catch (TimeoutExpiredException tee) {
-            Throwable t = th.t;
-            if (t != null) {
-                t.addSuppressed(tee);
-                if (t instanceof Exception) {
-                    throw (Exception) t;
-                } else if (t instanceof Error) {
-                    throw (Error) t;
-                } else if (t instanceof RuntimeException) {
-                    throw (RuntimeException) t;
-                } else {
-                    throw new IllegalStateException("Unexpected exception type", t);
-                }
-            }
-        }
-    }
-
-    public static BufferedImage capture(Robot rob, ComponentOperator operator) {
-        Rectangle boundary = new Rectangle(operator.getLocationOnScreen(),
-                operator.getSize());
-        return rob.createScreenCapture(boundary);
-    }
-
-    /**
-     * Wraps the test code so that in case of any failure as much information as
-     * possible is captured
-     *
-     * @param r test code Runnable
-     * @throws Exception whatever exception the test may throw
-     */
-    public static void captureDebugInfoOnFail(RunnableWithException r) throws Exception {
-        // TODO: Remove this once https://bugs.openjdk.java.net/browse/JDK-8151671 is fixed
-        try {
-            r.run();
-            System.out.println("TEST PASSED");
-        } catch (Throwable t) {
-            captureAll();
-            throw t;
-        }
-    }
-
-    /**
-     * This is a helper class which allows to catch throwables thrown in other
-     * threads and throw them in the main test thread
-     */
-    public static class MultiThreadedTryCatch {
-
-        private final List<Throwable> throwables
-                = Collections.synchronizedList(new ArrayList<>());
-
-        /**
-         * Throws registered throwables. If the list of the registered
-         * throwables is not empty, it re-throws the first throwable in the list
-         * adding all others into its suppressed list. Can be used in any
-         * thread.
-         *
-         * @throws Exception
-         */
-        public void throwRegistered() throws Exception {
-            Throwable root = null;
-            synchronized (throwables) {
-                if (!throwables.isEmpty()) {
-                    root = throwables.remove(0);
-                    while (!throwables.isEmpty()) {
-                        root.addSuppressed(throwables.remove(0));
-                    }
-                }
-            }
-            if (root != null) {
-                if (root instanceof Error) {
-                    throw (Error) root;
-                } else if (root instanceof Exception) {
-                    throw (Exception) root;
-                } else {
-                    throw new AssertionError("Unexpected exception type: " + root.getClass() + " (" + root + ")");
-                }
-            }
-        }
-
-        /**
-         * Registers a throwable and adds it to the list of throwables. Can be
-         * used in any thread.
-         *
-         * @param t
-         */
-        public void register(Throwable t) {
-            t.printStackTrace();
-            throwables.add(t);
-        }
-
-        /**
-         * Registers a throwable and adds it as the first item of the list of
-         * catched throwables.
-         *
-         * @param t
-         */
-        public void registerRoot(Throwable t) {
-            t.printStackTrace();
-            throwables.add(0, t);
-        }
-    }
-
-    /**
-     * Trying to capture as much information as possible. Currently it includes
-     * full dump and a screenshot of the whole screen.
-     */
-    public static void captureAll() {
-        PNGEncoder.captureScreen("failure.png", PNGEncoder.COLOR_MODE);
-        try {
-            Dumper.dumpAll("dumpAll.xml");
-        } catch (FileNotFoundException ex) {
-            Logger.getLogger(JemmyExt.class.getName()).log(Level.SEVERE, null, ex);
-        }
-        captureWindows();
-    }
-
-    /**
-     * Captures each showing window image using Window.paint() method.
-     */
-    private static void captureWindows() {
-        try {
-            EventQueue.invokeAndWait(() -> {
-                Window[] windows = Window.getWindows();
-                int index = 0;
-                for (Window w : windows) {
-                    if (!w.isShowing()) {
-                        continue;
-                    }
-                    BufferedImage img = new BufferedImage(w.getWidth(), w.getHeight(), BufferedImage.TYPE_INT_ARGB);
-                    Graphics g = img.getGraphics();
-                    w.paint(g);
-                    g.dispose();
-
-                    try {
-                        ImageIO.write(img, "png", new File("window" + index++ + ".png"));
-                    } catch (IOException e) {
-                        e.printStackTrace();
-                    }
-                }
-            });
-        } catch (InterruptedException | InvocationTargetException ex) {
-            Logger.getLogger(JemmyExt.class.getName()).log(Level.SEVERE, null, ex);
-        }
-    }
-
-    public static interface RunnableWithException {
-
-        public void run() throws Exception;
-    }
-
-    public static void waitIsFocused(JFrameOperator jfo) {
-        jfo.waitState(new ComponentChooser() {
-
-            @Override
-            public boolean checkComponent(Component comp) {
-                return jfo.isFocused();
-            }
-
-            @Override
-            public String getDescription() {
-                return "JFrame is focused";
-            }
-        });
-    }
-
-    public static int getJWindowCount() {
-        return new QueueTool().invokeAndWait(new QueueTool.QueueAction<Integer>(null) {
-
-            @Override
-            public Integer launch() throws Exception {
-                Window[] windows = Window.getWindows();
-                int windowCount = 0;
-                for (Window w : windows) {
-                    if (w.getClass().equals(JWindow.class)) {
-                        windowCount++;
-                    }
-                }
-                return windowCount;
-            }
-        });
-    }
-
-    public static JWindow getJWindow() {
-        return getJWindow(0);
-    }
-
-    public static JWindow getJWindow(int index) {
-        return new QueueTool().invokeAndWait(new QueueTool.QueueAction<JWindow>(null) {
-
-            @Override
-            public JWindow launch() throws Exception {
-                Window[] windows = Window.getWindows();
-                int windowIndex = 0;
-                for (Window w : windows) {
-                    if (w.getClass().equals(JWindow.class)) {
-                        if (windowIndex == index) {
-                            return (JWindow) w;
-                        }
-                        windowIndex++;
-                    }
-                }
-                return null;
-            }
-        });
-    }
-
-    public static boolean isIconified(FrameOperator frameOperator) {
-        return frameOperator.getQueueTool().invokeAndWait(new QueueTool.QueueAction<Boolean>("Frame is iconified") {
-
-            @Override
-            public Boolean launch() throws Exception {
-                return (((Frame) frameOperator.getSource()).getState() & Frame.ICONIFIED) != 0;
-            }
-        });
-    }
-
-    public static final Operator.DefaultStringComparator EXACT_STRING_COMPARATOR
-            = new Operator.DefaultStringComparator(true, true);
-
-    /**
-     * Finds a label with the exact labelText and returns the operator for its
-     * parent container.
-     *
-     * @param container
-     * @param labelText
-     * @return
-     */
-    public static ContainerOperator<?> getLabeledContainerOperator(ContainerOperator<?> container, String labelText) {
-
-        container.setComparator(EXACT_STRING_COMPARATOR);
-
-        JLabelOperator jLabelOperator = new JLabelOperator(container, labelText);
-
-        assert labelText.equals(jLabelOperator.getText());
-
-        return new ContainerOperator<>(jLabelOperator.getParent());
-    }
-
-    /**
-     * Finds a JPanel with exact title text.
-     *
-     * @param container
-     * @param titleText
-     * @return
-     */
-    public static ContainerOperator<?> getBorderTitledJPanelOperator(ContainerOperator<?> container, String titleText) {
-        return new ContainerOperator<>(container, new JPanelByBorderTitleFinder(titleText, EXACT_STRING_COMPARATOR));
-    }
-
-    public static final QueueTool QUEUE_TOOL = new QueueTool();
-
-    /**
-     * Allows to find JPanel by the title text in its border.
-     */
-    public static class JPanelByBorderTitleFinder implements ComponentChooser {
-
-        String titleText;
-        Operator.StringComparator comparator;
-
-        /**
-         * @param titleText title text pattern
-         * @param comparator specifies string comparison algorithm.
-         */
-        public JPanelByBorderTitleFinder(String titleText, Operator.StringComparator comparator) {
-            this.titleText = titleText;
-            this.comparator = comparator;
-        }
-
-        /**
-         * @param titleText title text pattern
-         */
-        public JPanelByBorderTitleFinder(String titleText) {
-            this(titleText, Operator.getDefaultStringComparator());
-        }
-
-        @Override
-        public boolean checkComponent(Component comp) {
-            assert EventQueue.isDispatchThread();
-            if (comp instanceof JPanel) {
-                return checkBorder(((JPanel) comp).getBorder());
-            }
-            return false;
-        }
-
-        public boolean checkBorder(Border border) {
-            if (border instanceof TitledBorder) {
-                String title = ((TitledBorder) border).getTitle();
-                return comparator.equals(title, titleText);
-            } else if (border instanceof CompoundBorder) {
-                CompoundBorder compoundBorder = (CompoundBorder) border;
-                return checkBorder(compoundBorder.getInsideBorder()) || checkBorder(compoundBorder.getOutsideBorder());
-            } else {
-                return false;
-            }
-        }
-
-        @Override
-        public String getDescription() {
-            return ("JPanel with border title text \"" + titleText + "\" with comparator " + comparator);
-        }
-    }
-
-    public static class ByClassSimpleNameChooser implements ComponentChooser {
-
-        private final String className;
-
-        public ByClassSimpleNameChooser(String className) {
-            this.className = className;
-        }
-
-        @Override
-        public boolean checkComponent(Component comp) {
-            return comp.getClass().getSimpleName().equals(className);
-        }
-
-        @Override
-        public String getDescription() {
-            return "Component with the simple class name of " + className;
-        }
-
-    }
-
-    public static class ByClassChooser implements ComponentChooser {
-
-        private final Class<?> clazz;
-
-        public ByClassChooser(Class<?> clazz) {
-            this.clazz = clazz;
-        }
-
-        @Override
-        public boolean checkComponent(Component comp) {
-            return comp.getClass().equals(clazz);
-        }
-
-        @Override
-        public String getDescription() {
-            return "Component with the class of " + clazz;
-        }
-
-    }
-
-    public static class ByToolTipChooser implements ComponentChooser {
-
-        private final String tooltip;
-
-        public ByToolTipChooser(String tooltip) {
-            if (tooltip == null) {
-                throw new NullPointerException("Tooltip cannot be null");
-            }
-            this.tooltip = tooltip;
-        }
-
-        @Override
-        public boolean checkComponent(Component comp) {
-            return (comp instanceof JComponent)
-                    ? tooltip.equals(((JComponent) comp).getToolTipText())
-                    : false;
-        }
-
-        @Override
-        public String getDescription() {
-            return "JComponent with the tooltip '" + tooltip + "'";
-        }
-
-    }
-
-    @SuppressWarnings(value = "unchecked")
-    public static <R, O extends Operator, S extends Component> R getUIValue(O operator, Function<S, R> getter) {
-        return operator.getQueueTool().invokeSmoothly(new QueueTool.QueueAction<R>("getting UI value through the queue using " + getter) {
-
-            @Override
-            public R launch() throws Exception {
-                return getter.apply((S) operator.getSource());
-            }
-        });
-    }
-}
--- a/jdk/test/sanity/client/lib/SwingSet3/README	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/lib/SwingSet3/README	Thu Apr 28 23:08:16 2016 -0700
@@ -1,4 +1,4 @@
 This content of this src folder was originally taken from SwingSet3 demo project: https://java.net/projects/swingset3/.
 Then it was modified to increase testability and remove extra content and extra dependencies.
 
-Do NOT modify files in it.
\ No newline at end of file
+This is NOT the official location of the SwingSet3 demo.
\ No newline at end of file
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/ButtonDemo.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/button/ButtonDemo.java	Thu Apr 28 23:08:16 2016 -0700
@@ -36,6 +36,7 @@
 
 import com.sun.swingset3.DemoProperties;
 import com.sun.swingset3.demos.JHyperlink;
+import java.lang.reflect.InvocationTargetException;
 
 /**
  *
@@ -210,12 +211,11 @@
         return panel;
     }
 
-    public static void main(String args[]) {
+    public static void main(String args[]) throws InterruptedException, InvocationTargetException {
         final ButtonDemo buttonDemo = new ButtonDemo();
 
-        javax.swing.SwingUtilities.invokeLater(() -> {
+        javax.swing.SwingUtilities.invokeAndWait(() -> {
             JFrame frame = new JFrame(DEMO_TITLE);
-            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             frame.add(buttonDemo);
             frame.pack();
             frame.setVisible(true);
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/ComboBoxDemo.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/combobox/ComboBoxDemo.java	Thu Apr 28 23:08:16 2016 -0700
@@ -120,7 +120,6 @@
     public static void main(String[] args) {
         JFrame frame = new JFrame(DEMO_TITLE);
 
-        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.getContentPane().add(new ComboBoxDemo());
         frame.setPreferredSize(new Dimension(800, 600));
         frame.pack();
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/ListDemo.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/list/ListDemo.java	Thu Apr 28 23:08:16 2016 -0700
@@ -90,7 +90,6 @@
     public static void main(String[] args) {
         JFrame frame = new JFrame(DEMO_TITLE);
 
-        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.getContentPane().add(new ListDemo());
         frame.setPreferredSize(new Dimension(800, 600));
         frame.pack();
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/optionpane/OptionPaneDemo.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/optionpane/OptionPaneDemo.java	Thu Apr 28 23:08:16 2016 -0700
@@ -93,7 +93,6 @@
     public static void main(String[] args) {
         JFrame frame = new JFrame(DEMO_TITLE);
 
-        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.getContentPane().add(new OptionPaneDemo());
         frame.setPreferredSize(new Dimension(800, 600));
         frame.pack();
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/progressbar/ProgressBarDemo.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/progressbar/ProgressBarDemo.java	Thu Apr 28 23:08:16 2016 -0700
@@ -64,7 +64,6 @@
     public static void main(String[] args) {
         JFrame frame = new JFrame(DEMO_TITLE);
 
-        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.getContentPane().add(new ProgressBarDemo());
         frame.setPreferredSize(new Dimension(800, 600));
         frame.pack();
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/ScrollPaneDemo.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/scrollpane/ScrollPaneDemo.java	Thu Apr 28 23:08:16 2016 -0700
@@ -64,7 +64,6 @@
     public static void main(String[] args) {
         JFrame frame = new JFrame(DEMO_TITLE);
 
-        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.getContentPane().add(new ScrollPaneDemo());
         frame.setPreferredSize(new Dimension(800, 600));
         frame.pack();
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/SpinnerDemo.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/spinner/SpinnerDemo.java	Thu Apr 28 23:08:16 2016 -0700
@@ -58,7 +58,6 @@
 
     public static void main(String[] args) {
         JFrame frame = new JFrame(DEMO_TITLE);
-        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.getContentPane().add(new SpinnerDemo());
         frame.setPreferredSize(new Dimension(800, 600));
         frame.pack();
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/splitpane/SplitPaneDemo.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/splitpane/SplitPaneDemo.java	Thu Apr 28 23:08:16 2016 -0700
@@ -86,7 +86,6 @@
     public static void main(String[] args) {
         JFrame frame = new JFrame(DEMO_TITLE);
 
-        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.getContentPane().add(new SplitPaneDemo());
         frame.setPreferredSize(new Dimension(800, 600));
         frame.pack();
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/TabbedPaneDemo.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tabbedpane/TabbedPaneDemo.java	Thu Apr 28 23:08:16 2016 -0700
@@ -91,7 +91,6 @@
     public static void main(String[] args) {
         JFrame frame = new JFrame(DEMO_TITLE);
 
-        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.getContentPane().add(new TabbedPaneDemo());
         frame.setPreferredSize(new Dimension(800, 600));
         frame.pack();
@@ -205,7 +204,9 @@
         }
 
         public void go() {
-            animator = new javax.swing.Timer(22 + 22 + 22, this);
+            if (animator == null) {
+                animator = new javax.swing.Timer(22 + 22 + 22, this);
+            }
             animator.start();
         }
 
@@ -247,7 +248,7 @@
 
         @Override
         public void actionPerformed(ActionEvent e) {
-            if (isVisible()) {
+            if (isShowing()) {
                 repaint();
             } else {
                 animator.stop();
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/textfield/TextFieldDemo.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/textfield/TextFieldDemo.java	Thu Apr 28 23:08:16 2016 -0700
@@ -115,7 +115,6 @@
     public static void main(String[] args) {
         JFrame frame = new JFrame(DEMO_TITLE);
 
-        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.getContentPane().add(new TextFieldDemo());
         frame.setPreferredSize(new Dimension(800, 600));
         frame.pack();
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/ToggleButtonDemo.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/togglebutton/ToggleButtonDemo.java	Thu Apr 28 23:08:16 2016 -0700
@@ -151,7 +151,6 @@
     public static void main(String[] args) {
         JFrame frame = new JFrame(ToggleButtonDemo.class.getAnnotation(DemoProperties.class).value());
 
-        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.getContentPane().add(new ToggleButtonDemo());
         frame.setPreferredSize(new Dimension(800, 600));
         frame.pack();
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tree/TreeDemo.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/tree/TreeDemo.java	Thu Apr 28 23:08:16 2016 -0700
@@ -65,7 +65,6 @@
     public static void main(String[] args) {
         JFrame frame = new JFrame(DEMO_TITLE);
 
-        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.getContentPane().add(new TreeDemo());
         frame.setPreferredSize(new Dimension(800, 600));
         frame.pack();
--- a/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/window/WindowDemo.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/window/WindowDemo.java	Thu Apr 28 23:08:16 2016 -0700
@@ -31,6 +31,7 @@
 
 import com.sun.swingset3.DemoProperties;
 import com.sun.swingset3.demos.DemoUtilities;
+import java.lang.reflect.InvocationTargetException;
 
 /**
  * @author aim
@@ -145,12 +146,11 @@
         }
     }
 
-    public static void main(String args[]) {
-        EventQueue.invokeLater(() -> {
+    public static void main(String args[]) throws InterruptedException, InvocationTargetException {
+        EventQueue.invokeAndWait(() -> {
             JFrame frame = new JFrame();
             WindowDemo demo = new WindowDemo();
             frame.add(demo);
-            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             frame.pack();
             frame.setVisible(true);
             demo.start();
--- a/jdk/test/sun/java2d/OpenGL/GradientPaints.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sun/java2d/OpenGL/GradientPaints.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, 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
@@ -23,11 +23,11 @@
 
 /*
  * @test
- * @bug 6521533 6525997
+ * @bug 6521533 6525997 7102282
  * @summary Verifies that the OGL-accelerated codepaths for GradientPaint,
  * LinearGradientPaint, and RadialGradientPaint produce results that are
  * sufficiently close to those produced by the software codepaths.
- * @run main/othervm -Dsun.java2d.opengl=True GradientPaints
+ * @run main/othervm -Dsun.java2d.uiScale=1 -Dsun.java2d.opengl=True GradientPaints
  * @author campbelc
  */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/ImpactOnSNI.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,390 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
+/*
+ * @test
+ * @bug 8144566
+ * @summary Custom HostnameVerifier disables SNI extension
+ * @run main/othervm ImpactOnSNI
+ */
+
+import java.io.*;
+import java.net.*;
+import javax.net.ssl.*;
+
+public class ImpactOnSNI {
+
+    /*
+     * =============================================================
+     * Set the various variables needed for the tests, then
+     * specify what tests to run on each side.
+     */
+
+    /*
+     * Should we run the client or server in a separate thread?
+     * Both sides can throw exceptions, but do you have a preference
+     * as to which side should be the main thread.
+     */
+    private static final boolean separateServerThread = true;
+
+    /*
+     * Where do we find the keystores?
+     */
+    private static final String pathToStores =
+                                        "../../../../../../javax/net/ssl/etc";
+    private static final String keyStoreFile = "keystore";
+    private static final String trustStoreFile = "truststore";
+    private static final String passwd = "passphrase";
+
+    /*
+     * Is the server ready to serve?
+     */
+    private static volatile boolean serverReady = false;
+
+    /*
+     * Is the connection ready to close?
+     */
+    private static volatile boolean closeReady = false;
+
+    /*
+     * Turn on SSL debugging?
+     */
+    private static final boolean debug = false;
+
+    /*
+     * Message posted
+     */
+    private static final String postMsg = "HTTP post on a https server";
+
+    /*
+     * the fully qualified domain name of localhost
+     */
+    private static String hostname = null;
+
+    /*
+     * If the client or server is doing some kind of object creation
+     * that the other side depends on, and that thread prematurely
+     * exits, you may experience a hang.  The test harness will
+     * terminate all hung threads after its timeout has expired,
+     * currently 3 minutes by default, but you might try to be
+     * smart about it....
+     */
+
+    /*
+     * Define the server side of the test.
+     *
+     * If the server prematurely exits, serverReady will be set to true
+     * to avoid infinite hangs.
+     */
+    private void doServerSide() throws Exception {
+        SSLServerSocketFactory sslssf =
+            (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
+        try (SSLServerSocket sslServerSocket =
+                (SSLServerSocket)sslssf.createServerSocket(serverPort)) {
+
+            serverPort = sslServerSocket.getLocalPort();
+
+            /*
+             * Signal Client, we're ready for his connect.
+             */
+            serverReady = true;
+
+            /*
+             * Accept connections
+             */
+            try (SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept()) {
+                InputStream sslIS = sslSocket.getInputStream();
+                OutputStream sslOS = sslSocket.getOutputStream();
+                BufferedReader br =
+                        new BufferedReader(new InputStreamReader(sslIS));
+                PrintStream ps = new PrintStream(sslOS);
+
+                // process HTTP POST request from client
+                System.out.println("status line: " + br.readLine());
+                String msg = null;
+                while ((msg = br.readLine()) != null && msg.length() > 0);
+
+                msg = br.readLine();
+                if (msg.equals(postMsg)) {
+                    ps.println("HTTP/1.1 200 OK\n\n");
+                } else {
+                    ps.println("HTTP/1.1 500 Not OK\n\n");
+                }
+                ps.flush();
+
+                ExtendedSSLSession session =
+                        (ExtendedSSLSession)sslSocket.getSession();
+                if (session.getRequestedServerNames().isEmpty()) {
+                    throw new Exception("No expected Server Name Indication");
+                }
+
+                // close the socket
+                while (!closeReady) {
+                    Thread.sleep(50);
+                }
+            }
+        }
+    }
+
+    /*
+     * Define the client side of the test.
+     *
+     * If the server prematurely exits, serverReady will be set to true
+     * to avoid infinite hangs.
+     */
+    private void doClientSide() throws Exception {
+        /*
+         * Wait for server to get started.
+         */
+        while (!serverReady) {
+            Thread.sleep(50);
+        }
+
+        // Send HTTP POST request to server
+        URL url = new URL("https://" + hostname + ":" + serverPort);
+
+        HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());
+        HttpsURLConnection http = (HttpsURLConnection)url.openConnection();
+        http.setDoOutput(true);
+
+        http.setRequestMethod("POST");
+        PrintStream ps = new PrintStream(http.getOutputStream());
+        try {
+            ps.println(postMsg);
+            ps.flush();
+            if (http.getResponseCode() != 200) {
+                throw new RuntimeException("test Failed");
+            }
+        } finally {
+            ps.close();
+            http.disconnect();
+            closeReady = true;
+        }
+    }
+
+    private static class NameVerifier implements HostnameVerifier {
+        public boolean verify(String hostname, SSLSession session) {
+            return true;
+        }
+    }
+
+    /*
+     * =============================================================
+     * The remainder is just support stuff
+     */
+
+    // use any free port by default
+    private volatile int serverPort = 0;
+
+    private volatile Exception serverException = null;
+    private volatile Exception clientException = null;
+
+    public static void main(String[] args) throws Exception {
+        String keyFilename =
+            System.getProperty("test.src", "./") + "/" + pathToStores +
+                "/" + keyStoreFile;
+        String trustFilename =
+            System.getProperty("test.src", "./") + "/" + pathToStores +
+                "/" + trustStoreFile;
+
+        System.setProperty("javax.net.ssl.keyStore", keyFilename);
+        System.setProperty("javax.net.ssl.keyStorePassword", passwd);
+        System.setProperty("javax.net.ssl.trustStore", trustFilename);
+        System.setProperty("javax.net.ssl.trustStorePassword", passwd);
+
+        if (debug) {
+            System.setProperty("javax.net.debug", "all");
+        }
+
+        try {
+            hostname = InetAddress.getLocalHost().getCanonicalHostName();
+        } catch (UnknownHostException uhe) {
+            System.out.println(
+                "Ignore the test as the local hostname cannot be determined");
+
+            return;
+        }
+
+        System.out.println(
+                "The fully qualified domain name of the local host is " +
+                hostname);
+        // Ignore the test if the hostname does not sound like a domain name.
+        if ((hostname == null) || hostname.isEmpty() ||
+                hostname.startsWith("localhost") ||
+                Character.isDigit(hostname.charAt(hostname.length() - 1))) {
+
+            System.out.println("Ignore the test as the local hostname " +
+                    "cannot be determined as fully qualified domain name");
+
+            return;
+        }
+
+        /*
+         * Start the tests.
+         */
+        new ImpactOnSNI();
+    }
+
+    private Thread clientThread = null;
+    private Thread serverThread = null;
+
+    /*
+     * Primary constructor, used to drive remainder of the test.
+     *
+     * Fork off the other side, then do your work.
+     */
+    ImpactOnSNI() throws Exception {
+        Exception startException = null;
+        try {
+            if (separateServerThread) {
+                startServer(true);
+                startClient(false);
+            } else {
+                startClient(true);
+                startServer(false);
+            }
+        } catch (Exception e) {
+            startException = e;
+        }
+
+        /*
+         * Wait for other side to close down.
+         */
+        if (separateServerThread) {
+            if (serverThread != null) {
+                serverThread.join();
+            }
+        } else {
+            if (clientThread != null) {
+                clientThread.join();
+            }
+        }
+
+        /*
+         * When we get here, the test is pretty much over.
+         * Which side threw the error?
+         */
+        Exception local;
+        Exception remote;
+
+        if (separateServerThread) {
+            remote = serverException;
+            local = clientException;
+        } else {
+            remote = clientException;
+            local = serverException;
+        }
+
+        Exception exception = null;
+
+        /*
+         * Check various exception conditions.
+         */
+        if ((local != null) && (remote != null)) {
+            // If both failed, return the curthread's exception.
+            local.initCause(remote);
+            exception = local;
+        } else if (local != null) {
+            exception = local;
+        } else if (remote != null) {
+            exception = remote;
+        } else if (startException != null) {
+            exception = startException;
+        }
+
+        /*
+         * If there was an exception *AND* a startException,
+         * output it.
+         */
+        if (exception != null) {
+            if (exception != startException && startException != null) {
+                exception.addSuppressed(startException);
+            }
+            throw exception;
+        }
+
+        // Fall-through: no exception to throw!
+    }
+
+    private void startServer(boolean newThread) throws Exception {
+        if (newThread) {
+            serverThread = new Thread() {
+                @Override
+                public void run() {
+                    try {
+                        doServerSide();
+                    } catch (Exception e) {
+                        /*
+                         * Our server thread just died.
+                         *
+                         * Release the client, if not active already...
+                         */
+                        System.err.println("Server died...");
+                        serverReady = true;
+                        serverException = e;
+                    }
+                }
+            };
+            serverThread.start();
+        } else {
+            try {
+                doServerSide();
+            } catch (Exception e) {
+                serverException = e;
+            } finally {
+                serverReady = true;
+            }
+        }
+    }
+
+    private void startClient(boolean newThread) throws Exception {
+        if (newThread) {
+            clientThread = new Thread() {
+                @Override
+                public void run() {
+                    try {
+                        doClientSide();
+                    } catch (Exception e) {
+                        /*
+                         * Our client thread just died.
+                         */
+                        System.err.println("Client died...");
+                        clientException = e;
+                    }
+                }
+            };
+            clientThread.start();
+        } else {
+            try {
+                doClientSide();
+            } catch (Exception e) {
+                clientException = e;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/rmi/TEST.properties	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,1 @@
+modules = java.rmi
--- a/jdk/test/sun/security/provider/DSA/TestDSA2.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sun/security/provider/DSA/TestDSA2.java	Thu Apr 28 23:08:16 2016 -0700
@@ -60,8 +60,8 @@
         boolean[] expectedToPass = { true, true, true, true,
                                      true, true, true, true };
         test(1024, expectedToPass);
-        boolean[] expectedToPass2 = { true, true, true, true,
-                                      true, true, true, true };
+        boolean[] expectedToPass2 = { true, false, true, true,
+                                      true, false, true, true };
         test(2048, expectedToPass2);
     }
 
--- a/jdk/test/sun/security/rsa/SpecTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sun/security/rsa/SpecTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -20,32 +20,32 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+
+/**
+ * @test
+ * @bug 8044199 8137231
+ * @key intermittent
+ * @summary Check same KeyPair's private key and public key have same modulus.
+ * also check public key's public exponent equals to given spec's public
+ * exponent. Only key size 1024 is tested with RSAKeyGenParameterSpec.F0 (3).
+ * @run main SpecTest 512
+ * @run main SpecTest 768
+ * @run main SpecTest 1024
+ * @run main SpecTest 1024 3
+ * @run main SpecTest 2048
+ * @run main/timeout=240 SpecTest 4096
+ * @run main/timeout=240 SpecTest 5120
+ */
 import java.math.BigInteger;
-import java.security.InvalidAlgorithmParameterException;
 import java.security.KeyPair;
 import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
 import java.security.interfaces.RSAKey;
 import java.security.interfaces.RSAPrivateKey;
 import java.security.interfaces.RSAPublicKey;
 import java.security.spec.RSAKeyGenParameterSpec;
 
-/**
- * @test
- * @bug 8044199
- * @key intermittent
- * @summary Check same KeyPair's private key and public key have same modulus.
- *  also check public key's public exponent equals to given spec's public
- *  exponent.
- * @run main SpecTest 512
- * @run main SpecTest 768
- * @run main SpecTest 1024
- * @run main SpecTest 2048
- * @run main/timeout=240 SpecTest 4096
- * @run main/timeout=240 SpecTest 5120
- */
 public class SpecTest {
+
     /**
      * ALGORITHM name, fixed as RSA.
      */
@@ -70,14 +70,14 @@
         // test the getModulus method
         if ((priv instanceof RSAKey) && (pub instanceof RSAKey)) {
             if (!priv.getModulus().equals(pub.getModulus())) {
-                System.err.println("priv.getModulus() = " + priv.getModulus());
-                System.err.println("pub.getModulus() = " + pub.getModulus());
+                System.out.println("priv.getModulus() = " + priv.getModulus());
+                System.out.println("pub.getModulus() = " + pub.getModulus());
                 passed = false;
             }
 
             if (!pubExponent.equals(pub.getPublicExponent())) {
-                System.err.println("pubExponent = " + pubExponent);
-                System.err.println("pub.getPublicExponent() = "
+                System.out.println("pubExponent = " + pubExponent);
+                System.out.println("pub.getPublicExponent() = "
                         + pub.getPublicExponent());
                 passed = false;
             }
@@ -85,36 +85,26 @@
         return passed;
     }
 
-    public static void main(String[] args) {
-        int failCount = 0;
+    public static void main(String[] args) throws Exception {
 
-        // Test key size.
-        int size = Integer.parseInt(args[0]);
+        int size = 0;
 
-        try {
-            KeyPairGenerator kpg1 = KeyPairGenerator.getInstance(KEYALG, PROVIDER);
-            kpg1.initialize(new RSAKeyGenParameterSpec(size,
-                    RSAKeyGenParameterSpec.F4));
-            if (!specTest(kpg1.generateKeyPair(),
-                    RSAKeyGenParameterSpec.F4)) {
-                failCount++;
-            }
-
-            KeyPairGenerator kpg2 = KeyPairGenerator.getInstance(KEYALG, PROVIDER);
-            kpg2.initialize(new RSAKeyGenParameterSpec(size,
-                    RSAKeyGenParameterSpec.F0));
-            if (!specTest(kpg2.generateKeyPair(), RSAKeyGenParameterSpec.F0)) {
-                failCount++;
-            }
-        } catch (NoSuchAlgorithmException | NoSuchProviderException
-                | InvalidAlgorithmParameterException ex) {
-            ex.printStackTrace(System.err);
-            failCount++;
+        if (args.length >= 1) {
+            size = Integer.parseInt(args[0]);
+        } else {
+            throw new RuntimeException("Missing keysize to test with");
         }
 
-        if (failCount != 0) {
-            throw new RuntimeException("There are " + failCount
-                    + " tests failed.");
+        BigInteger publicExponent
+                = (args.length >= 2) ? new BigInteger(args[1]) : RSAKeyGenParameterSpec.F4;
+
+        System.out.println("Running test with key size: " + size
+                + " and public exponent: " + publicExponent);
+
+        KeyPairGenerator kpg1 = KeyPairGenerator.getInstance(KEYALG, PROVIDER);
+        kpg1.initialize(new RSAKeyGenParameterSpec(size, publicExponent));
+        if (!specTest(kpg1.generateKeyPair(), publicExponent)) {
+            throw new RuntimeException("Test failed.");
         }
     }
 }
--- a/jdk/test/sun/security/ssl/SSLContextImpl/MD2InTrustAnchor.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sun/security/ssl/SSLContextImpl/MD2InTrustAnchor.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,106 +37,88 @@
  * @run main/othervm MD2InTrustAnchor PKIX TLSv1.2
  * @run main/othervm MD2InTrustAnchor SunX509 TLSv1.2
  */
-
-import java.net.*;
-import java.util.*;
-import java.io.*;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
 import javax.net.ssl.*;
 import java.security.Security;
 import java.security.KeyStore;
 import java.security.KeyFactory;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateFactory;
-import java.security.spec.*;
-import java.security.interfaces.*;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.spec.PKCS8EncodedKeySpec;
 import java.util.Base64;
+import java.util.concurrent.CountDownLatch;
 
 public class MD2InTrustAnchor {
 
     /*
-     * =============================================================
-     * Set the various variables needed for the tests, then
-     * specify what tests to run on each side.
-     */
-
-    /*
-     * Should we run the client or server in a separate thread?
-     * Both sides can throw exceptions, but do you have a preference
-     * as to which side should be the main thread.
-     */
-    static boolean separateServerThread = false;
-
-    /*
      * Certificates and key used in the test.
      */
-
     // It's a trust anchor signed with MD2 hash function.
-    static String trustedCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIICkjCCAfugAwIBAgIBADANBgkqhkiG9w0BAQIFADA7MQswCQYDVQQGEwJVUzEN\n" +
-        "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" +
-        "MTExMTE4MTExNDA0WhcNMzIxMDI4MTExNDA0WjA7MQswCQYDVQQGEwJVUzENMAsG\n" +
-        "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwgZ8wDQYJ\n" +
-        "KoZIhvcNAQEBBQADgY0AMIGJAoGBAPGyB9tugUGgxtdeqe0qJEwf9x1Gy4BOi1yR\n" +
-        "wzDZY4H5LquvIfQ2V3J9X1MQENVsFvkvp65ZcFcy+ObOucXUUPFcd/iw2DVb5QXA\n" +
-        "ffyeVqWD56GPi8Qe37wrJO3L6fBhN9oxp/BbdRLgjU81zx8qLEyPODhPMxV4OkcA\n" +
-        "SDwZTSxxAgMBAAGjgaUwgaIwHQYDVR0OBBYEFLOAtr/YrYj9H04EDLA0fd14jisF\n" +
-        "MGMGA1UdIwRcMFqAFLOAtr/YrYj9H04EDLA0fd14jisFoT+kPTA7MQswCQYDVQQG\n" +
-        "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" +
-        "Y2WCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEC\n" +
-        "BQADgYEAr8ExpXu/FTIRiMzPm0ubqwME4lniilwQUiEOD/4DbksNjEIcUyS2hIk1\n" +
-        "qsmjJz3SHBnwhxl9dhJVwk2tZLkPGW86Zn0TPVRsttK4inTgCC9GFGeqQBdrU/uf\n" +
-        "lipBzXWljrfbg4N/kK8m2LabtKUMMnGysM8rN0Fx2PYm5xxGvtM=\n" +
-        "-----END CERTIFICATE-----";
+    private static final String TRUSTED_CERT_STR = "-----BEGIN CERTIFICATE-----\n"
+            + "MIICkjCCAfugAwIBAgIBADANBgkqhkiG9w0BAQIFADA7MQswCQYDVQQGEwJVUzEN\n"
+            + "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n"
+            + "MTExMTE4MTExNDA0WhcNMzIxMDI4MTExNDA0WjA7MQswCQYDVQQGEwJVUzENMAsG\n"
+            + "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwgZ8wDQYJ\n"
+            + "KoZIhvcNAQEBBQADgY0AMIGJAoGBAPGyB9tugUGgxtdeqe0qJEwf9x1Gy4BOi1yR\n"
+            + "wzDZY4H5LquvIfQ2V3J9X1MQENVsFvkvp65ZcFcy+ObOucXUUPFcd/iw2DVb5QXA\n"
+            + "ffyeVqWD56GPi8Qe37wrJO3L6fBhN9oxp/BbdRLgjU81zx8qLEyPODhPMxV4OkcA\n"
+            + "SDwZTSxxAgMBAAGjgaUwgaIwHQYDVR0OBBYEFLOAtr/YrYj9H04EDLA0fd14jisF\n"
+            + "MGMGA1UdIwRcMFqAFLOAtr/YrYj9H04EDLA0fd14jisFoT+kPTA7MQswCQYDVQQG\n"
+            + "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n"
+            + "Y2WCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEC\n"
+            + "BQADgYEAr8ExpXu/FTIRiMzPm0ubqwME4lniilwQUiEOD/4DbksNjEIcUyS2hIk1\n"
+            + "qsmjJz3SHBnwhxl9dhJVwk2tZLkPGW86Zn0TPVRsttK4inTgCC9GFGeqQBdrU/uf\n"
+            + "lipBzXWljrfbg4N/kK8m2LabtKUMMnGysM8rN0Fx2PYm5xxGvtM=\n"
+            + "-----END CERTIFICATE-----";
 
     // The certificate issued by above trust anchor, signed with MD5
-    static String targetCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIICeDCCAeGgAwIBAgIBAjANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" +
-        "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" +
-        "MTExMTE4MTExNDA2WhcNMzEwODA1MTExNDA2WjBPMQswCQYDVQQGEwJVUzENMAsG\n" +
-        "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxEjAQBgNV\n" +
-        "BAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwDnm96mw\n" +
-        "fXCH4bgXk1US0VcJsQVxUtGMyncAveMuzBzNzOmKZPeqyYX1Fuh4q+cuza03WTJd\n" +
-        "G9nOkNr364e3Rn1aaHjCMcBmFflObnGnhhufNmIGYogJ9dJPmhUVPEVAXrMG+Ces\n" +
-        "NKy2E8woGnLMrqu6yiuTClbLBPK8fWzTXrECAwEAAaN4MHYwCwYDVR0PBAQDAgPo\n" +
-        "MB0GA1UdDgQWBBSdRrpocLPJXyGfDmMWJrcEf29WGDAfBgNVHSMEGDAWgBSzgLa/\n" +
-        "2K2I/R9OBAywNH3deI4rBTAnBgNVHSUEIDAeBggrBgEFBQcDAQYIKwYBBQUHAwIG\n" +
-        "CCsGAQUFBwMDMA0GCSqGSIb3DQEBBAUAA4GBAKJ71ZiCUykkJrCLYUxlFlhvUcr9\n" +
-        "sTcOc67QdroW5f412NI15SXWDiley/JOasIiuIFPjaJBjOKoHOvTjG/snVu9wEgq\n" +
-        "YNR8dPsO+NM8r79C6jO+Jx5fYAC7os2XxS75h3NX0ElJcbwIXGBJ6xRrsFh/BGYH\n" +
-        "yvudOlX4BkVR0l1K\n" +
-        "-----END CERTIFICATE-----";
+    private static final String TARGET_CERT_STR = "-----BEGIN CERTIFICATE-----\n"
+            + "MIICeDCCAeGgAwIBAgIBAjANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n"
+            + "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n"
+            + "MTExMTE4MTExNDA2WhcNMzEwODA1MTExNDA2WjBPMQswCQYDVQQGEwJVUzENMAsG\n"
+            + "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxEjAQBgNV\n"
+            + "BAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwDnm96mw\n"
+            + "fXCH4bgXk1US0VcJsQVxUtGMyncAveMuzBzNzOmKZPeqyYX1Fuh4q+cuza03WTJd\n"
+            + "G9nOkNr364e3Rn1aaHjCMcBmFflObnGnhhufNmIGYogJ9dJPmhUVPEVAXrMG+Ces\n"
+            + "NKy2E8woGnLMrqu6yiuTClbLBPK8fWzTXrECAwEAAaN4MHYwCwYDVR0PBAQDAgPo\n"
+            + "MB0GA1UdDgQWBBSdRrpocLPJXyGfDmMWJrcEf29WGDAfBgNVHSMEGDAWgBSzgLa/\n"
+            + "2K2I/R9OBAywNH3deI4rBTAnBgNVHSUEIDAeBggrBgEFBQcDAQYIKwYBBQUHAwIG\n"
+            + "CCsGAQUFBwMDMA0GCSqGSIb3DQEBBAUAA4GBAKJ71ZiCUykkJrCLYUxlFlhvUcr9\n"
+            + "sTcOc67QdroW5f412NI15SXWDiley/JOasIiuIFPjaJBjOKoHOvTjG/snVu9wEgq\n"
+            + "YNR8dPsO+NM8r79C6jO+Jx5fYAC7os2XxS75h3NX0ElJcbwIXGBJ6xRrsFh/BGYH\n"
+            + "yvudOlX4BkVR0l1K\n"
+            + "-----END CERTIFICATE-----";
 
     // Private key in the format of PKCS#8.
-    static String targetPrivateKey =
-        "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMA55vepsH1wh+G4\n" +
-        "F5NVEtFXCbEFcVLRjMp3AL3jLswczczpimT3qsmF9RboeKvnLs2tN1kyXRvZzpDa\n" +
-        "9+uHt0Z9Wmh4wjHAZhX5Tm5xp4YbnzZiBmKICfXST5oVFTxFQF6zBvgnrDSsthPM\n" +
-        "KBpyzK6rusorkwpWywTyvH1s016xAgMBAAECgYEAn9bF3oRkdDoBU0i/mcww5I+K\n" +
-        "SH9tFt+WQbiojjz9ac49trkvUfu7MO1Jui2+QbrvaSkyj+HYGFOJd1wMsPXeB7ck\n" +
-        "5mOIYV4uZK8jfNMSQ8v0tFEeIPp5lKdw1XnrQfSe+abo2eL5Lwso437Y4s3w37+H\n" +
-        "aY3d76hR5qly+Ys+Ww0CQQDjeOoX89d/xhRqGXKjCx8ImE/dPmsI8O27cwtKrDYJ\n" +
-        "6t0v/xryVIdvOYcRBvKnqEogOH7T1kI+LnWKUTJ2ehJ7AkEA2FVloPVqCehXcc7e\n" +
-        "z3TDpU9w1B0JXklcV5HddYsRqp9RukN/VK4szKE7F1yoarIUtfE9Lr9082Jwyp3M\n" +
-        "L11xwwJBAKsZ+Hur3x0tUY29No2Nf/pnFyvEF57SGwA0uPmiL8Ol9lpz+UDudDEl\n" +
-        "hIM6Rqv12kwCMuQE9i7vo1o3WU3k5KECQEqhg1L49yD935TqiiFFpe0Ur9btQXse\n" +
-        "kdXAA4d2d5zGI7q/aGD9SYU6phkUJSHR16VA2RuUfzMrpb+wmm1IrmMCQFtLoKRT\n" +
-        "A5kokFb+E3Gplu29tJvCUpfwgBFRS+wmkvtiaU/tiyDcVgDO+An5DwedxxdVzqiE\n" +
-        "njWHoKY3axDQ8OU=\n";
+    private static final String TARGET_PRIV_KEY_STR = "MIICdwIBADANBgkqhkiG9w0B\n"
+            + "AQEFAASCAmEwggJdAgEAAoGBAMA55vepsH1wh+G4F5NVEtFXCbEFcVLRjMp3AL3j\n"
+            + "LswczczpimT3qsmF9RboeKvnLs2tN1kyXRvZzpDa9+uHt0Z9Wmh4wjHAZhX5Tm5x\n"
+            + "p4YbnzZiBmKICfXST5oVFTxFQF6zBvgnrDSsthPMKBpyzK6rusorkwpWywTyvH1s\n"
+            + "016xAgMBAAECgYEAn9bF3oRkdDoBU0i/mcww5I+KSH9tFt+WQbiojjz9ac49trkv\n"
+            + "Ufu7MO1Jui2+QbrvaSkyj+HYGFOJd1wMsPXeB7ck5mOIYV4uZK8jfNMSQ8v0tFEe\n"
+            + "IPp5lKdw1XnrQfSe+abo2eL5Lwso437Y4s3w37+HaY3d76hR5qly+Ys+Ww0CQQDj\n"
+            + "eOoX89d/xhRqGXKjCx8ImE/dPmsI8O27cwtKrDYJ6t0v/xryVIdvOYcRBvKnqEog\n"
+            + "OH7T1kI+LnWKUTJ2ehJ7AkEA2FVloPVqCehXcc7ez3TDpU9w1B0JXklcV5HddYsR\n"
+            + "qp9RukN/VK4szKE7F1yoarIUtfE9Lr9082Jwyp3ML11xwwJBAKsZ+Hur3x0tUY29\n"
+            + "No2Nf/pnFyvEF57SGwA0uPmiL8Ol9lpz+UDudDElhIM6Rqv12kwCMuQE9i7vo1o3\n"
+            + "WU3k5KECQEqhg1L49yD935TqiiFFpe0Ur9btQXsekdXAA4d2d5zGI7q/aGD9SYU6\n"
+            + "phkUJSHR16VA2RuUfzMrpb+wmm1IrmMCQFtLoKRTA5kokFb+E3Gplu29tJvCUpfw\n"
+            + "gBFRS+wmkvtiaU/tiyDcVgDO+An5DwedxxdVzqiEnjWHoKY3axDQ8OU=";
 
-
-    static char passphrase[] = "passphrase".toCharArray();
+    private static final char PASSPHRASE[] = "passphrase".toCharArray();
 
     /*
      * Is the server ready to serve?
      */
-    volatile static boolean serverReady = false;
+    private static volatile CountDownLatch sync = new CountDownLatch(1);
 
     /*
      * Turn on SSL debugging?
      */
-    static boolean debug = false;
+    private static final boolean DEBUG = false;
 
     /*
      * Define the server side of the test.
@@ -144,29 +126,30 @@
      * If the server prematurely exits, serverReady will be set to true
      * to avoid infinite hangs.
      */
-    void doServerSide() throws Exception {
-        SSLContext context = generateSSLContext(trustedCertStr, targetCertStr,
-                                            targetPrivateKey);
+    private void doServerSide() throws Exception {
+        SSLContext context = generateSSLContext(TRUSTED_CERT_STR, TARGET_CERT_STR,
+                TARGET_PRIV_KEY_STR);
         SSLServerSocketFactory sslssf = context.getServerSocketFactory();
-        SSLServerSocket sslServerSocket =
-            (SSLServerSocket)sslssf.createServerSocket(serverPort);
-        sslServerSocket.setNeedClientAuth(true);
-        serverPort = sslServerSocket.getLocalPort();
+        try (SSLServerSocket sslServerSocket
+                = (SSLServerSocket) sslssf.createServerSocket(serverPort)) {
+            sslServerSocket.setNeedClientAuth(true);
+            serverPort = sslServerSocket.getLocalPort();
+            /*
+            * Signal Client, we're ready for his connect.
+             */
+            System.out.println("Signal server ready");
+            sync.countDown();
 
-        /*
-         * Signal Client, we're ready for his connect.
-         */
-        serverReady = true;
+            System.out.println("Waiting for client connection");
+            try (SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept()) {
+                InputStream sslIS = sslSocket.getInputStream();
+                OutputStream sslOS = sslSocket.getOutputStream();
 
-        SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept();
-        InputStream sslIS = sslSocket.getInputStream();
-        OutputStream sslOS = sslSocket.getOutputStream();
-
-        sslIS.read();
-        sslOS.write('A');
-        sslOS.flush();
-
-        sslSocket.close();
+                sslIS.read();
+                sslOS.write('A');
+                sslOS.flush();
+            }
+        }
     }
 
     /*
@@ -175,33 +158,31 @@
      * If the server prematurely exits, serverReady will be set to true
      * to avoid infinite hangs.
      */
-    void doClientSide() throws Exception {
+    private void doClientSide() throws Exception {
 
         /*
          * Wait for server to get started.
          */
-        while (!serverReady) {
-            Thread.sleep(50);
-        }
+        System.out.println("Waiting for server ready");
+        sync.await();
 
-        SSLContext context = generateSSLContext(trustedCertStr, targetCertStr,
-                                            targetPrivateKey);
+        SSLContext context = generateSSLContext(TRUSTED_CERT_STR, TARGET_CERT_STR,
+                TARGET_PRIV_KEY_STR);
         SSLSocketFactory sslsf = context.getSocketFactory();
 
-        SSLSocket sslSocket =
-            (SSLSocket)sslsf.createSocket("localhost", serverPort);
-
-        // enable the specified TLS protocol
-        sslSocket.setEnabledProtocols(new String[] {tlsProtocol});
+        System.out.println("Connect to server on port: " + serverPort);
+        try (SSLSocket sslSocket
+                = (SSLSocket) sslsf.createSocket("localhost", serverPort)) {
+            // enable the specified TLS protocol
+            sslSocket.setEnabledProtocols(new String[]{tlsProtocol});
 
-        InputStream sslIS = sslSocket.getInputStream();
-        OutputStream sslOS = sslSocket.getOutputStream();
+            InputStream sslIS = sslSocket.getInputStream();
+            OutputStream sslOS = sslSocket.getOutputStream();
 
-        sslOS.write('B');
-        sslOS.flush();
-        sslIS.read();
-
-        sslSocket.close();
+            sslOS.write('B');
+            sslOS.flush();
+            sslIS.read();
+        }
     }
 
     /*
@@ -240,10 +221,10 @@
         if (keyCertStr != null) {
             // generate the private key.
             PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(
-                                Base64.getMimeDecoder().decode(keySpecStr));
+                    Base64.getMimeDecoder().decode(keySpecStr));
             KeyFactory kf = KeyFactory.getInstance("RSA");
-            RSAPrivateKey priKey =
-                    (RSAPrivateKey)kf.generatePrivate(priKeySpec);
+            RSAPrivateKey priKey
+                    = (RSAPrivateKey) kf.generatePrivate(priKeySpec);
 
             // generate certificate chain
             is = new ByteArrayInputStream(keyCertStr.getBytes());
@@ -257,7 +238,7 @@
             chain[0] = keyCert;
 
             // import the key entry.
-            ks.setKeyEntry("Whatever", priKey, passphrase, chain);
+            ks.setKeyEntry("Whatever", priKey, PASSPHRASE, chain);
         }
 
         // create SSL context
@@ -267,7 +248,7 @@
         SSLContext ctx = SSLContext.getInstance(tlsProtocol);
         if (keyCertStr != null && !keyCertStr.isEmpty()) {
             KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");
-            kmf.init(ks, passphrase);
+            kmf.init(ks, PASSPHRASE);
 
             ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
             ks = null;
@@ -278,12 +259,10 @@
         return ctx;
     }
 
+    // use any free port by default
+    private volatile int serverPort = 0;
 
-    // use any free port by default
-    volatile int serverPort = 0;
-
-    volatile Exception serverException = null;
-    volatile Exception clientException = null;
+    private volatile Exception serverException = null;
 
     public static void main(String[] args) throws Exception {
         // MD5 is used in this test case, don't disable MD5 algorithm.
@@ -292,140 +271,61 @@
         Security.setProperty("jdk.tls.disabledAlgorithms",
                 "SSLv3, RC4, DH keySize < 768");
 
-        if (debug)
+        if (DEBUG) {
             System.setProperty("javax.net.debug", "all");
+        }
 
         /*
          * Get the customized arguments.
          */
         parseArguments(args);
-
         /*
          * Start the tests.
          */
-        new MD2InTrustAnchor();
+        new MD2InTrustAnchor().runTest();
     }
 
-    Thread clientThread = null;
-    Thread serverThread = null;
+    private Thread serverThread = null;
 
     /*
-     * Primary constructor, used to drive remainder of the test.
+     * Used to drive remainder of the test.
      *
      * Fork off the other side, then do your work.
      */
-    MD2InTrustAnchor() throws Exception {
-        try {
-            if (separateServerThread) {
-                startServer(true);
-                startClient(false);
-            } else {
-                startClient(true);
-                startServer(false);
-            }
-        } catch (Exception e) {
-            // swallow for now.  Show later
-        }
+    public void runTest() throws Exception {
+        startServerThread();
+        doClientSide();
 
         /*
          * Wait for other side to close down.
          */
-        if (separateServerThread) {
-            serverThread.join();
-        } else {
-            clientThread.join();
-        }
-
-        /*
-         * When we get here, the test is pretty much over.
-         * Which side threw the error?
-         */
-        Exception local;
-        Exception remote;
-        String whichRemote;
+        serverThread.join();
 
-        if (separateServerThread) {
-            remote = serverException;
-            local = clientException;
-            whichRemote = "server";
-        } else {
-            remote = clientException;
-            local = serverException;
-            whichRemote = "client";
-        }
-
-        /*
-         * If both failed, return the curthread's exception, but also
-         * print the remote side Exception
-         */
-        if ((local != null) && (remote != null)) {
-            System.out.println(whichRemote + " also threw:");
-            remote.printStackTrace();
-            System.out.println();
-            throw local;
-        }
-
-        if (remote != null) {
-            throw remote;
-        }
-
-        if (local != null) {
-            throw local;
+        if (serverException != null) {
+            throw serverException;
         }
     }
 
-    void startServer(boolean newThread) throws Exception {
-        if (newThread) {
-            serverThread = new Thread() {
-                public void run() {
-                    try {
-                        doServerSide();
-                    } catch (Exception e) {
-                        /*
-                         * Our server thread just died.
-                         *
-                         * Release the client, if not active already...
-                         */
-                        System.err.println("Server died...");
-                        serverReady = true;
-                        serverException = e;
-                    }
+    private void startServerThread() {
+        serverThread = new Thread() {
+            @Override
+            public void run() {
+                try {
+                    doServerSide();
+                } catch (Exception e) {
+                    /*
+                     * Our server thread just died.
+                     *
+                     * Release the client, if not active already...
+                     */
+                    System.err.println("Server died...");
+                    e.printStackTrace(System.out);
+                    serverException = e;
+                    sync.countDown();
                 }
-            };
-            serverThread.start();
-        } else {
-            try {
-                doServerSide();
-            } catch (Exception e) {
-                serverException = e;
-            } finally {
-                serverReady = true;
             }
-        }
-    }
+        };
 
-    void startClient(boolean newThread) throws Exception {
-        if (newThread) {
-            clientThread = new Thread() {
-                public void run() {
-                    try {
-                        doClientSide();
-                    } catch (Exception e) {
-                        /*
-                         * Our client thread just died.
-                         */
-                        System.err.println("Client died...");
-                        clientException = e;
-                    }
-                }
-            };
-            clientThread.start();
-        } else {
-            try {
-                doClientSide();
-            } catch (Exception e) {
-                clientException = e;
-            }
-        }
+        serverThread.start();
     }
 }
--- a/jdk/test/sun/security/tools/jarsigner/Warning.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sun/security/tools/jarsigner/Warning.java	Thu Apr 28 23:08:16 2016 -0700
@@ -89,7 +89,7 @@
         issueCert("c");
         run("jarsigner", "a.jar c")
                 .shouldContain("chain is not validated. " +
-                        "Reason: algorithm constraints check failed");
+                        "Reason: Algorithm constraints check failed");
 
         recreateJar();
 
--- a/jdk/test/sun/util/logging/PlatformLoggerTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/sun/util/logging/PlatformLoggerTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -197,7 +197,7 @@
         // create a brand new java logger
         Logger javaLogger = sun.util.logging.internal.LoggingProviderImpl.getLogManagerAccess()
                      .demandLoggerFor(LogManager.getLogManager(),
-                          logger.getName()+"."+level.getName(), Thread.class);
+                          logger.getName()+"."+level.getName(), Thread.class.getModule());
 
         // Set a non standard java.util.logging.Level on the java logger
         // (except for OFF & ALL - which will remain unchanged)
--- a/jdk/test/tools/jimage/JImageTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/tools/jimage/JImageTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -110,54 +110,5 @@
                 .dir(helper.createNewExtractedDir("modules"))
                 .image(image.resolve("lib").resolve("modules"))
                 .extract().assertSuccess();
-
-        Path recreatedImage = JImageGenerator.getJImageTask()
-                .dir(extractedDir)
-                .image(helper.createNewRecreatedDir(extractedDir.getFileName().toString()))
-                .recreate().assertSuccess();
-        JImageValidator.validate(recreatedImage, bootClasses, Collections.emptyList());
-
-        // Check replacing the boot image by recreated one
-        Path destFile = image.resolve("lib").resolve("modules");
-        Files.copy(recreatedImage, destFile, REPLACE_EXISTING);
-        JImageValidator validator = new JImageValidator(module, Collections.emptyList(),
-                image.toFile(), Collections.emptyList(), Collections.emptyList());
-        validator.validate();
-
-        Path recreatedImage2 = JImageGenerator.getJImageTask()
-                .dir(extractedDir)
-                .option("--compress").option("2")
-                .image(helper.createNewRecreatedDir(extractedDir.getFileName().toString()))
-                .recreate().assertSuccess();
-        JImageValidator.validate(recreatedImage2, bootClasses, Collections.emptyList());
-
-        Path recreatedImage3 = JImageGenerator.getJImageTask()
-                .dir(extractedDir)
-                .option("--strip-debug")
-                .image(helper.createNewRecreatedDir(extractedDir.getFileName().toString()))
-                .recreate().assertSuccess();
-        JImageValidator.validate(recreatedImage3, bootClasses, Collections.emptyList());
-
-        Path recreatedImage4 = JImageGenerator.getJImageTask()
-                .dir(extractedDir)
-                .option("--exclude-resources")
-                .option("*.jcov, */META-INF/*")
-                .image(helper.createNewRecreatedDir(extractedDir.getFileName().toString()))
-                .recreate().assertSuccess();
-        List<String> unexpectedPaths = new ArrayList<>();
-        unexpectedPaths.add(".jcov");
-        unexpectedPaths.add("/META-INF/");
-        JImageValidator.validate(recreatedImage4, bootClasses, unexpectedPaths);
-
-        Path recreatedImage5 = JImageGenerator.getJImageTask()
-                .dir(extractedDir)
-                .option("--compress")
-                .option("2")
-                .option("--strip-debug")
-                .option("--exclude-resources")
-                .option("*.jcov, */META-INF/*")
-                .image(helper.createNewRecreatedDir(extractedDir.getFileName().toString()))
-                .recreate().assertSuccess();
-        JImageValidator.validate(recreatedImage5, bootClasses, unexpectedPaths);
     }
 }
--- a/jdk/test/tools/jimage/JImageToolTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/tools/jimage/JImageToolTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -63,11 +63,7 @@
             String jimage = jimagePath.toAbsolutePath().toString();
             String bootimage = modulesimagePath.toAbsolutePath().toString();
             String extractDir = Paths.get(".", "extract").toAbsolutePath().toString();
-            String recreateImage = Paths.get(".", "recreate").toAbsolutePath().toString();
-            String relativeRecreateImage = Paths.get(".", "recreate2").toString();
             jimage("extract", "--dir", extractDir, bootimage);
-            jimage("recreate", "--dir", extractDir, recreateImage);
-            jimage("recreate", "--dir", extractDir, relativeRecreateImage);
             System.out.println("Test successful");
          } else {
             System.out.println("Test skipped, not an images build");
--- a/jdk/test/tools/jlink/plugins/InstalledModuleDescriptors/src/m1/p1/Main.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/tools/jlink/plugins/InstalledModuleDescriptors/src/m1/p1/Main.java	Thu Apr 28 23:08:16 2016 -0700
@@ -29,6 +29,7 @@
 import java.nio.file.FileSystems;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.util.Collections;
 import java.util.Set;
 
 public class Main {
@@ -40,7 +41,8 @@
         validate(Main.class.getModule().getDescriptor());
 
         // read m1/module-info.class
-        FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"), null);
+        FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"),
+                                                  Collections.emptyMap());
         Path path = fs.getPath("/", "modules", "m1", "module-info.class");
         validate(ModuleDescriptor.read(Files.newInputStream(path)));
     }
--- a/jdk/test/tools/launcher/Arrrghs.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/tools/launcher/Arrrghs.java	Thu Apr 28 23:08:16 2016 -0700
@@ -489,7 +489,7 @@
             return;
         }
 
-        TestResult tr = null;
+        TestResult tr;
 
         // a missing class
         createJar("MIA", new File("some.jar"), new File("Foo"),
@@ -592,7 +592,7 @@
         if (!isEnglishLocale()) { // only english version
             return;
         }
-        TestResult tr = null;
+        TestResult tr;
         // a missing class
         createJar("MIA", new File("some.jar"), new File("Foo"),
                 (String[])null);
--- a/jdk/test/tools/launcher/DefaultLocaleTestRun.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/tools/launcher/DefaultLocaleTestRun.java	Thu Apr 28 23:08:16 2016 -0700
@@ -41,7 +41,7 @@
             System.out.println("Test passes vacuously on non-windows");
             return;
         }
-        TestResult tr = null;
+        TestResult tr;
         tr = doExec(javaCmd,
                 "-cp", TEST_CLASSES_DIR.getAbsolutePath(),
                 "DefaultLocaleTest", "-w", "x.out");
--- a/jdk/test/tools/launcher/ExecutionEnvironment.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/tools/launcher/ExecutionEnvironment.java	Thu Apr 28 23:08:16 2016 -0700
@@ -120,15 +120,14 @@
      */
     @Test
     void testEcoFriendly() {
-        TestResult tr = null;
-
         Map<String, String> env = new HashMap<>();
         for (String x : LD_PATH_STRINGS) {
             String pairs[] = x.split("=");
             env.put(pairs[0], pairs[1]);
         }
 
-        tr = doExec(env, javaCmd, "-jar", testJarFile.getAbsolutePath());
+        TestResult tr =
+            doExec(env, javaCmd, "-jar", testJarFile.getAbsolutePath());
 
         if (!tr.isNotZeroOutput()) {
             flagError(tr, "Error: No output at all. Did the test execute ?");
@@ -180,7 +179,7 @@
      */
     @Test
     void testJavaLibraryPath() {
-        TestResult tr = null;
+        TestResult tr;
 
         Map<String, String> env = new HashMap<>();
 
@@ -240,17 +239,14 @@
      */
     @Test
     void testVmSelection() {
-
-        TestResult tr = null;
-
         if (haveClientVM) {
-            tr = doExec(javaCmd, "-client", "-version");
+            TestResult tr = doExec(javaCmd, "-client", "-version");
             if (!tr.matches(".*Client VM.*")) {
                 flagError(tr, "the expected vm -client did not launch");
             }
         }
         if (haveServerVM) {
-            tr = doExec(javaCmd, "-server", "-version");
+            TestResult tr = doExec(javaCmd, "-server", "-version");
             if (!tr.matches(".*Server VM.*")) {
                 flagError(tr, "the expected vm -server did not launch");
             }
--- a/jdk/test/tools/launcher/FXLauncherTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/tools/launcher/FXLauncherTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -239,7 +239,7 @@
             createFile(ManifestFile, createManifestContents(StdMainClass, fxMC));
             createJar(FXtestJar, ManifestFile);
             String sTestJar = FXtestJar.getAbsolutePath();
-            TestResult tr;
+            final TestResult tr;
             if (useCP) {
                 tr = doExec(javaCmd, "-cp", sTestJar, StdMainClass, APP_PARMS[0], APP_PARMS[1]);
             } else {
@@ -290,7 +290,7 @@
             createFile(ManifestFile, createManifestContents(ExtMainClass, fxMC));
             createJar(FXtestJar, ManifestFile);
             String sTestJar = FXtestJar.getAbsolutePath();
-            TestResult tr;
+            final TestResult tr;
             if (useCP) {
                 tr = doExec(javaCmd, "-cp", sTestJar, ExtMainClass, APP_PARMS[0], APP_PARMS[1]);
             } else {
@@ -359,7 +359,7 @@
         createFile(ManifestFile, createManifestContents(NonFXMainClass, null));
         createJar(FXtestJar, ManifestFile);
         String sTestJar = FXtestJar.getAbsolutePath();
-        TestResult tr;
+        final TestResult tr;
 
         if (useCP) {
             tr = doExec(javaCmd, "-verbose:class", "-cp", sTestJar, NonFXMainClass, APP_PARMS[0], APP_PARMS[1]);
--- a/jdk/test/tools/launcher/I18NTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/tools/launcher/I18NTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -60,7 +60,7 @@
 
         // compile the generate code using the javac compiler vs. the api, to
         // as a bonus point to see if the argument is passed correctly
-        TestResult tr = null;
+        TestResult tr;
         tr = doExec(javacCmd, fileName + JAVA_FILE_EXT);
         if (!tr.isOK()) {
             System.out.println(tr);
--- a/jdk/test/tools/launcher/MiscTests.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/tools/launcher/MiscTests.java	Thu Apr 28 23:08:16 2016 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 6856415 8154212
+ * @bug 6856415 8154212 8154470
  * @summary Miscellaneous tests, Exceptions
  * @compile -XDignore.symbol.file MiscTests.java
  * @run main MiscTests
@@ -95,30 +95,34 @@
 
         TestResult tr = doExec(javaCmd,
                 "-Djava.security.manager", "-jar", testJar.getName(), "foo.bak");
-        for (String s : tr.testOutput) {
-            System.out.println(s);
-        }
         if (!tr.contains("java.security.AccessControlException:" +
                 " access denied (\"java.lang.RuntimePermission\"" +
                 " \"accessClassInPackage.sun.security.pkcs11\")")) {
-            System.out.println(tr.status);
+            System.out.println(tr);
         }
     }
 
-    static void testJLDEnvWithTool() {
-        final Map<String, String> envMap = new HashMap<>();
-        envMap.put("_JAVA_LAUNCHER_DEBUG", "true");
-        TestResult tr = doExec(envMap, javacCmd, "-version");
-        tr.checkPositive();
-        if (!tr.isOK()) {
-           System.out.println(tr);
+    static void testJLDEnv() {
+        final Map<String, String> envToSet = new HashMap<>();
+        envToSet.put("_JAVA_LAUNCHER_DEBUG", "true");
+        for (String cmd : new String[] { javaCmd, javacCmd }) {
+            TestResult tr = doExec(envToSet, cmd, "-version");
+            tr.checkPositive();
+            String javargs = cmd.equals(javacCmd) ? "on" : "off";
+            String progname = cmd.equals(javacCmd) ? "javac" : "java";
+            if (!tr.isOK()
+                || !tr.matches("\\s*debug:on$")
+                || !tr.matches("\\s*javargs:" + javargs + "$")
+                || !tr.matches("\\s*program name:" + progname + "$")) {
+                System.out.println(tr);
+            }
         }
     }
 
     public static void main(String... args) throws IOException {
         testWithClassPathSetViaProperty();
         test6856415();
-        testJLDEnvWithTool();
+        testJLDEnv();
         if (testExitValue != 0) {
             throw new Error(testExitValue + " tests failed");
         }
--- a/jdk/test/tools/launcher/Settings.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/tools/launcher/Settings.java	Thu Apr 28 23:08:16 2016 -0700
@@ -55,9 +55,9 @@
         }
     }
 
-    static void checkNoContains(TestResult tr, String str) {
-        if (tr.contains(str)) {
-            System.out.println(tr.status);
+    static void checkNotContains(TestResult tr, String str) {
+        if (!tr.notContains(str)) {
+            System.out.println(tr);
             throw new RuntimeException(str + " found");
         }
     }
@@ -77,84 +77,77 @@
         if (getArch().equals("ppc64") || getArch().equals("ppc64le")) {
             stackSize = "800";
         }
-        TestResult tr = null;
+        TestResult tr;
         tr = doExec(javaCmd, "-Xms64m", "-Xmx512m",
                 "-Xss" + stackSize + "k", "-XshowSettings", "-jar", testJar.getAbsolutePath());
         containsAllOptions(tr);
         if (!tr.isOK()) {
-            System.out.println(tr.status);
+            System.out.println(tr);
             throw new RuntimeException("test fails");
         }
         tr = doExec(javaCmd, "-Xms65536k", "-Xmx712m",
                 "-Xss" + stackSize + "000", "-XshowSettings", "-jar", testJar.getAbsolutePath());
         containsAllOptions(tr);
         if (!tr.isOK()) {
-            System.out.println(tr.status);
+            System.out.println(tr);
             throw new RuntimeException("test fails");
         }
     }
 
     static void runTestOptionAll() throws IOException {
         init();
-        TestResult tr = null;
-        tr = doExec(javaCmd, "-XshowSettings:all");
+        TestResult tr = doExec(javaCmd, "-XshowSettings:all");
         containsAllOptions(tr);
     }
 
     static void runTestOptionVM() throws IOException {
-        TestResult tr = null;
-        tr = doExec(javaCmd, "-XshowSettings:vm");
+        TestResult tr = doExec(javaCmd, "-XshowSettings:vm");
         checkContains(tr, VM_SETTINGS);
-        checkNoContains(tr, PROP_SETTINGS);
-        checkNoContains(tr, LOCALE_SETTINGS);
+        checkNotContains(tr, PROP_SETTINGS);
+        checkNotContains(tr, LOCALE_SETTINGS);
     }
 
     static void runTestOptionProperty() throws IOException {
-        TestResult tr = null;
-        tr = doExec(javaCmd, "-XshowSettings:properties");
-        checkNoContains(tr, VM_SETTINGS);
+        TestResult tr = doExec(javaCmd, "-XshowSettings:properties");
+        checkNotContains(tr, VM_SETTINGS);
         checkContains(tr, PROP_SETTINGS);
-        checkNoContains(tr, LOCALE_SETTINGS);
+        checkNotContains(tr, LOCALE_SETTINGS);
     }
 
     static void runTestOptionLocale() throws IOException {
-        TestResult tr = null;
-        tr = doExec(javaCmd, "-XshowSettings:locale");
-        checkNoContains(tr, VM_SETTINGS);
-        checkNoContains(tr, PROP_SETTINGS);
+        TestResult tr = doExec(javaCmd, "-XshowSettings:locale");
+        checkNotContains(tr, VM_SETTINGS);
+        checkNotContains(tr, PROP_SETTINGS);
         checkContains(tr, LOCALE_SETTINGS);
     }
 
     static void runTestBadOptions() throws IOException {
-        TestResult tr = null;
-        tr = doExec(javaCmd, "-XshowSettingsBadOption");
-        checkNoContains(tr, VM_SETTINGS);
-        checkNoContains(tr, PROP_SETTINGS);
-        checkNoContains(tr, LOCALE_SETTINGS);
+        TestResult tr = doExec(javaCmd, "-XshowSettingsBadOption");
+        checkNotContains(tr, VM_SETTINGS);
+        checkNotContains(tr, PROP_SETTINGS);
+        checkNotContains(tr, LOCALE_SETTINGS);
         checkContains(tr, "Unrecognized option: -XshowSettingsBadOption");
     }
 
     static void runTest7123582() throws IOException {
-        TestResult tr = null;
-        tr = doExec(javaCmd, "-XshowSettings", "-version");
+        TestResult tr = doExec(javaCmd, "-XshowSettings", "-version");
         if (!tr.isOK()) {
-            System.out.println(tr.status);
+            System.out.println(tr);
             throw new RuntimeException("test fails");
         }
         containsAllOptions(tr);
     }
 
-    public static void main(String... args) {
-        try {
-            runTestOptionAll();
-            runTestOptionDefault();
-            runTestOptionVM();
-            runTestOptionProperty();
-            runTestOptionLocale();
-            runTestBadOptions();
-            runTest7123582();
-        } catch (IOException ioe) {
-            throw new RuntimeException(ioe);
+    public static void main(String... args) throws IOException {
+        runTestOptionAll();
+        runTestOptionDefault();
+        runTestOptionVM();
+        runTestOptionProperty();
+        runTestOptionLocale();
+        runTestBadOptions();
+        runTest7123582();
+        if (testExitValue != 0) {
+            throw new Error(testExitValue + " tests failed");
         }
     }
 }
--- a/jdk/test/tools/launcher/TestHelper.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/tools/launcher/TestHelper.java	Thu Apr 28 23:08:16 2016 -0700
@@ -603,23 +603,23 @@
             return true;
         }
 
-        boolean matches(String stringToMatch) {
+        boolean matches(String regexToMatch) {
             for (String x : testOutput) {
-                if (x.matches(stringToMatch)) {
+                if (x.matches(regexToMatch)) {
                     return true;
                 }
             }
-            appendError("string <" + stringToMatch + "> not found");
+            appendError("regex <" + regexToMatch + "> not matched");
             return false;
         }
 
-        boolean notMatches(String stringToMatch) {
+        boolean notMatches(String regexToMatch) {
             for (String x : testOutput) {
-                if (!x.matches(stringToMatch)) {
+                if (!x.matches(regexToMatch)) {
                     return true;
                 }
             }
-            appendError("string <" + stringToMatch + "> found");
+            appendError("regex <" + regexToMatch + "> matched");
             return false;
         }
     }
--- a/jdk/test/tools/launcher/TestSpecialArgs.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/tools/launcher/TestSpecialArgs.java	Thu Apr 28 23:08:16 2016 -0700
@@ -241,7 +241,7 @@
 
     @Test
     void testNMArgumentProcessing() throws FileNotFoundException {
-        TestResult tr = null;
+        TestResult tr;
         // the direct invokers of the VM
         String options[] = {
             "-version", "-fullversion", "-help", "-?", "-X"
--- a/jdk/test/tools/launcher/TooSmallStackSize.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/tools/launcher/TooSmallStackSize.java	Thu Apr 28 23:08:16 2016 -0700
@@ -85,11 +85,10 @@
      */
     static String checkStack(String stackSize) {
         String min_stack_allowed;
-        TestResult tr;
 
         if (verbose)
             System.out.println("*** Testing " + stackSize);
-        tr = doExec(javaCmd, "-Xss" + stackSize, "-version");
+        TestResult tr = doExec(javaCmd, "-Xss" + stackSize, "-version");
         if (verbose)
             printTestOutput(tr);
 
@@ -114,11 +113,9 @@
      * Run the JVM with the minimum allowed stack size. This should always succeed.
      */
     static void checkMinStackAllowed(String stackSize) {
-        TestResult tr = null;
-
         if (verbose)
             System.out.println("*** Testing " + stackSize);
-        tr = doExec(javaCmd, "-Xss" + stackSize, "-version");
+        TestResult tr = doExec(javaCmd, "-Xss" + stackSize, "-version");
         if (verbose)
             printTestOutput(tr);
 
--- a/jdk/test/tools/launcher/ToolsOpts.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/tools/launcher/ToolsOpts.java	Thu Apr 28 23:08:16 2016 -0700
@@ -149,7 +149,7 @@
      */
     static void runTestOptions() throws IOException {
         init();
-        TestResult tr = null;
+        TestResult tr;
         int jpos = -1;
         for (String arg[] : optionPatterns) {
             jpos = indexOfJoption(arg);
--- a/jdk/test/tools/launcher/VersionCheck.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/tools/launcher/VersionCheck.java	Thu Apr 28 23:08:16 2016 -0700
@@ -151,12 +151,11 @@
      * of the -version output as they are inconsistent.
      */
     static boolean testToolVersion() {
-        TestResult tr = null;
         TestHelper.testExitValue = 0;
         for (File f : new File(JAVA_BIN).listFiles(new ToolFilter(BLACKLIST_VERSION))) {
             String x = f.getAbsolutePath();
             System.out.println("Testing (-version): " + x);
-            tr = doExec(x, "-version");
+            TestResult tr = doExec(x, "-version");
             tr.checkPositive();
         }
         return TestHelper.testExitValue == 0;
--- a/jdk/test/tools/launcher/modules/limitmods/LimitModsTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/tools/launcher/modules/limitmods/LimitModsTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -103,10 +103,9 @@
     public void testWithAddMods() throws Exception {
         int exitValue;
 
-        // java -limitmods java.base -addmods java.logging,jdk.unsupported -listmods
+        // java -limitmods java.base -addmods java.logging -listmods
         exitValue = executeTestJava("-limitmods", "java.base",
-                                    "-addmods",
-                                    "java.logging,jdk.unsupported",  // TODO: add bug No.
+                                    "-addmods", "java.logging",
                                     "-listmods")
             .outputTo(System.out)
             .errorTo(System.out)
--- a/jdk/test/tools/lib/tests/JImageGenerator.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/jdk/test/tools/lib/tests/JImageGenerator.java	Thu Apr 28 23:08:16 2016 -0700
@@ -553,10 +553,6 @@
         public Result extract() {
             return cmd("extract", dir);
         }
-
-        public Result recreate() {
-            return cmd("recreate", image);
-        }
     }
 
     public static class JLinkTask {
--- a/langtools/.hgtags	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/.hgtags	Thu Apr 28 23:08:16 2016 -0700
@@ -357,3 +357,5 @@
 3d4117c36559b344a73f786d39cc7626b4d8e2c0 jdk-9+112
 4e87682893e662421af10a62d29ae822ce0fea04 jdk-9+113
 cba09a2e6ae969b029783eb59bb01017b78f8eef jdk-9+114
+31c8b18fdc5b94a2ddd5ea0694f350a2c907e9f7 jdk-9+115
+3e3553ee39d9e081573bc7c88a252214a3152763 jdk-9+116
--- a/langtools/src/java.compiler/share/classes/javax/tools/ToolProvider.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/tools/ToolProvider.java	Thu Apr 28 23:08:16 2016 -0700
@@ -123,7 +123,9 @@
     private static <T> T getSystemTool(Class<T> clazz, String moduleName, String className) {
         if (useLegacy) {
             try {
-                return Class.forName(className, true, ClassLoader.getSystemClassLoader()).asSubclass(clazz).newInstance();
+                @SuppressWarnings("deprecation")
+                T result = Class.forName(className, true, ClassLoader.getSystemClassLoader()).asSubclass(clazz).newInstance();
+                return result;
             } catch (ReflectiveOperationException e) {
                 throw new Error(e);
             }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java	Thu Apr 28 23:08:16 2016 -0700
@@ -698,7 +698,7 @@
      */
     public boolean packageExists(ModuleSymbol msym, Name fullname) {
         Assert.checkNonNull(msym);
-        return enterPackage(msym, fullname).exists();
+        return lookupPackage(msym, fullname).exists();
     }
 
     /** Make a package, given its fully qualified name.
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Apr 28 23:08:16 2016 -0700
@@ -4491,10 +4491,11 @@
         chk.checkNonCyclicElements(tree);
 
         // Check for proper use of serialVersionUID
-        if (env.info.lint.isEnabled(LintCategory.SERIAL) &&
-            isSerializable(c.type) &&
-            (c.flags() & Flags.ENUM) == 0 &&
-            checkForSerial(c)) {
+        if (env.info.lint.isEnabled(LintCategory.SERIAL)
+                && isSerializable(c.type)
+                && (c.flags() & Flags.ENUM) == 0
+                && !c.isAnonymous()
+                && checkForSerial(c)) {
             checkSerialVersionUID(tree, c);
         }
         if (allowTypeAnnos) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ConstFold.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ConstFold.java	Thu Apr 28 23:08:16 2016 -0700
@@ -125,15 +125,15 @@
                 return syms.booleanType.constType(b2i(intValue(od) >= 0));
 
             case lneg: // unary -
-                return syms.longType.constType(new Long(-longValue(od)));
+                return syms.longType.constType(Long.valueOf(-longValue(od)));
             case lxor: // ~
-                return syms.longType.constType(new Long(~longValue(od)));
+                return syms.longType.constType(Long.valueOf(~longValue(od)));
 
             case fneg: // unary -
-                return syms.floatType.constType(new Float(-floatValue(od)));
+                return syms.floatType.constType(Float.valueOf(-floatValue(od)));
 
             case dneg: // ~
-                return syms.doubleType.constType(new Double(-doubleValue(od)));
+                return syms.doubleType.constType(Double.valueOf(-doubleValue(od)));
 
             default:
                 return null;
@@ -216,37 +216,37 @@
 
                 case ladd:
                     return syms.longType.constType(
-                        new Long(longValue(l) + longValue(r)));
+                        Long.valueOf(longValue(l) + longValue(r)));
                 case lsub:
                     return syms.longType.constType(
-                        new Long(longValue(l) - longValue(r)));
+                        Long.valueOf(longValue(l) - longValue(r)));
                 case lmul:
                     return syms.longType.constType(
-                        new Long(longValue(l) * longValue(r)));
+                        Long.valueOf(longValue(l) * longValue(r)));
                 case ldiv:
                     return syms.longType.constType(
-                        new Long(longValue(l) / longValue(r)));
+                        Long.valueOf(longValue(l) / longValue(r)));
                 case lmod:
                     return syms.longType.constType(
-                        new Long(longValue(l) % longValue(r)));
+                        Long.valueOf(longValue(l) % longValue(r)));
                 case land:
                     return syms.longType.constType(
-                        new Long(longValue(l) & longValue(r)));
+                        Long.valueOf(longValue(l) & longValue(r)));
                 case lor:
                     return syms.longType.constType(
-                        new Long(longValue(l) | longValue(r)));
+                        Long.valueOf(longValue(l) | longValue(r)));
                 case lxor:
                     return syms.longType.constType(
-                        new Long(longValue(l) ^ longValue(r)));
+                        Long.valueOf(longValue(l) ^ longValue(r)));
                 case lshl: case lshll:
                     return syms.longType.constType(
-                        new Long(longValue(l) << intValue(r)));
+                        Long.valueOf(longValue(l) << intValue(r)));
                 case lshr: case lshrl:
                     return syms.longType.constType(
-                        new Long(longValue(l) >> intValue(r)));
+                        Long.valueOf(longValue(l) >> intValue(r)));
                 case lushr:
                     return syms.longType.constType(
-                        new Long(longValue(l) >>> intValue(r)));
+                        Long.valueOf(longValue(l) >>> intValue(r)));
                 case lcmp:
                     if (longValue(l) < longValue(r))
                         return syms.intType.constType(minusOne);
@@ -256,19 +256,19 @@
                         return syms.intType.constType(zero);
                 case fadd:
                     return syms.floatType.constType(
-                        new Float(floatValue(l) + floatValue(r)));
+                        Float.valueOf(floatValue(l) + floatValue(r)));
                 case fsub:
                     return syms.floatType.constType(
-                        new Float(floatValue(l) - floatValue(r)));
+                        Float.valueOf(floatValue(l) - floatValue(r)));
                 case fmul:
                     return syms.floatType.constType(
-                        new Float(floatValue(l) * floatValue(r)));
+                        Float.valueOf(floatValue(l) * floatValue(r)));
                 case fdiv:
                     return syms.floatType.constType(
-                        new Float(floatValue(l) / floatValue(r)));
+                        Float.valueOf(floatValue(l) / floatValue(r)));
                 case fmod:
                     return syms.floatType.constType(
-                        new Float(floatValue(l) % floatValue(r)));
+                        Float.valueOf(floatValue(l) % floatValue(r)));
                 case fcmpg: case fcmpl:
                     if (floatValue(l) < floatValue(r))
                         return syms.intType.constType(minusOne);
@@ -282,19 +282,19 @@
                         return syms.intType.constType(minusOne);
                 case dadd:
                     return syms.doubleType.constType(
-                        new Double(doubleValue(l) + doubleValue(r)));
+                        Double.valueOf(doubleValue(l) + doubleValue(r)));
                 case dsub:
                     return syms.doubleType.constType(
-                        new Double(doubleValue(l) - doubleValue(r)));
+                        Double.valueOf(doubleValue(l) - doubleValue(r)));
                 case dmul:
                     return syms.doubleType.constType(
-                        new Double(doubleValue(l) * doubleValue(r)));
+                        Double.valueOf(doubleValue(l) * doubleValue(r)));
                 case ddiv:
                     return syms.doubleType.constType(
-                        new Double(doubleValue(l) / doubleValue(r)));
+                        Double.valueOf(doubleValue(l) / doubleValue(r)));
                 case dmod:
                     return syms.doubleType.constType(
-                        new Double(doubleValue(l) % doubleValue(r)));
+                        Double.valueOf(doubleValue(l) % doubleValue(r)));
                 case dcmpg: case dcmpl:
                     if (doubleValue(l) < doubleValue(r))
                         return syms.intType.constType(minusOne);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java	Thu Apr 28 23:08:16 2016 -0700
@@ -86,6 +86,7 @@
     private final TypeEnvs typeEnvs;
     private final Name dollarAssertionsDisabled;
     private final Name classDollar;
+    private final Name dollarCloseResource;
     private final Types types;
     private final boolean debugLower;
     private final PkgInfo pkginfoOpt;
@@ -109,6 +110,8 @@
             fromString(target.syntheticNameChar() + "assertionsDisabled");
         classDollar = names.
             fromString("class" + target.syntheticNameChar());
+        dollarCloseResource = names.
+            fromString(target.syntheticNameChar() + "closeResource");
 
         types = Types.instance(context);
         Options options = Options.instance(context);
@@ -1648,9 +1651,11 @@
         ListBuffer<JCStatement> stats = new ListBuffer<>();
         JCTree resource = resources.head;
         JCExpression expr = null;
+        boolean resourceNonNull;
         if (resource instanceof JCVariableDecl) {
             JCVariableDecl var = (JCVariableDecl) resource;
             expr = make.Ident(var.sym).setType(resource.type);
+            resourceNonNull = var.init != null && TreeInfo.skipParens(var.init).hasTag(NEWCLASS);
             stats.add(var);
         } else {
             Assert.check(resource instanceof JCExpression);
@@ -1665,6 +1670,7 @@
             JCVariableDecl syntheticTwrVarDecl =
                 make.VarDef(syntheticTwrVar, (JCExpression)resource);
             expr = (JCExpression)make.Ident(syntheticTwrVar);
+            resourceNonNull = TreeInfo.skipParens(resource).hasTag(NEWCLASS);
             stats.add(syntheticTwrVarDecl);
         }
 
@@ -1694,7 +1700,7 @@
 
         int oldPos = make.pos;
         make.at(TreeInfo.endPos(block));
-        JCBlock finallyClause = makeTwrFinallyClause(primaryException, expr);
+        JCBlock finallyClause = makeTwrFinallyClause(primaryException, expr, resourceNonNull);
         make.at(oldPos);
         JCTry outerTry = make.Try(makeTwrBlock(resources.tail, block,
                                     finallyCanCompleteNormally, depth + 1),
@@ -1706,7 +1712,96 @@
         return newBlock;
     }
 
-    private JCBlock makeTwrFinallyClause(Symbol primaryException, JCExpression resource) {
+    /**If the estimated number of copies the close resource code in a single class is above this
+     * threshold, generate and use a method for the close resource code, leading to smaller code.
+     * As generating a method has overhead on its own, generating the method for cases below the
+     * threshold could lead to an increase in code size.
+     */
+    public static final int USE_CLOSE_RESOURCE_METHOD_THRESHOLD = 4;
+
+    private JCBlock makeTwrFinallyClause(Symbol primaryException, JCExpression resource,
+            boolean resourceNonNull) {
+        MethodSymbol closeResource = (MethodSymbol)lookupSynthetic(dollarCloseResource,
+                                                                   currentClass.members());
+
+        if (closeResource == null && shouldUseCloseResourceMethod()) {
+            closeResource = new MethodSymbol(
+                PRIVATE | STATIC | SYNTHETIC,
+                dollarCloseResource,
+                new MethodType(
+                    List.of(syms.throwableType, syms.autoCloseableType),
+                    syms.voidType,
+                    List.<Type>nil(),
+                    syms.methodClass),
+                currentClass);
+            enterSynthetic(resource.pos(), closeResource, currentClass.members());
+
+            JCMethodDecl md = make.MethodDef(closeResource, null);
+            List<JCVariableDecl> params = md.getParameters();
+            md.body = make.Block(0, List.<JCStatement>of(makeTwrCloseStatement(params.get(0).sym,
+                                                                               make.Ident(params.get(1)))));
+
+            JCClassDecl currentClassDecl = classDef(currentClass);
+            currentClassDecl.defs = currentClassDecl.defs.prepend(md);
+        }
+
+        JCStatement closeStatement;
+
+        if (closeResource != null) {
+            //$closeResource(#primaryException, #resource)
+            closeStatement = make.Exec(make.Apply(List.<JCExpression>nil(),
+                                                  make.Ident(closeResource),
+                                                  List.of(make.Ident(primaryException),
+                                                          resource)
+                                                 ).setType(syms.voidType));
+        } else {
+            closeStatement = makeTwrCloseStatement(primaryException, resource);
+        }
+
+        JCStatement finallyStatement;
+
+        if (resourceNonNull) {
+            finallyStatement = closeStatement;
+        } else {
+            // if (#resource != null) { $closeResource(...); }
+            finallyStatement = make.If(makeNonNullCheck(resource),
+                                       closeStatement,
+                                       null);
+        }
+
+        return make.Block(0L,
+                          List.<JCStatement>of(finallyStatement));
+    }
+        //where:
+        private boolean shouldUseCloseResourceMethod() {
+            class TryFinder extends TreeScanner {
+                int closeCount;
+                @Override
+                public void visitTry(JCTry tree) {
+                    boolean empty = tree.body.stats.isEmpty();
+
+                    for (JCTree r : tree.resources) {
+                        closeCount += empty ? 1 : 2;
+                        empty = false; //with multiple resources, only the innermost try can be empty.
+                    }
+                    super.visitTry(tree);
+                }
+                @Override
+                public void scan(JCTree tree) {
+                    if (useCloseResourceMethod())
+                        return;
+                    super.scan(tree);
+                }
+                boolean useCloseResourceMethod() {
+                    return closeCount >= USE_CLOSE_RESOURCE_METHOD_THRESHOLD;
+                }
+            }
+            TryFinder tryFinder = new TryFinder();
+            tryFinder.scan(classDef(currentClass));
+            return tryFinder.useCloseResourceMethod();
+        }
+
+    private JCStatement makeTwrCloseStatement(Symbol primaryException, JCExpression resource) {
         // primaryException.addSuppressed(catchException);
         VarSymbol catchException =
             new VarSymbol(SYNTHETIC, make.paramName(2),
@@ -1731,11 +1826,7 @@
                                         tryTree,
                                         makeResourceCloseInvocation(resource));
 
-        // if (#resource != null) { if (primaryException ...  }
-        return make.Block(0L,
-                          List.<JCStatement>of(make.If(makeNonNullCheck(resource),
-                                                       closeIfStatement,
-                                                       null)));
+        return closeIfStatement;
     }
 
     private JCStatement makeResourceCloseInvocation(JCExpression resource) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Thu Apr 28 23:08:16 2016 -0700
@@ -53,10 +53,6 @@
 public class MemberEnter extends JCTree.Visitor {
     protected static final Context.Key<MemberEnter> memberEnterKey = new Context.Key<>();
 
-    /** A switch to determine whether we check for package/class conflicts
-     */
-    final static boolean checkClash = true;
-
     private final Enter enter;
     private final Log log;
     private final Check chk;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/FSInfo.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/FSInfo.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,3 +1,27 @@
+/*
+ * Copyright (c) 2008, 2015, 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.file;
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Thu Apr 28 23:08:16 2016 -0700
@@ -457,13 +457,13 @@
             poolObj[i] = getInt(index + 1);
             break;
         case CONSTANT_Float:
-            poolObj[i] = new Float(getFloat(index + 1));
+            poolObj[i] = Float.valueOf(getFloat(index + 1));
             break;
         case CONSTANT_Long:
-            poolObj[i] = new Long(getLong(index + 1));
+            poolObj[i] = Long.valueOf(getLong(index + 1));
             break;
         case CONSTANT_Double:
-            poolObj[i] = new Double(getDouble(index + 1));
+            poolObj[i] = Double.valueOf(getDouble(index + 1));
             break;
         case CONSTANT_MethodHandle:
             skipBytes(4);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Thu Apr 28 23:08:16 2016 -0700
@@ -826,7 +826,7 @@
         }
         public void visitClass(Attribute.Class clazz) {
             databuf.appendByte('c');
-            databuf.appendChar(pool.put(typeSig(clazz.classType)));
+            databuf.appendChar(pool.put(typeSig(types.erasure(clazz.classType))));
         }
         public void visitCompound(Attribute.Compound compound) {
             databuf.appendByte('@');
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java	Thu Apr 28 23:08:16 2016 -0700
@@ -203,7 +203,7 @@
      */
     void emitMinusOne(int tc) {
         if (tc == LONGcode) {
-            items.makeImmediateItem(syms.longType, new Long(-1)).load();
+            items.makeImmediateItem(syms.longType, Long.valueOf(-1)).load();
         } else {
             code.emitop0(iconst_m1);
         }
@@ -1086,17 +1086,19 @@
                 genStat(body, loopEnv, CRT_STATEMENT | CRT_FLOW_TARGET);
                 code.resolve(loopEnv.info.cont);
                 genStats(step, loopEnv);
-                CondItem c;
-                if (cond != null) {
-                    code.statBegin(cond.pos);
+                if (code.isAlive()) {
+                    CondItem c;
+                    if (cond != null) {
+                        code.statBegin(cond.pos);
+                        Assert.check(code.state.stacksize == 0);
+                        c = genCond(TreeInfo.skipParens(cond), CRT_FLOW_CONTROLLER);
+                    } else {
+                        c = items.makeCondItem(goto_);
+                    }
+                    code.resolve(c.jumpTrue(), startpc);
                     Assert.check(code.state.stacksize == 0);
-                    c = genCond(TreeInfo.skipParens(cond), CRT_FLOW_CONTROLLER);
-                } else {
-                    c = items.makeCondItem(goto_);
+                    code.resolve(c.falseJumps);
                 }
-                code.resolve(c.jumpTrue(), startpc);
-                Assert.check(code.state.stacksize == 0);
-                code.resolve(c.falseJumps);
             }
             Chain exit = loopEnv.info.exit;
             if (exit != null) {
@@ -1647,6 +1649,7 @@
 
     public void visitConditional(JCConditional tree) {
         Chain thenExit = null;
+        code.statBegin(tree.cond.pos);
         CondItem c = genCond(tree.cond, CRT_FLOW_CONTROLLER);
         Chain elseChain = c.jumpFalse();
         if (!c.isFalse()) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java	Thu Apr 28 23:08:16 2016 -0700
@@ -686,7 +686,7 @@
             try {
                 t = F.at(pos).Literal(
                     TypeTag.LONG,
-                    new Long(Convert.string2long(strval(prefix), token.radix())));
+                    Long.valueOf(Convert.string2long(strval(prefix), token.radix())));
             } catch (NumberFormatException ex) {
                 error(token.pos, "int.number.too.large", strval(prefix));
             }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Thu Apr 28 23:08:16 2016 -0700
@@ -282,6 +282,7 @@
 
         if (options.isSet(XPRINT)) {
             try {
+                @SuppressWarnings("deprecation")
                 Processor processor = PrintingProcessor.class.newInstance();
                 processorIterator = List.of(processor).iterator();
             } catch (Throwable t) {
@@ -549,8 +550,9 @@
                         try {
                             Class<?> processorClass = processorCL.loadClass(processorName);
                             ensureReadable(processorClass);
-                            processor =
-                                (Processor) (processorClass.newInstance());
+                            @SuppressWarnings("deprecation")
+                            Object tmp = processorClass.newInstance();
+                            processor = (Processor) tmp;
                         } catch (ClassNotFoundException cnfe) {
                             log.error("proc.processor.not.found", processorName);
                             return false;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java	Thu Apr 28 23:08:16 2016 -0700
@@ -26,8 +26,6 @@
 package com.sun.tools.sjavac;
 
 import java.io.File;
-import java.io.IOException;
-import java.io.Writer;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -42,9 +40,8 @@
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
-import java.util.regex.Pattern;
-import java.util.stream.Stream;
 
+import com.sun.tools.javac.main.Main.Result;
 import com.sun.tools.sjavac.comp.CompilationService;
 import com.sun.tools.sjavac.options.Options;
 import com.sun.tools.sjavac.pubapi.PubApi;
@@ -283,7 +280,7 @@
             }
 
             // Check the return values.
-            if (subResult.returnCode != 0) {
+            if (subResult.result != Result.OK) {
                 rc = false;
             }
         }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/ClientMain.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/ClientMain.java	Thu Apr 28 23:08:16 2016 -0700
@@ -28,6 +28,8 @@
 import java.io.OutputStreamWriter;
 import java.io.Writer;
 
+import com.sun.tools.javac.main.Main;
+import com.sun.tools.javac.main.Main.Result;
 import com.sun.tools.sjavac.AutoFlushWriter;
 import com.sun.tools.sjavac.Log;
 import com.sun.tools.sjavac.Util;
@@ -58,7 +60,7 @@
             options = Options.parseArgs(args);
         } catch (IllegalArgumentException e) {
             Log.error(e.getMessage());
-            return -1;
+            return Result.CMDERR.exitCode;
         }
 
         Log.setLogLevel(options.getLogLevel());
@@ -73,13 +75,13 @@
         Sjavac sjavac = useServer ? new SjavacClient(options) : new SjavacImpl();
 
         // Perform compilation
-        int rc = sjavac.compile(args);
+        Result result = sjavac.compile(args);
 
         // If sjavac is running in the foreground we should shut it down at this point
         if (!useServer) {
             sjavac.shutdown();
         }
 
-        return rc;
+        return result.exitCode;
     }
 }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/SjavacClient.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/SjavacClient.java	Thu Apr 28 23:08:16 2016 -0700
@@ -26,23 +26,20 @@
 package com.sun.tools.sjavac.client;
 
 import java.io.BufferedReader;
-import java.io.File;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
-import java.io.PrintStream;
 import java.io.PrintWriter;
 import java.io.Reader;
-import java.io.Writer;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.Socket;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import java.util.Scanner;
-import java.util.stream.Stream;
 
+import com.sun.tools.javac.main.Main;
+import com.sun.tools.javac.main.Main.Result;
 import com.sun.tools.sjavac.Log;
 import com.sun.tools.sjavac.Util;
 import com.sun.tools.sjavac.options.OptionHelper;
@@ -116,8 +113,8 @@
     }
 
     @Override
-    public int compile(String[] args) {
-        int result = -1;
+    public Result compile(String[] args) {
+        Result result = null;
         try (Socket socket = tryConnect()) {
             PrintWriter out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
             BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
@@ -150,22 +147,28 @@
                 }
 
                 if (type.equals(SjavacServer.LINE_TYPE_RC)) {
-                    result = Integer.parseInt(content);
+                    result = Main.Result.valueOf(content);
                 }
             }
         } catch (PortFileInaccessibleException e) {
             Log.error("Port file inaccessible.");
-            result = CompilationSubResult.ERROR_FATAL;
+            result = Result.ERROR;
         } catch (IOException ioe) {
             Log.error("IOException caught during compilation: " + ioe.getMessage());
             Log.debug(ioe);
-            result = CompilationSubResult.ERROR_FATAL;
+            result = Result.ERROR;
         } catch (InterruptedException ie) {
             Thread.currentThread().interrupt(); // Restore interrupt
             Log.error("Compilation interrupted.");
             Log.debug(ie);
-            result = CompilationSubResult.ERROR_FATAL;
+            result = Result.ERROR;
         }
+
+        if (result == null) {
+            // No LINE_TYPE_RC was found.
+            result = Result.ERROR;
+        }
+
         return result;
     }
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/CompilationService.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/CompilationService.java	Thu Apr 28 23:08:16 2016 -0700
@@ -42,6 +42,8 @@
 
 import com.sun.tools.javac.api.JavacTaskImpl;
 import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.main.Main;
+import com.sun.tools.javac.main.Main.Result;
 import com.sun.tools.javac.util.Context;
 import com.sun.tools.javac.util.Dependencies;
 import com.sun.tools.javac.util.ListBuffer;
@@ -80,7 +82,7 @@
             Dependencies.GraphDependencies.preRegister(context);
 
             // Now setup the actual compilation
-            CompilationSubResult compilationResult = new CompilationSubResult(0);
+            CompilationSubResult compilationResult = new CompilationSubResult(Result.OK);
 
             // First deal with explicit source files on cmdline and in at file
             ListBuffer<JavaFileObject> explicitJFOs = new ListBuffer<>();
@@ -97,7 +99,7 @@
 
             // Create a log to capture compiler output
             StringWriter stderrLog = new StringWriter();
-            com.sun.tools.javac.main.Main.Result rc = com.sun.tools.javac.main.Main.Result.OK;
+            Result result;
             PublicApiCollector pubApiCollector = new PublicApiCollector(context, explicitJFOs);
             PathAndPackageVerifier papVerifier = new PathAndPackageVerifier();
             NewDependencyCollector depsCollector = new NewDependencyCollector(context, explicitJFOs);
@@ -120,20 +122,23 @@
                     task.addTaskListener(pubApiCollector);
                     task.addTaskListener(papVerifier);
                     logJavacInvocation(args);
-                    rc = task.doCall();
-                    Log.debug("javac returned with code " + rc);
+                    result = task.doCall();
+                    Log.debug("javac result: " + result);
                     sfm.flush();
+                } else {
+                    result = Result.ERROR;
                 }
             } catch (Exception e) {
                 Log.error(Util.getStackTrace(e));
                 stderrLog.append(Util.getStackTrace(e));
-                rc = com.sun.tools.javac.main.Main.Result.ERROR;
+                result = Result.ERROR;
             }
 
             compilationResult.packageArtifacts = sfm.getPackageArtifacts();
 
-            if (papVerifier.errorsDiscovered())
-                rc = com.sun.tools.javac.main.Main.Result.ERROR;
+            if (papVerifier.errorsDiscovered()) {
+                result = Result.ERROR;
+            }
 
             compilationResult.packageDependencies = depsCollector.getDependencies(false);
             compilationResult.packageCpDependencies = depsCollector.getDependencies(true);
@@ -141,7 +146,7 @@
             compilationResult.packagePubapis = pubApiCollector.getPubApis(true);
             compilationResult.dependencyPubapis = pubApiCollector.getPubApis(false);
             compilationResult.stderr = stderrLog.toString();
-            compilationResult.returnCode = rc.exitCode;
+            compilationResult.result = result;
 
             return compilationResult;
         } catch (IOException e) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/PooledSjavac.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/PooledSjavac.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,6 +25,7 @@
 
 package com.sun.tools.sjavac.comp;
 
+import com.sun.tools.javac.main.Main.Result;
 import com.sun.tools.sjavac.Log;
 import com.sun.tools.sjavac.server.Sjavac;
 
@@ -54,7 +55,7 @@
     }
 
     @Override
-    public int compile(String[] args) {
+    public Result compile(String[] args) {
         Log log = Log.get();
         try {
             return pool.submit(() -> {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SjavacImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SjavacImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -41,6 +41,7 @@
 
 import com.sun.tools.javac.file.JavacFileManager;
 import com.sun.tools.javac.main.Main;
+import com.sun.tools.javac.main.Main.Result;
 import com.sun.tools.javac.util.Context;
 import com.sun.tools.sjavac.JavacState;
 import com.sun.tools.sjavac.Log;
@@ -69,36 +70,36 @@
 public class SjavacImpl implements Sjavac {
 
     @Override
-    public int compile(String[] args) {
+    public Result compile(String[] args) {
         Options options;
         try {
             options = Options.parseArgs(args);
         } catch (IllegalArgumentException e) {
             Log.error(e.getMessage());
-            return RC_FATAL;
+            return Result.CMDERR;
         }
 
         if (!validateOptions(options))
-            return RC_FATAL;
+            return Result.CMDERR;
 
         if (srcDstOverlap(options.getSources(), options.getDestDir())) {
-            return RC_FATAL;
+            return Result.CMDERR;
         }
 
         if (!createIfMissing(options.getDestDir()))
-            return RC_FATAL;
+            return Result.ERROR;
 
         Path stateDir = options.getStateDir();
         if (stateDir != null && !createIfMissing(options.getStateDir()))
-            return RC_FATAL;
+            return Result.ERROR;
 
         Path gensrc = options.getGenSrcDir();
         if (gensrc != null && !createIfMissing(gensrc))
-            return RC_FATAL;
+            return Result.ERROR;
 
         Path hdrdir = options.getHeaderDir();
         if (hdrdir != null && !createIfMissing(hdrdir))
-            return RC_FATAL;
+            return Result.ERROR;
 
         if (stateDir == null) {
             // Prepare context. Direct logging to our byte array stream.
@@ -113,7 +114,7 @@
                                              .filter(arg -> !arg.startsWith(Option.SERVER.arg))
                                              .toArray(String[]::new);
             // Compile
-            Main.Result result = new Main("javac", printWriter).compile(passThroughArgs, context);
+            Result result = new Main("javac", printWriter).compile(passThroughArgs, context);
 
             // Process compiler output (which is always errors)
             printWriter.flush();
@@ -128,7 +129,7 @@
                     throw new UncheckedIOException(es);
                 }
             }
-            return result.exitCode;
+            return result;
 
         } else {
             // Load the prev build state database.
@@ -166,7 +167,7 @@
 
                 if (sources.isEmpty()) {
                     Log.error("Found nothing to compile!");
-                    return RC_FATAL;
+                    return Result.ERROR;
                 }
 
 
@@ -292,15 +293,15 @@
                     javac_state.removeSuperfluousArtifacts(recently_compiled);
                 }
 
-                return rc[0] ? RC_OK : RC_FATAL;
+                return rc[0] ? Result.OK : Result.ERROR;
             } catch (ProblemException e) {
                 // For instance make file list mismatch.
                 Log.error(e.getMessage());
                 Log.debug(e);
-                return RC_FATAL;
+                return Result.ERROR;
             } catch (Exception e) {
                 Log.error(e);
-                return RC_FATAL;
+                return Result.ERROR;
             }
         }
     }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Option.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Option.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, 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
@@ -151,6 +151,7 @@
             // Construct transformer
             try {
                 Class<?> trCls = Class.forName(classname);
+                @SuppressWarnings("deprecation")
                 Transformer transformer = (Transformer) trCls.newInstance();
                 transformer.setExtra(extra);
                 helper.addTransformer(suffix, transformer);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/CompilationSubResult.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/CompilationSubResult.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, 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,6 +31,7 @@
 import java.util.Map;
 import java.util.Set;
 
+import com.sun.tools.javac.main.Main.Result;
 import com.sun.tools.sjavac.pubapi.PubApi;
 
 /**
@@ -44,10 +45,7 @@
 
     static final long serialVersionUID = 46739181113L;
 
-    // Return code constants
-    public final static int ERROR_FATAL = -1;
-
-    public int returnCode;
+    public Result result;
     public Map<String, Set<URI>> packageArtifacts = new HashMap<>();
     public Map<String, Map<String, Set<String>>> packageDependencies = new HashMap<>();
     public Map<String, Map<String, Set<String>>> packageCpDependencies = new HashMap<>();
@@ -56,11 +54,11 @@
     public String stdout = "";
     public String stderr = "";
 
-    public CompilationSubResult(int returnCode) {
-        this.returnCode = returnCode;
+    public CompilationSubResult(Result result) {
+        this.result = result;
     }
 
-    public void setReturnCode(int returnCode) {
-        this.returnCode = returnCode;
+    public void setResult(Result result) {
+        this.result = result;
     }
 }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/IdleResetSjavac.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/IdleResetSjavac.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,11 +25,9 @@
 
 package com.sun.tools.sjavac.server;
 
+import com.sun.tools.javac.main.Main.Result;
 import com.sun.tools.sjavac.Log;
 
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Writer;
 import java.util.Timer;
 import java.util.TimerTask;
 
@@ -66,7 +64,7 @@
     }
 
     @Override
-    public int compile(String[] args) {
+    public Result compile(String[] args) {
         startCall();
         try {
             return delegate.compile(args);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/RequestHandler.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/RequestHandler.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,6 +25,7 @@
 
 package com.sun.tools.sjavac.server;
 
+import com.sun.tools.javac.main.Main;
 import com.sun.tools.sjavac.Log;
 import com.sun.tools.sjavac.Util;
 
@@ -100,10 +101,10 @@
             checkInternalErrorLog();
 
             // Perform compilation
-            int rc = sjavac.compile(args);
+            Main.Result rc = sjavac.compile(args);
 
             // Send return code back to client
-            out.println(LINE_TYPE_RC + ":" + rc);
+            out.println(LINE_TYPE_RC + ":" + rc.name());
 
             // Check for internal errors again.
             checkInternalErrorLog();
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/ServerMain.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/ServerMain.java	Thu Apr 28 23:08:16 2016 -0700
@@ -32,6 +32,8 @@
 import java.io.PrintStream;
 import java.lang.Thread.UncaughtExceptionHandler;
 
+import com.sun.tools.javac.main.Main;
+import com.sun.tools.javac.main.Main.Result;
 import com.sun.tools.sjavac.Log;
 import com.sun.tools.sjavac.Log.Level;
 import com.sun.tools.sjavac.server.log.LazyInitFileLog;
@@ -75,7 +77,7 @@
         // Any options other than --startserver?
         if (args.length > 1) {
             Log.error("When spawning a background server, only a single --startserver argument is allowed.");
-            return 1;
+            return Result.CMDERR.exitCode;
         }
 
         int exitCode;
@@ -84,7 +86,7 @@
             exitCode = server.startServer();
         } catch (IOException | InterruptedException ex) {
             ex.printStackTrace();
-            exitCode = -1;
+            exitCode = Result.ERROR.exitCode;
         }
 
         return exitCode;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/Sjavac.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/Sjavac.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,6 +25,8 @@
 
 package com.sun.tools.sjavac.server;
 
+import com.sun.tools.javac.main.Main.Result;
+
 import java.io.Writer;
 
 
@@ -38,10 +40,6 @@
  *  deletion without notice.</b>
  */
 public interface Sjavac {
-
-    final static int RC_FATAL = -1;
-    final static int RC_OK = 0;
-
-    int compile(String[] args);
+    Result compile(String[] args);
     void shutdown();
 }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/SjavacServer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/SjavacServer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -40,6 +40,8 @@
 import java.util.Random;
 import java.util.concurrent.atomic.AtomicBoolean;
 
+import com.sun.tools.javac.main.Main;
+import com.sun.tools.javac.main.Main.Result;
 import com.sun.tools.sjavac.Log;
 import com.sun.tools.sjavac.Util;
 import com.sun.tools.sjavac.client.PortFileInaccessibleException;
@@ -167,7 +169,7 @@
             if (portFile.containsPortInfo()) {
                 Log.debug("Javac server not started because portfile exists!");
                 portFile.unlock();
-                return -1;
+                return Result.ERROR.exitCode;
             }
 
             //           .-----------.   .--------.   .------.
@@ -221,7 +223,7 @@
         // Shut down
         sjavac.shutdown();
 
-        return 0;
+        return Result.OK.exitCode;
     }
 
     @Override
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties	Thu Apr 28 23:08:16 2016 -0700
@@ -1,4 +1,4 @@
-doclet.build_version=Standard Doclet version {0}
+doclet.build_version=Standard Doclet (Old) version {0}
 doclet.Contents=Contents
 doclet.Overview=Overview
 doclet.Window_Overview=Overview List
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java	Thu Apr 28 23:08:16 2016 -0700
@@ -242,7 +242,6 @@
             }
 
             customTagClass = tagClassLoader.loadClass(classname);
-            ensureReadable(customTagClass);
 
             Method meth = customTagClass.getMethod("register",
                                                    Map.class);
@@ -270,27 +269,6 @@
     }
 
     /**
-     * Ensures that the module of the given class is readable to this
-     * module.
-     * @param targetClass class in module to be made readable
-     */
-    private void ensureReadable(Class<?> targetClass) {
-        try {
-            Method getModuleMethod = Class.class.getMethod("getModule");
-            Object thisModule = getModuleMethod.invoke(this.getClass());
-            Object targetModule = getModuleMethod.invoke(targetClass);
-
-            Class<?> moduleClass = getModuleMethod.getReturnType();
-            Method addReadsMethod = moduleClass.getMethod("addReads", moduleClass);
-            addReadsMethod.invoke(thisModule, targetModule);
-        } catch (NoSuchMethodException e) {
-            // ignore
-        } catch (Exception e) {
-            throw new InternalError(e);
-        }
-    }
-
-    /**
      * Export javadoc internal API to the unnamed module for a classloader.
      * This is to support continued use of existing non-standard doclets that
      * use the internal toolkit API and related classes.
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/DocletInvoker.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/DocletInvoker.java	Thu Apr 28 23:08:16 2016 -0700
@@ -102,7 +102,6 @@
         this.apiMode = apiMode;
         this.exportInternalAPI = exportInternalAPI; // for backdoor use by standard doclet for taglets
 
-        ensureReadable(docletClass);
         // this may not be soon enough if the class has already been loaded
         if (exportInternalAPI) {
             exportInternalAPI(docletClass.getClassLoader());
@@ -149,8 +148,6 @@
             messager.exit();
         }
         docletClass = dc;
-
-        ensureReadable(docletClass);
     }
 
     /*
@@ -362,27 +359,6 @@
     }
 
     /**
-     * Ensures that the module of the given class is readable to this
-     * module.
-     * @param targetClass class in module to be made readable
-     */
-    private void ensureReadable(Class<?> targetClass) {
-        try {
-            Method getModuleMethod = Class.class.getMethod("getModule");
-            Object thisModule = getModuleMethod.invoke(this.getClass());
-            Object targetModule = getModuleMethod.invoke(targetClass);
-
-            Class<?> moduleClass = getModuleMethod.getReturnType();
-            Method addReadsMethod = moduleClass.getMethod("addReads", moduleClass);
-            addReadsMethod.invoke(thisModule, targetModule);
-        } catch (NoSuchMethodException e) {
-            // ignore
-        } catch (Exception e) {
-            throw new InternalError(e);
-        }
-    }
-
-    /**
      * Export javadoc internal API to the unnamed module for a classloader.
      * This is to support continued use of existing non-standard doclets that
      * use the internal toolkit API and related classes.
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -168,6 +168,21 @@
     }
 
     /**
+     * {@inheritDoc}
+     */
+    public void addModuleDescription(Content moduleContentTree) {
+        if (!utils.getBody(mdle).isEmpty()) {
+            Content tree = configuration.allowTag(HtmlTag.SECTION) ? HtmlTree.SECTION() : moduleContentTree;
+            tree.addContent(HtmlConstants.START_OF_MODULE_DESCRIPTION);
+            tree.addContent(getMarkerAnchor(SectionName.MODULE_DESCRIPTION));
+            addInlineComment(mdle, tree);
+            if (configuration.allowTag(HtmlTag.SECTION)) {
+                moduleContentTree.addContent(tree);
+            }
+        }
+    }
+
+    /**
      * Adds list of packages in the package summary table. Generate link to each package.
      *
      * @param packages Packages to which link is to be generated
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SectionName.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SectionName.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, 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
@@ -53,6 +53,7 @@
     METHOD_DETAIL("method.detail"),
     METHODS_INHERITANCE("methods.inherited.from.class."),
     METHOD_SUMMARY("method.summary"),
+    MODULE_DESCRIPTION("module.description"),
     NAVBAR_BOTTOM("navbar.bottom"),
     NAVBAR_BOTTOM_FIRSTROW("navbar.bottom.firstrow"),
     NAVBAR_TOP("navbar.top"),
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlConstants.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlConstants.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, 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
@@ -64,6 +64,12 @@
             new Comment("======== END OF BOTTOM NAVBAR =======");
 
     /**
+     * Marker to identify start of module description.
+     */
+    public static final Content START_OF_MODULE_DESCRIPTION =
+            new Comment("============ MODULE DESCRIPTION ===========");
+
+    /**
      * Marker to identify start of class data.
      */
     public static final Content START_OF_CLASS_DATA =
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties	Thu Apr 28 23:08:16 2016 -0700
@@ -1,4 +1,4 @@
-doclet.build_version=Standard Doclet (Next) version {0}
+doclet.build_version=Standard Doclet version {0}
 doclet.Contents=Contents
 doclet.Overview=Overview
 doclet.Window_Overview=Overview List
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/ModuleSummaryWriter.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/ModuleSummaryWriter.java	Thu Apr 28 23:08:16 2016 -0700
@@ -74,6 +74,14 @@
     public abstract Content getSummaryTree(Content summaryContentTree);
 
     /**
+     * Adds the module description.
+     *
+     * @param moduleContentTree the content tree to which the module description
+     *                           will be added
+     */
+    public abstract void addModuleDescription(Content moduleContentTree);
+
+    /**
      * Adds the table of packages to the documentation tree.
      *
      * @param packages the set of packages that should be added.
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/ModuleSummaryBuilder.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/ModuleSummaryBuilder.java	Thu Apr 28 23:08:16 2016 -0700
@@ -185,4 +185,17 @@
                     packageTableSummary, summaryContentTree);
         }
     }
+
+    /**
+     * Build the description for the module.
+     *
+     * @param node the XML element that specifies which components to document
+     * @param moduleContentTree the tree to which the module description will
+     *                           be added
+     */
+    public void buildModuleDescription(XMLNode node, Content moduleContentTree) {
+        if (!configuration.nocomment) {
+            moduleWriter.addModuleDescription(moduleContentTree);
+        }
+    }
 }
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclet.xml	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclet.xml	Thu Apr 28 23:08:16 2016 -0700
@@ -30,6 +30,7 @@
 
     <ModuleDoc>
         <Content>
+            <ModuleDescription/>
             <Summary>
                 <PackageSummary/>
             </Summary>
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletManager.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletManager.java	Thu Apr 28 23:08:16 2016 -0700
@@ -246,7 +246,7 @@
             }
             tagClassLoader = fileManager.getClassLoader(TAGLET_PATH);
             Class<?> customTagClass = tagClassLoader.loadClass(classname);
-            ensureReadable(customTagClass);
+            @SuppressWarnings("deprecation")
             Object instance = customTagClass.newInstance();
             Taglet newLegacy = new UserTaglet((jdk.javadoc.doclet.taglet.Taglet)instance);
             String tname = newLegacy.getName();
@@ -262,27 +262,6 @@
     }
 
     /**
-     * Ensures that the module of the given class is readable to this
-     * module.
-     * @param targetClass class in module to be made readable
-     */
-    private void ensureReadable(Class<?> targetClass) {
-        try {
-            Method getModuleMethod = Class.class.getMethod("getModule");
-            Object thisModule = getModuleMethod.invoke(this.getClass());
-            Object targetModule = getModuleMethod.invoke(targetClass);
-
-            Class<?> moduleClass = getModuleMethod.getReturnType();
-            Method addReadsMethod = moduleClass.getMethod("addReads", moduleClass);
-            addReadsMethod.invoke(thisModule, targetModule);
-        } catch (NoSuchMethodException e) {
-            // ignore
-        } catch (Exception e) {
-            throw new InternalError(e.toString());
-        }
-    }
-
-    /**
      * Add a new <code>SimpleTaglet</code>.  If this tag already exists
      * and the header passed as an argument is null, move tag to the back of the
      * list. If this tag already exists and the header passed as an argument is
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/IndexBuilder.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/IndexBuilder.java	Thu Apr 28 23:08:16 2016 -0700
@@ -73,6 +73,7 @@
 
     private final Configuration configuration;
     private final Utils utils;
+    private final Comparator<Element> comparator;
 
     /**
      * Constructor. Build the index map.
@@ -106,6 +107,9 @@
         this.classesOnly = classesOnly;
         this.javafx = configuration.javafx;
         this.indexmap = new TreeMap<>();
+        comparator = classesOnly
+                ? utils.makeAllClassesComparator()
+                : utils.makeIndexUseComparator();
         buildIndexMap(configuration.root);
     }
 
@@ -175,7 +179,7 @@
                           Character.toUpperCase(name.charAt(0));
                 Character unicode = ch;
                 SortedSet<Element> list = indexmap.computeIfAbsent(unicode,
-                        c -> new TreeSet<>(utils.makeIndexUseComparator()));
+                        c -> new TreeSet<>(comparator));
                 list.add(element);
             }
         }
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1628,6 +1628,7 @@
 
     /**
      * Comparator for ModuleElements, simply compares the fully qualified names
+     * @return a Comparator
      */
     public Comparator<Element> makeModuleComparator() {
         return new Utils.ElementComparator<Element>() {
@@ -1639,7 +1640,28 @@
     }
 
     /**
-     * Comparator for PackageElements, simply compares the fully qualified names
+     * Returns a Comparator for all classes, compares the simple names of
+     * TypeElement, if equal then the fully qualified names.
+     *
+     * @return Comparator
+     */
+    public Comparator<Element> makeAllClassesComparator() {
+        return new Utils.ElementComparator<Element>() {
+            @Override
+            public int compare(Element e1, Element e2) {
+                int result =  compareNames(e1, e2);
+                if (result == 0)
+                    result =  compareFullyQualifiedNames(e1, e2);
+
+                return result;
+            }
+        };
+    }
+
+    /**
+     * Returns a Comparator for packages, by comparing the fully qualified names.
+     *
+     * @return a Comparator
      */
     public Comparator<Element> makePackageComparator() {
         return new Utils.ElementComparator<Element>() {
@@ -1650,6 +1672,10 @@
         };
     }
 
+    /**
+     * Returns a Comparator for SerialFieldTree.
+     * @return a Comparator
+     */
     public Comparator<SerialFieldTree> makeSerialFieldTreeComparator() {
         return (SerialFieldTree o1, SerialFieldTree o2) -> {
             String s1 = o1.getName().toString();
@@ -1659,18 +1685,19 @@
     }
 
     /**
-     * Comparator for General Purpose
-     * @return a ElementComparatorForClassUse
+     * Returns a general purpose comparator.
+     * @return a Comparator
      */
     public Comparator<Element> makeGeneralPurposeComparator() {
         return makeClassUseComparator();
     }
 
     /**
-     * A Comparator for Overrides and Implements use used on ExecutableElements
-     * compares the name first, then compares the SimpleName of the enclosing
-     * class and the FullyQualifiedName of the enclosing class.
-     * @return
+     * Returns a Comparator for overrides and implements,
+     * used primarily on methods, compares the name first,
+     * then compares the simple names of the enclosing
+     * TypeElement and the fully qualified name of the enclosing TypeElement.
+     * @return a Comparator
      */
     public Comparator<Element> makeOverrideUseComparator() {
         return new Utils.ElementComparator<Element>() {
@@ -1696,21 +1723,24 @@
     }
 
     /**
-     * A comparator for index file presentations, and are sorted as follows:
+     * Returns a Comparator for index file presentations, and are sorted as follows.
+     *  If comparing packages then simply compare the qualified names, otherwise
      *  1. sort on simple names of entities
      *  2. if equal, then compare the ElementKind ex: Package, Interface etc.
      *  3a. if equal and if the type is of ExecutableElement(Constructor, Methods),
      *      a case insensitive comparison of parameter the type signatures
      *  3b. if equal, case sensitive comparison of the type signatures
      *  4. finally, if equal, compare the FQNs of the entities
+     * Iff comparing packages then simply sort on qualified names.
      * @return a comparator for index file use
      */
     public Comparator<Element> makeIndexUseComparator() {
         return new Utils.ElementComparator<Element>() {
             /**
-             * Compare two given elements, first sort on names, then on the kinds,
-             * then on the parameters only if the type is an instance of ExecutableElement,
-             * the parameters are compared and finally the fully qualified names.
+             * Compare two given elements, if comparing two packages, return the
+             * comparison of FullyQualifiedName, first sort on names, then on the
+             * kinds, then on the parameters only if the type is an ExecutableElement,
+             * the parameters are compared and finally the qualified names.
              *
              * @param e1 - an element.
              * @param e2 - an element.
@@ -1719,10 +1749,7 @@
              */
             @Override
             public int compare(Element e1, Element e2) {
-                int result = compareElementTypeKinds(e1, e2);
-                if (result != 0) {
-                    return result;
-                }
+                int result = 0;
                 if (isPackage(e1) && isPackage(e2)) {
                     return compareFullyQualifiedNames(e1, e2);
                 }
@@ -1730,6 +1757,10 @@
                 if (result != 0) {
                     return result;
                 }
+                result = compareElementTypeKinds(e1, e2);
+                if (result != 0) {
+                    return result;
+                }
                 if (hasParameters(e1)) {
                     List<? extends VariableElement> parameters1 = ((ExecutableElement)e1).getParameters();
                     List<? extends VariableElement> parameters2 = ((ExecutableElement)e2).getParameters();
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/DocEnv.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/DocEnv.java	Thu Apr 28 23:08:16 2016 -0700
@@ -550,7 +550,7 @@
         // Messager should be replaced by a more general
         // compilation environment.  This can probably
         // subsume DocEnv as well.
-        messager.exit();
+        throw new Messager.ExitJavadoc();
     }
 
     /**
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Main.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Main.java	Thu Apr 28 23:08:16 2016 -0700
@@ -59,13 +59,6 @@
      * @return The return code.
      */
     public static int execute(String... args) {
-        // NOTE: the following should be removed when the old doclet
-        // is removed.
-        if (args != null && args.length > 0 && "-Xold".equals(args[0])) {
-            String[] nargs = new String[args.length - 1];
-            System.arraycopy(args, 1, nargs, 0, nargs.length);
-            return com.sun.tools.javadoc.Main.execute(nargs);
-        }
         Start jdoc = new Start();
         return jdoc.begin(args);
     }
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Messager.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Messager.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -139,7 +139,7 @@
         }
     }
 
-    public class ExitJavadoc extends Error {
+    public static class ExitJavadoc extends Error {
         private static final long serialVersionUID = 0;
     }
 
@@ -416,15 +416,6 @@
         }
     }
 
-    /**
-     * Force program exit, e.g., from a fatal error.
-     * <p>
-     * TODO: This method does not really belong here.
-     */
-    public void exit() {
-        throw new ExitJavadoc();
-    }
-
     private void report(DiagnosticType type, String pos, String msg) {
         switch (type) {
             case ERROR:
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java	Thu Apr 28 23:08:16 2016 -0700
@@ -66,6 +66,7 @@
 import jdk.javadoc.doclet.DocletEnvironment;
 
 import static com.sun.tools.javac.main.Option.*;
+
 /**
  * Main program of Javadoc.
  * Previously named "Main".
@@ -79,6 +80,12 @@
  * @author Neal Gafter (rewrite)
  */
 public class Start extends ToolOption.Helper {
+
+    private static final Class<?> OldStdDoclet =
+            com.sun.tools.doclets.standard.Standard.class;
+
+    private static final Class<?> StdDoclet =
+            jdk.javadoc.internal.doclets.standard.Standard.class;
     /** Context for this invocation. */
     private final Context context;
 
@@ -193,18 +200,26 @@
         if (foot != null)
             messager.notice(foot);
 
-        if (exit) exit();
+        if (exit)
+            throw new Messager.ExitJavadoc();
     }
 
+
     /**
-     * Exit
-     */
-    private void exit() {
-        messager.exit();
-    }
-
-    /**
-     * Main program - external wrapper
+     * Main program - external wrapper. In order to maintain backward
+     * CLI  compatibility, we dispatch to the old tool or the old doclet's
+     * Start mechanism, based on the options present on the command line
+     * with the following precedence:
+     *   1. presence of -Xold, dispatch to old tool
+     *   2. doclet variant, if old, dispatch to old Start
+     *   3. taglet variant, if old, dispatch to old Start
+     *
+     * Thus the presence of -Xold switches the tool, soon after command files
+     * if any, are expanded, this is performed here, noting that the messager
+     * is available at this point in time.
+     * The doclet/taglet tests are performed in the begin method, further on,
+     * this is to minimize argument processing and most importantly the impact
+     * of class loader creation, needed to detect the doclet/taglet class variants.
      */
     int begin(String... argv) {
         // Preprocess @file arguments
@@ -212,14 +227,18 @@
             argv = CommandLine.parse(argv);
         } catch (FileNotFoundException e) {
             messager.error("main.cant.read", e.getMessage());
-            exit();
+            throw new Messager.ExitJavadoc();
         } catch (IOException e) {
             e.printStackTrace(System.err);
-            exit();
+            throw new Messager.ExitJavadoc();
         }
 
-        List<String> argList = Arrays.asList(argv);
-        boolean ok = begin(argList, Collections.<JavaFileObject> emptySet());
+        if (argv.length > 0 && "-Xold".equals(argv[0])) {
+            messager.warning("main.legacy_api");
+            String[] nargv = Arrays.copyOfRange(argv, 1, argv.length);
+            return com.sun.tools.javadoc.Main.execute(nargv);
+        }
+        boolean ok = begin(Arrays.asList(argv), Collections.<JavaFileObject> emptySet());
         return ok ? 0 : 1;
     }
 
@@ -231,11 +250,11 @@
         List<String> opts = new ArrayList<>();
         for (String opt: options)
             opts.add(opt);
+
         return begin(opts, fileObjects);
     }
 
     private boolean begin(List<String> options, Iterable<? extends JavaFileObject> fileObjects) {
-
         fileManager = context.get(JavaFileManager.class);
         if (fileManager == null) {
             JavacFileManager.preRegister(context);
@@ -244,20 +263,21 @@
                 ((BaseFileManager) fileManager).autoClose = true;
             }
         }
-        // locale and doclet needs to be determined first
+        // locale, doclet and maybe taglet, needs to be determined first
         docletClass = preProcess(fileManager, options);
-
         if (jdk.javadoc.doclet.Doclet.class.isAssignableFrom(docletClass)) {
             // no need to dispatch to old, safe to init now
             initMessager();
             messager.setLocale(locale);
             try {
-                doclet = (Doclet) docletClass.newInstance();
+                @SuppressWarnings("deprecation")
+                Object o = docletClass.newInstance();
+                doclet = (Doclet) o;
             } catch (InstantiationException | IllegalAccessException exc) {
                 exc.printStackTrace();
                 if (!apiMode) {
                     error("main.could_not_instantiate_class", docletClass);
-                    messager.exit();
+                    throw new Messager.ExitJavadoc();
                 }
                 throw new ClientCodeException(exc);
             }
@@ -267,6 +287,7 @@
                         = new com.sun.tools.javadoc.Start(context);
                 return ostart.begin(docletClass, options, fileObjects);
             }
+            warn("main.legacy_api");
             String[] array = options.toArray(new String[options.size()]);
             return com.sun.tools.javadoc.Main.execute(array) == 0;
         }
@@ -312,27 +333,6 @@
     }
 
     /**
-     * Ensures that the module of the given class is readable to this
-     * module.
-     * @param targetClass class in module to be made readable
-     */
-    private void ensureReadable(Class<?> targetClass) {
-        try {
-            Method getModuleMethod = Class.class.getMethod("getModule");
-            Object thisModule = getModuleMethod.invoke(this.getClass());
-            Object targetModule = getModuleMethod.invoke(targetClass);
-
-            Class<?> moduleClass = getModuleMethod.getReturnType();
-            Method addReadsMethod = moduleClass.getMethod("addReads", moduleClass);
-            addReadsMethod.invoke(thisModule, targetModule);
-        } catch (NoSuchMethodException e) {
-            // ignore
-        } catch (Exception e) {
-            throw new InternalError(e);
-        }
-    }
-
-    /**
      * Main program - internal
      */
     private boolean parseAndExecute(List<String> argList,
@@ -459,6 +459,11 @@
         String userDocletPath = null;
         String userDocletName = null;
 
+        // taglet specifying arguments, since tagletpath is a doclet
+        // functionality, assume they are repeated and inspect all.
+        List<File> userTagletPath = new ArrayList<>();
+        List<String> userTagletNames = new ArrayList<>();
+
         // Step 1: loop through the args, set locale early on, if found.
         for (int i = 0 ; i < argv.size() ; i++) {
             String arg = argv.get(i);
@@ -470,7 +475,7 @@
                 oneArg(argv, i++);
                 if (userDocletName != null) {
                     usageError("main.more_than_one_doclet_specified_0_and_1",
-                               userDocletName, argv.get(i));
+                            userDocletName, argv.get(i));
                 }
                 if (docletName != null) {
                     usageError("main.more_than_one_doclet_specified_0_and_1",
@@ -484,13 +489,20 @@
                 } else {
                     userDocletPath += File.pathSeparator + argv.get(i);
                 }
+            } else if ("-taglet".equals(arg)) {
+                userTagletNames.add(argv.get(i + 1));
+            } else if ("-tagletpath".equals(arg)) {
+                for (String pathname : argv.get(i + 1).split(File.pathSeparator)) {
+                    userTagletPath.add(new File(pathname));
+                }
             }
         }
-        // Step 2: a doclet has already been provided,
-        // nothing more to do.
+
+        // Step 2: a doclet is provided, nothing more to do.
         if (docletClass != null) {
             return docletClass;
         }
+
         // Step 3: doclet name specified ? if so find a ClassLoader,
         // and load it.
         if (userDocletName != null) {
@@ -506,38 +518,78 @@
                     try {
                         ((StandardJavaFileManager)fileManager).setLocation(DOCLET_PATH, paths);
                     } catch (IOException ioe) {
-                        panic("main.doclet_no_classloader_found", ioe);
-                        return null; // keep compiler happy
+                        error("main.doclet_could_not_set_location", paths);
+                        throw new Messager.ExitJavadoc();
                     }
                 }
                 cl = fileManager.getClassLoader(DOCLET_PATH);
                 if (cl == null) {
                     // despite doclet specified on cmdline no classloader found!
-                    panic("main.doclet_no_classloader_found", userDocletName);
-                    return null; // keep compiler happy
-                }
-                try {
-                    Class<?> klass = cl.loadClass(userDocletName);
-                    ensureReadable(klass);
-                    return klass;
-                } catch (ClassNotFoundException cnfe) {
-                    panic("main.doclet_class_not_found", userDocletName);
-                    return null; // keep compiler happy
+                    error("main.doclet_no_classloader_found", userDocletName);
+                    throw new Messager.ExitJavadoc();
                 }
             }
+            try {
+                Class<?> klass = cl.loadClass(userDocletName);
+                return klass;
+            } catch (ClassNotFoundException cnfe) {
+                error("main.doclet_class_not_found", userDocletName);
+                throw new Messager.ExitJavadoc();
+            }
         }
-        // Step 4: we have a doclet, try loading it, otherwise
-        // return back the standard doclet
+
+        // Step 4: we have a doclet, try loading it
         if (docletName != null) {
             try {
                 return Class.forName(docletName, true, getClass().getClassLoader());
             } catch (ClassNotFoundException cnfe) {
-                panic("main.doclet_class_not_found", userDocletName);
-                return null; // happy compiler, should not happen
+                error("main.doclet_class_not_found", userDocletName);
+                throw new Messager.ExitJavadoc();
             }
-        } else {
-            return jdk.javadoc.internal.doclets.standard.Standard.class;
+        }
+
+        // Step 5: we don't have a doclet specified, do we have taglets ?
+        if (!userTagletNames.isEmpty() && hasOldTaglet(userTagletNames, userTagletPath)) {
+            // found a bogey, return the old doclet
+            return OldStdDoclet;
         }
+
+        // finally
+        return StdDoclet;
+    }
+
+    /*
+     * This method returns true iff it finds a legacy taglet, but for
+     * all other conditions including errors it returns false, allowing
+     * nature to take its own course.
+     */
+    private boolean hasOldTaglet(List<String> tagletNames, List<File> tagletPaths) {
+        if (!fileManager.hasLocation(TAGLET_PATH)) {
+            try {
+                ((StandardJavaFileManager) fileManager).setLocation(TAGLET_PATH, tagletPaths);
+            } catch (IOException ioe) {
+                error("main.doclet_could_not_set_location", tagletPaths);
+                throw new Messager.ExitJavadoc();
+            }
+        }
+        ClassLoader cl = fileManager.getClassLoader(TAGLET_PATH);
+        if (cl == null) {
+            // no classloader found!
+            error("main.doclet_no_classloader_found", tagletNames.get(0));
+            throw new Messager.ExitJavadoc();
+        }
+        for (String tagletName : tagletNames) {
+            try {
+                Class<?> klass = cl.loadClass(tagletName);
+                if (com.sun.tools.doclets.Taglet.class.isAssignableFrom(klass)) {
+                    return true;
+                }
+            } catch (ClassNotFoundException cnfe) {
+                error("main.doclet_class_not_found", tagletName);
+                throw new Messager.ExitJavadoc();
+            }
+        }
+        return false;
     }
 
     private void parseArgs(List<String> args, List<String> javaNames) {
@@ -595,14 +647,12 @@
         usage(true);
     }
 
-    // a terminal call, will not return
-    void panic(String key, Object... args) {
-        error(key, args);
-        messager.exit();
+    void error(String key, Object... args) {
+        messager.error(key, args);
     }
 
-    void error(String key, Object... args) {
-        messager.error(key, args);
+    void warn(String key, Object... args)  {
+        messager.warning(key, args);
     }
 
     /**
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties	Thu Apr 28 23:08:16 2016 -0700
@@ -73,7 +73,8 @@
 \                                   given module. <other-module> may be ALL-UNNAMED to require\n\
 \                                   the unnamed module.\n\
 \  -Xmodule:<module-name>           Specify a module to which the classes being compiled belong.\n\
-\  -Xpatch:<path>                   Specify location of module class files to patch\n  
+\  -Xpatch:<path>                   Specify location of module class files to patch\n\
+\  -Xold                            Invoke the legacy javadoc tool\n
 
 main.Xusage.foot=\
 These options are non-standard and subject to change without notice.
@@ -96,6 +97,7 @@
 such as -J-Xmx32m.
 main.done_in=[done in {0} ms]
 main.more_than_one_doclet_specified_0_and_1=More than one doclet specified ({0} and {1}).
+main.doclet_could_not_set_location=Could not set location for {0}
 main.doclet_no_classloader_found=Could not obtain classloader to load {0}
 main.could_not_instantiate_class=Could not instantiate class {0}
 main.doclet_class_not_found=Cannot find doclet class {0}
@@ -109,10 +111,15 @@
 main.unsupported.release.version=release version {0} not supported
 main.release.not.standard.file.manager=-release option specified, but the provided JavaFileManager is not a StandardJavaFileManager.
 main.unknown.error=an unknown error has occurred
+main.legacy_api=The old Doclet and Taglet APIs in the packages\n\
+    com.sun.javadoc, com.sun.tools.doclets and their implementations\n\
+    are planned to be removed in a future JDK release. These\n\
+    components have been superseded by the new APIs in jdk.javadoc.doclet.\n\
+    Users are strongly recommended to migrate to the new APIs.\n
+
 javadoc.class_not_found=Class {0} not found.
 javadoc.error=error
 javadoc.warning=warning
-
 javadoc.error.msg={0}: error - {1}
 javadoc.warning.msg={0}: warning - {1}
 javadoc.note.msg = {1}
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/remote/RemoteAgent.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/remote/RemoteAgent.java	Thu Apr 28 23:08:16 2016 -0700
@@ -113,7 +113,6 @@
                     }
                     Method doitMethod;
                     try {
-                        this.getClass().getModule().addReads(klass.getModule());
                         this.getClass().getModule().addExports(RemoteResolutionException.class.getPackage().getName(), klass.getModule());
                         doitMethod = klass.getDeclaredMethod(DOIT_METHOD_NAME, new Class<?>[0]);
                         doitMethod.setAccessible(true);
@@ -184,7 +183,6 @@
                         break;
                     }
                     try {
-                        this.getClass().getModule().addReads(klass.getModule());
                         Field var = klass.getDeclaredField(varname);
                         var.setAccessible(true);
                         Object res = var.get(null);
@@ -264,9 +262,14 @@
         }
     }
 
+    /**
+     * Expunge internal info from string
+     * @param s string to process
+     * @return string the display, JShell package and wrapper class names removed
+     */
     static String expunge(String s) {
         StringBuilder sb = new StringBuilder();
-        for (String comp : prefixPattern.split(s)) {
+        for (String comp : PREFIX_PATTERN.split(s)) {
             sb.append(comp);
         }
         return sb.toString();
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/remote/RemoteCodes.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/remote/RemoteCodes.java	Thu Apr 28 23:08:16 2016 -0700
@@ -47,8 +47,12 @@
     public static final int RESULT_CORRALLED = 103;
     public static final int RESULT_KILLED    = 104;
 
+    // String constants
+    public static final String REPL_PACKAGE = "REPL";
+    public static final String REPL_CLASS_PREFIX = "$JShell$";
     public static final String DOIT_METHOD_NAME = "do_it$";
-    public static final String replClass = "\\$REPL(?<num>\\d+)[A-Z]*";
-    public static final Pattern prefixPattern = Pattern.compile("(REPL\\.)?" + replClass + "[\\$\\.]?");
-
+    public static final Pattern PREFIX_PATTERN = Pattern.compile(
+            "(" + REPL_PACKAGE + "\\.)?" +
+            "(?<class>" + Pattern.quote(REPL_CLASS_PREFIX) +
+            "\\w+" + ")" + "[\\$\\.]?");
 }
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ArgTokenizer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ArgTokenizer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -35,6 +35,7 @@
 class ArgTokenizer {
 
     private final String str;
+    private final String prefix;
     private final int length;
     private int next = 0;
     private char buf[] = new char[20];
@@ -49,7 +50,12 @@
     private boolean isQuoted = false;
 
     ArgTokenizer(String arg) {
+        this("", arg);
+    }
+
+    ArgTokenizer(String prefix, String arg) {
         this.str = arg;
+        this.prefix = prefix;
         this.length = arg.length();
         quoteChar('"');
         quoteChar('\'');
@@ -88,7 +94,7 @@
     }
 
     String whole() {
-        return str;
+        return prefix + str;
     }
 
     void mark() {
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java	Thu Apr 28 23:08:16 2016 -0700
@@ -95,20 +95,20 @@
         return mode.getContinuationPrompt(nextId);
     }
 
-    public boolean setFeedback(JShellTool tool, ArgTokenizer at) {
-        return new Setter(tool, at).setFeedback();
+    public boolean setFeedback(MessageHandler messageHandler, ArgTokenizer at) {
+        return new Setter(messageHandler, at).setFeedback();
     }
 
-    public boolean setFormat(JShellTool tool, ArgTokenizer at) {
-        return new Setter(tool, at).setFormat();
+    public boolean setFormat(MessageHandler messageHandler, ArgTokenizer at) {
+        return new Setter(messageHandler, at).setFormat();
     }
 
-    public boolean setNewMode(JShellTool tool, ArgTokenizer at) {
-        return new Setter(tool, at).setNewMode();
+    public boolean setNewMode(MessageHandler messageHandler, ArgTokenizer at) {
+        return new Setter(messageHandler, at).setNewMode();
     }
 
-    public boolean setPrompt(JShellTool tool, ArgTokenizer at) {
-        return new Setter(tool, at).setPrompt();
+    public boolean setPrompt(MessageHandler messageHandler, ArgTokenizer at) {
+        return new Setter(messageHandler, at).setPrompt();
     }
 
     {
@@ -529,26 +529,26 @@
     private class Setter {
 
         private final ArgTokenizer at;
-        private final JShellTool tool;
+        private final MessageHandler messageHandler;
         boolean valid = true;
 
-        Setter(JShellTool tool, ArgTokenizer at) {
-            this.tool = tool;
+        Setter(MessageHandler messageHandler, ArgTokenizer at) {
+            this.messageHandler = messageHandler;
             this.at = at;
         }
 
         void fluff(String format, Object... args) {
-            tool.fluff(format, args);
+            messageHandler.fluff(format, args);
         }
 
-        void fluffmsg(String format, Object... args) {
-            tool.fluffmsg(format, args);
+        void fluffmsg(String messageKey, Object... args) {
+            messageHandler.fluffmsg(messageKey, args);
         }
 
         void errorat(String messageKey, Object... args) {
             Object[] a2 = Arrays.copyOf(args, args.length + 2);
-            a2[args.length] = "/set " + at.whole();
-            tool.errormsg(messageKey, a2);
+            a2[args.length] = at.whole();
+            messageHandler.errormsg(messageKey, a2);
         }
 
         // For /set prompt <mode> "<prompt>" "<continuation-prompt>"
@@ -606,6 +606,7 @@
                 fluffmsg("jshell.msg.feedback.mode", mode.name);
             } else {
                 fluffmsg("jshell.msg.see", "/help /set feedback");
+                printFeedbackModes();
             }
             return valid;
         }
@@ -671,13 +672,17 @@
                 } else {
                     errorat("jshell.err.feedback.ambiguous.mode", umode);
                 }
-                fluffmsg("jshell.msg.feedback.mode.following");
-                modeMap.keySet().stream()
-                        .forEach(mk -> fluff("   %s", mk));
+                printFeedbackModes();
                 return null;
             }
         }
 
+        void printFeedbackModes() {
+            fluffmsg("jshell.msg.feedback.mode.following");
+            modeMap.keySet().stream()
+                    .forEach(mk -> fluff("   %s", mk));
+        }
+
         // Test if the format string is correctly
         final String nextFormat() {
             String format = at.next();
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Thu Apr 28 23:08:16 2016 -0700
@@ -108,7 +108,7 @@
  * Command line REPL tool for Java using the JShell API.
  * @author Robert Field
  */
-public class JShellTool {
+public class JShellTool implements MessageHandler {
 
     private static final String LINE_SEP = System.getProperty("line.separator");
     private static final Pattern LINEBREAK = Pattern.compile("\\R");
@@ -166,6 +166,8 @@
     private boolean regenerateOnDeath = true;
     private boolean live = false;
     private boolean feedbackInitialized = false;
+    private String initialMode = null;
+    private List<String> remoteVMOptions = new ArrayList<>();
 
     SourceCodeAnalysis analysis;
     JShell state = null;
@@ -256,7 +258,8 @@
      * @param format printf format
      * @param args printf args
      */
-    void fluff(String format, Object... args) {
+    @Override
+    public void fluff(String format, Object... args) {
         if (feedback.shouldDisplayCommandFluff() && interactive()) {
             hard(format, args);
         }
@@ -362,7 +365,8 @@
      * @param key the resource key
      * @param args
      */
-    void errormsg(String key, Object... args) {
+    @Override
+    public void errormsg(String key, Object... args) {
         cmdout.println(prefix(messageFormat(key, args), feedback.getErrorPre()));
     }
 
@@ -383,7 +387,8 @@
      * @param key the resource key
      * @param args
      */
-    void fluffmsg(String key, Object... args) {
+    @Override
+    public void fluffmsg(String key, Object... args) {
         if (feedback.shouldDisplayCommandFluff() && interactive()) {
             hardmsg(key, args);
         }
@@ -512,6 +517,23 @@
                     case "-fullversion":
                         cmdout.printf("jshell %s\n", fullVersion());
                         return null;
+                    case "-feedback":
+                        if (ai.hasNext()) {
+                            initialMode = ai.next();
+                        } else {
+                            startmsg("jshell.err.opt.feedback.arg");
+                            return null;
+                        }
+                        break;
+                    case "-q":
+                        initialMode = "concise";
+                        break;
+                    case "-qq":
+                        initialMode = "silent";
+                        break;
+                    case "-v":
+                        initialMode = "verbose";
+                        break;
                     case "-startup":
                         if (cmdlineStartup != null) {
                             startmsg("jshell.err.opt.startup.conflict");
@@ -530,6 +552,10 @@
                         cmdlineStartup = "";
                         break;
                     default:
+                        if (arg.startsWith("-R")) {
+                            remoteVMOptions.add(arg.substring(2));
+                            break;
+                        }
                         startmsg("jshell.err.opt.unknown", arg);
                         printUsage();
                         return null;
@@ -567,6 +593,7 @@
                 .idGenerator((sn, i) -> (currentNameSpace == startNamespace || state.status(sn).isActive)
                         ? currentNameSpace.tid(sn)
                         : errorNamespace.tid(sn))
+                .remoteVMOptions(remoteVMOptions.toArray(new String[remoteVMOptions.size()]))
                 .build();
         shutdownSubscription = state.onShutdown((JShell deadState) -> {
             if (deadState == state) {
@@ -596,6 +623,26 @@
             start = cmdlineStartup;
         }
         startUpRun(start);
+        if (initialMode != null) {
+            MessageHandler mh = new MessageHandler() {
+                @Override
+                public void fluff(String format, Object... args) {
+                }
+
+                @Override
+                public void fluffmsg(String messageKey, Object... args) {
+                }
+
+                @Override
+                public void errormsg(String messageKey, Object... args) {
+                    startmsg(messageKey, args);
+                }
+            };
+            if (!feedback.setFeedback(mh, new ArgTokenizer("-feedback ", initialMode))) {
+                regenerateOnDeath = false;
+            }
+            initialMode = null;
+        }
         currentNameSpace = mainNamespace;
     }
     //where
@@ -1050,7 +1097,7 @@
         "format", "feedback", "newmode", "prompt", "editor", "start"};
 
     final boolean cmdSet(String arg) {
-        ArgTokenizer at = new ArgTokenizer(arg.trim());
+        ArgTokenizer at = new ArgTokenizer("/set ", arg.trim());
         String which = setSubCommand(at);
         if (which == null) {
             return false;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/MessageHandler.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016, 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 jdk.internal.jshell.tool;
+
+
+/**
+ * User message reporting support
+ *
+ * @author Robert Field
+ */
+public interface MessageHandler {
+
+    void fluff(String format, Object... args);
+
+    void fluffmsg(String messageKey, Object... args);
+
+    void errormsg(String messageKey, Object... args);
+}
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties	Thu Apr 28 23:08:16 2016 -0700
@@ -28,6 +28,7 @@
 For an introduction type: /help intro\n
 jshell.err.opt.classpath.conflict = Conflicting -classpath option.
 jshell.err.opt.classpath.arg = Argument to -classpath missing.
+jshell.err.opt.feedback.arg = Argument to -feedback missing. Mode required.
 jshell.err.opt.startup.conflict = Conflicting -startup or -nostartup option.
 jshell.err.opt.unknown = Unknown option: {0}
 
@@ -128,13 +129,23 @@
 
 help.usage = \
 Usage:   jshell <options> <load files>\n\
-where possible options include:\n\t\
-  -classpath <path>          Specify where to find user class files\n\t\
-  -cp <path>                 Specify where to find user class files\n\t\
-  -startup <file>            One run replacement for the start-up definitions\n\t\
-  -nostartup                 Do not run the start-up definitions\n\t\
-  -help                      Print a synopsis of standard options\n\t\
-  -version                   Version information\n
+where possible options include:\n\
+\    -classpath <path>    Specify where to find user class files\n\
+\    -cp <path>           Specify where to find user class files\n\
+\    -startup <file>      One run replacement for the start-up definitions\n\
+\    -nostartup           Do not run the start-up definitions\n\
+\    -feedback <mode>     Specify the initial feedback mode. The mode may be\n\
+\                         predefined (silent, concise, normal, or verbose) or\n\
+\                         previously user-defined\n\
+\    -q                   Quiet feedback.  Same as: -feedback concise\n\
+\    -qq                  Really quiet feedback.  Same as: -feedback silent\n\
+\    -v                   Verbose feedback.  Same as: -feedback verbose\n\
+\    -J<flag>             Pass <flag> directly to the runtime system.\n\
+\                         Use one -J for each runtime flag or flag argument\n\
+\    -R<flag>             Pass <flag> to the remote runtime system.\n\
+\                         Use one -R for each remote flag or flag argument\n\
+\    -help                Print this synopsis of standard options\n\
+\    -version             Version information\n
 
 help.list.summary = list the source you have typed
 help.list.args = [all|start|<name or id>]
@@ -512,7 +523,7 @@
 /set format verbose errorpre '|  '    \n\
 /set format verbose errorpost '%n'    \n\
 \n\
-/set format verbose errorline '{pre}    {err}'    \n\
+/set format verbose errorline '{post}{pre}    {err}'    \n\
 \n\
 /set format verbose action 'created' added-primary    \n\
 /set format verbose action 'modified' modified-primary    \n\
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/ClassTracker.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ClassTracker.java	Thu Apr 28 23:08:16 2016 -0700
@@ -27,6 +27,7 @@
 
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.Objects;
 import com.sun.jdi.ReferenceType;
 
 /**
@@ -82,6 +83,17 @@
             }
             return rt;
         }
+
+        @Override
+        public boolean equals(Object o) {
+            return o instanceof ClassInfo &&
+                    ((ClassInfo) o).className.equals(className);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hashCode(this.className);
+        }
     }
 
     ClassInfo classInfo(String className, byte[] bytes) {
@@ -93,5 +105,4 @@
     ClassInfo get(String className) {
         return map.get(className);
     }
-
 }
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/DeclarationSnippet.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/DeclarationSnippet.java	Thu Apr 28 23:08:16 2016 -0700
@@ -84,6 +84,6 @@
 
     @Override
     String importLine(JShell state) {
-        return "import static " + state.maps.classFullName(this) + "." + name() + ";\n";
+        return "import static " + classFullName() + "." + name() + ";\n";
     }
 }
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Diag.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Diag.java	Thu Apr 28 23:08:16 2016 -0700
@@ -36,12 +36,18 @@
     // Simplified view on compiler Diagnostic.
 
     /**
+     * In-package creation only.
+     */
+    Diag() {
+    }
+
+    /**
      * Used to signal that no position is available.
      */
     public final static long NOPOS = Diagnostic.NOPOS;
 
     /**
-     * Is this diagnostic and error (as opposed to a warning or note)
+     * Is this diagnostic an error (as opposed to a warning or note)
      * @return true if this diagnostic is an error
      */
     public abstract boolean isError();
@@ -100,10 +106,12 @@
     // *** Internal support ***
 
     /**
-     * Internal: If this is from a compile, extract the compilation Unit.
+     * Internal: If this is from a compile/analyze wrapped in an outer class, extract the snippet.
      * Otherwise null.
      */
-    abstract Unit unitOrNull();
+    Snippet snippetOrNull() {
+        return null;
+    }
 
     /**
      * This is an unreachable-statement error
@@ -124,6 +132,7 @@
      */
     boolean isResolutionError() {
         //TODO: try javac RESOLVE_ERROR flag
-        return getCode().startsWith("compiler.err.cant.resolve");
+        return getCode().startsWith("compiler.err.cant.resolve")
+                || getCode().equals("compiler.err.cant.apply.symbol");
     }
 }
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/DiagList.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/DiagList.java	Thu Apr 28 23:08:16 2016 -0700
@@ -106,7 +106,10 @@
 
     DiagList ofUnit(Unit u) {
         return this.stream()
-                .filter(d -> d.unitOrNull() == u)
+                .filter(d -> {
+                    Snippet snn = d.snippetOrNull();
+                    return snn == u.snippet();
+                })
                 .collect(Collectors.toCollection(() -> new DiagList()));
     }
 
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Eval.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Eval.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, 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
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.jshell;
 
 import java.util.ArrayList;
@@ -50,7 +49,6 @@
 import java.io.Writer;
 import java.util.LinkedHashSet;
 import java.util.Set;
-import com.sun.tools.javac.util.Context;
 import jdk.jshell.ClassTracker.ClassInfo;
 import jdk.jshell.Key.ErroneousKey;
 import jdk.jshell.Key.MethodKey;
@@ -68,7 +66,7 @@
 import static jdk.internal.jshell.debug.InternalDebugControl.DBG_GEN;
 import static jdk.jshell.Util.*;
 import static jdk.internal.jshell.remote.RemoteCodes.DOIT_METHOD_NAME;
-import static jdk.internal.jshell.remote.RemoteCodes.prefixPattern;
+import static jdk.internal.jshell.remote.RemoteCodes.PREFIX_PATTERN;
 import static jdk.jshell.Snippet.SubKind.SINGLE_TYPE_IMPORT_SUBKIND;
 import static jdk.jshell.Snippet.SubKind.SINGLE_STATIC_IMPORT_SUBKIND;
 import static jdk.jshell.Snippet.SubKind.TYPE_IMPORT_ON_DEMAND_SUBKIND;
@@ -339,18 +337,8 @@
         return declare(snip);
     }
 
-    private OuterWrap wrapInClass(String className, Set<Key> except, String userSource, Wrap guts, Collection<Snippet> plus) {
-        String imports = state.maps.packageAndImportsExcept(except, plus);
-        return OuterWrap.wrapInClass(state.maps.packageName(), className, imports, userSource, guts);
-    }
-
-    OuterWrap wrapInClass(Snippet snip, Set<Key> except, Wrap guts, Collection<Snippet> plus) {
-        return wrapInClass(snip.className(), except, snip.source(), guts, plus);
-    }
-
     private AnalyzeTask trialCompile(Wrap guts) {
-        OuterWrap outer = wrapInClass(REPL_DOESNOTMATTER_CLASS_NAME,
-                Collections.emptySet(), "", guts, null);
+        OuterWrap outer = state.outerMap.wrapInTrialClass(guts);
         return state.taskFactory.new AnalyzeTask(outer);
     }
 
@@ -464,17 +452,18 @@
 
         // If appropriate, execute the snippet
         String value = null;
-        Exception exception = null;
+        JShellException exception = null;
         if (si.status().isDefined) {
             if (si.isExecutable()) {
                 try {
-                    value = state.executionControl().commandInvoke(state.maps.classFullName(si));
+                value = state.executionControl().commandInvoke(si.classFullName());
                     value = si.subKind().hasValue()
                             ? expunge(value)
                             : "";
                 } catch (EvalException ex) {
                     exception = translateExecutionException(ex);
-                } catch (UnresolvedReferenceException ex) {
+                } catch (JShellException ex) {
+                    // UnresolvedReferenceException
                     exception = ex;
                 }
             } else if (si.subKind() == SubKind.VAR_DECLARATION_SUBKIND) {
@@ -504,37 +493,54 @@
         return events(c, outs, value, exception);
     }
 
-    private List<SnippetEvent> events(Unit c, Collection<Unit> outs, String value, Exception exception) {
+    private boolean interestingEvent(SnippetEvent e) {
+        return e.isSignatureChange()
+                    || e.causeSnippet() == null
+                    || e.status() != e.previousStatus()
+                    || e.exception() != null;
+    }
+
+    private List<SnippetEvent> events(Unit c, Collection<Unit> outs, String value, JShellException exception) {
         List<SnippetEvent> events = new ArrayList<>();
         events.add(c.event(value, exception));
         events.addAll(outs.stream()
                 .filter(u -> u != c)
                 .map(u -> u.event(null, null))
+                .filter(this::interestingEvent)
                 .collect(Collectors.toList()));
         events.addAll(outs.stream()
                 .flatMap(u -> u.secondaryEvents().stream())
+                .filter(this::interestingEvent)
                 .collect(Collectors.toList()));
         //System.err.printf("Events: %s\n", events);
         return events;
     }
 
+    private Set<OuterWrap> outerWrapSet(Collection<Unit> units) {
+        return units.stream()
+                .map(u -> u.snippet().outerWrap())
+                .collect(toSet());
+    }
+
     private Set<Unit> compileAndLoad(Set<Unit> ins) {
         if (ins.isEmpty()) {
             return ins;
         }
         Set<Unit> replaced = new LinkedHashSet<>();
+        // Loop until dependencies and errors are stable
         while (true) {
             state.debug(DBG_GEN, "compileAndLoad  %s\n", ins);
 
-            ins.stream().forEach(u -> u.initialize(ins));
-            AnalyzeTask at = state.taskFactory.new AnalyzeTask(ins);
+            ins.stream().forEach(u -> u.initialize());
+            ins.stream().forEach(u -> u.setWrap(ins, ins));
+            AnalyzeTask at = state.taskFactory.new AnalyzeTask(outerWrapSet(ins));
             ins.stream().forEach(u -> u.setDiagnostics(at));
 
             // corral any Snippets that need it
             AnalyzeTask cat;
             if (ins.stream().anyMatch(u -> u.corralIfNeeded(ins))) {
                 // if any were corralled, re-analyze everything
-                cat = state.taskFactory.new AnalyzeTask(ins);
+                cat = state.taskFactory.new AnalyzeTask(outerWrapSet(ins));
                 ins.stream().forEach(u -> u.setCorralledDiagnostics(cat));
             } else {
                 cat = at;
@@ -556,7 +562,7 @@
                     legit.stream().forEach(u -> u.setWrap(ins, legit));
 
                     // generate class files for those capable
-                    CompileTask ct = state.taskFactory.new CompileTask(legit);
+                    CompileTask ct = state.taskFactory.new CompileTask(outerWrapSet(legit));
                     if (!ct.compile()) {
                         // oy! compile failed because of recursive new unresolved
                         if (legit.stream()
@@ -572,8 +578,8 @@
 
                     // load all new classes
                     load(legit.stream()
-                            .flatMap(u -> u.classesToLoad(ct.classInfoList(u)))
-                            .collect(toList()));
+                            .flatMap(u -> u.classesToLoad(ct.classInfoList(u.snippet().outerWrap())))
+                            .collect(toSet()));
                     // attempt to redefine the remaining classes
                     List<Unit> toReplace = legit.stream()
                             .filter(u -> !u.doRedefines())
@@ -607,7 +613,7 @@
         }
     }
 
-    private void load(List<ClassInfo> cil) {
+    private void load(Set<ClassInfo> cil) {
         if (!cil.isEmpty()) {
             state.executionControl().commandLoad(cil);
         }
@@ -625,20 +631,14 @@
         StackTraceElement[] elems = new StackTraceElement[last + 1];
         for (int i = 0; i <= last; ++i) {
             StackTraceElement r = raw[i];
-            String rawKlass = r.getClassName();
-            Matcher matcher = prefixPattern.matcher(rawKlass);
-            String num;
-            if (matcher.find() && (num = matcher.group("num")) != null) {
-                int end = matcher.end();
-                if (rawKlass.charAt(end - 1) == '$') {
-                    --end;
-                }
-                int id = Integer.parseInt(num);
-                Snippet si = state.maps.getSnippet(id);
-                String klass = expunge(rawKlass);
+            OuterSnippetsClassWrap outer = state.outerMap.getOuter(r.getClassName());
+            if (outer != null) {
+                String klass = expunge(r.getClassName());
                 String method = r.getMethodName().equals(DOIT_METHOD_NAME) ? "" : r.getMethodName();
-                String file = "#" + id;
-                int line = si.outerWrap().wrapLineToSnippetLine(r.getLineNumber() - 1) + 1;
+                int wln = r.getLineNumber() - 1;
+                int line = outer.wrapLineToSnippetLine(wln) + 1;
+                Snippet sn = outer.wrapLineToSnippet(wln);
+                String file = "#" + sn.id();
                 elems[i] = new StackTraceElement(klass, method, file, line);
             } else if (r.getFileName().equals("<none>")) {
                 elems[i] = new StackTraceElement(r.getClassName(), r.getMethodName(), null, r.getLineNumber());
@@ -654,7 +654,7 @@
     }
 
     private boolean isWrap(StackTraceElement ste) {
-        return prefixPattern.matcher(ste.getClassName()).find();
+        return PREFIX_PATTERN.matcher(ste.getClassName()).find();
     }
 
     private DiagList modifierDiagnostics(ModifiersTree modtree,
@@ -714,11 +714,6 @@
             public String getMessage(Locale locale) {
                 return message;
             }
-
-            @Override
-            Unit unitOrNull() {
-                return null;
-            }
         }
 
         List<Modifier> list = new ArrayList<>();
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/EvalException.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/EvalException.java	Thu Apr 28 23:08:16 2016 -0700
@@ -40,7 +40,7 @@
  * empty string.
  */
 @SuppressWarnings("serial")             // serialVersionUID intentionally omitted
-public class EvalException extends Exception {
+public class EvalException extends JShellException {
     private final String exceptionClass;
 
     EvalException(String message, String exceptionClass, StackTraceElement[] stackElements) {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/ExecutionControl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ExecutionControl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -36,6 +36,7 @@
 import java.net.Socket;
 import com.sun.jdi.*;
 import java.io.EOFException;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -56,11 +57,19 @@
     private ObjectInputStream in;
     private ObjectOutputStream out;
     private final JShell proc;
+    private final String remoteVMOptions;
 
-    ExecutionControl(JDIEnv env, SnippetMaps maps, JShell proc) {
+    ExecutionControl(JDIEnv env, SnippetMaps maps, JShell proc, List<String> extraRemoteVMOptions) {
         this.env = env;
         this.maps = maps;
         this.proc = proc;
+        StringBuilder sb = new StringBuilder();
+        extraRemoteVMOptions.stream()
+                .forEach(s -> {
+                    sb.append(" ");
+                    sb.append(s);
+                });
+        this.remoteVMOptions = sb.toString();
     }
 
     void launch() throws IOException {
@@ -94,7 +103,7 @@
     }
 
 
-    boolean commandLoad(List<ClassInfo> cil) {
+    boolean commandLoad(Collection<ClassInfo> cil) {
         try {
             out.writeInt(CMD_LOAD);
             out.writeInt(cil.size());
@@ -110,7 +119,7 @@
         }
     }
 
-    String commandInvoke(String classname) throws EvalException, UnresolvedReferenceException {
+    String commandInvoke(String classname) throws JShellException {
         try {
             synchronized (STOP_LOCK) {
                 userCodeRunning = true;
@@ -122,7 +131,7 @@
                 String result = in.readUTF();
                 return result;
             }
-        } catch (IOException | ClassNotFoundException ex) {
+        } catch (IOException | RuntimeException ex) {
             if (!env.connection().isRunning()) {
                 env.shutdown();
             } else {
@@ -204,7 +213,7 @@
         }
     }
 
-    private boolean readAndReportExecutionResult() throws IOException, ClassNotFoundException, EvalException, UnresolvedReferenceException {
+    private boolean readAndReportExecutionResult() throws IOException, JShellException {
         int ok = in.readInt();
         switch (ok) {
             case RESULT_SUCCESS:
@@ -224,7 +233,7 @@
             case RESULT_CORRALLED: {
                 int id = in.readInt();
                 StackTraceElement[] elems = readStackTrace();
-                Snippet si = maps.getSnippet(id);
+                Snippet si = maps.getSnippetDeadOrAlive(id);
                 throw new UnresolvedReferenceException((DeclarationSnippet) si, elems);
             }
             case RESULT_KILLED: {
@@ -256,11 +265,9 @@
         //        Locale.getDefault());
 
         String connectorName = "com.sun.jdi.CommandLineLaunch";
-        String classPath = System.getProperty("java.class.path");
-        String javaArgs = "-classpath " + classPath;
         Map<String, String> argumentName2Value = new HashMap<>();
         argumentName2Value.put("main", "jdk.internal.jshell.remote.RemoteAgent " + port);
-        argumentName2Value.put("options", javaArgs);
+        argumentName2Value.put("options", remoteVMOptions);
 
         boolean launchImmediately = true;
         int traceFlags = 0;// VirtualMachine.TRACE_SENDS | VirtualMachine.TRACE_EVENTS;
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java	Thu Apr 28 23:08:16 2016 -0700
@@ -26,10 +26,11 @@
 package jdk.jshell;
 
 import java.io.ByteArrayInputStream;
-import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintStream;
 import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -77,12 +78,14 @@
 
     final SnippetMaps maps;
     final KeyMap keyMap;
+    final OuterWrapMap outerMap;
     final TaskFactory taskFactory;
     final InputStream in;
     final PrintStream out;
     final PrintStream err;
     final Supplier<String> tempVariableNameGenerator;
     final BiFunction<Snippet, Integer, String> idGenerator;
+    final List<String> extraRemoteVMOptions;
 
     private int nextKeyIndex = 1;
 
@@ -104,10 +107,11 @@
         this.err = b.err;
         this.tempVariableNameGenerator = b.tempVariableNameGenerator;
         this.idGenerator = b.idGenerator;
+        this.extraRemoteVMOptions = b.extraRemoteVMOptions;
 
         this.maps = new SnippetMaps(this);
-        maps.setPackageName("REPL");
         this.keyMap = new KeyMap(this);
+        this.outerMap = new OuterWrapMap(this);
         this.taskFactory = new TaskFactory(this);
         this.eval = new Eval(this);
         this.classTracker = new ClassTracker(this);
@@ -138,6 +142,7 @@
         PrintStream err = System.err;
         Supplier<String> tempVariableNameGenerator = null;
         BiFunction<Snippet, Integer, String> idGenerator = null;
+        List<String> extraRemoteVMOptions = new ArrayList<>();
 
         Builder() { }
 
@@ -263,6 +268,18 @@
         }
 
         /**
+         * Set additional VM options for launching the VM.
+         *
+         * @param options The options for the remote VM.
+         * @return the <code>Builder</code> instance (for use in chained
+         * initialization).
+         */
+        public Builder remoteVMOptions(String... options) {
+            this.extraRemoteVMOptions.addAll(Arrays.asList(options));
+            return this;
+        }
+
+        /**
          * Build a JShell state engine. This is the entry-point to all JShell
          * functionality. This creates a remote process for execution. It is
          * thus important to close the returned instance.
@@ -563,7 +580,7 @@
             throw new IllegalArgumentException(
                     messageFormat("jshell.exc.var.not.valid",  snippet, snippet.status()));
         }
-        String value = executionControl().commandVarValue(maps.classFullName(snippet), snippet.name());
+        String value = executionControl().commandVarValue(snippet.classFullName(), snippet.name());
         return expunge(value);
     }
 
@@ -620,10 +637,10 @@
 
     ExecutionControl executionControl() {
         if (executionControl == null) {
-            this.executionControl = new ExecutionControl(new JDIEnv(this), maps, this);
+            this.executionControl = new ExecutionControl(new JDIEnv(this), maps, this, extraRemoteVMOptions);
             try {
                 executionControl.launch();
-            } catch (IOException ex) {
+            } catch (Throwable ex) {
                 throw new InternalError("Launching JDI execution engine threw: " + ex.getMessage(), ex);
             }
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShellException.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016, 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 jdk.jshell;
+
+/**
+ * The superclass of JShell generated exceptions
+ */
+@SuppressWarnings("serial")             // serialVersionUID intentionally omitted
+public class JShellException extends Exception {
+
+    JShellException(String message) {
+        super(message);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/OuterImportSnippetWrap.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016, 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 jdk.jshell;
+
+import java.util.IdentityHashMap;
+import java.util.List;
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
+
+/**
+ * The outer wrap for a set of snippets wrapped in a generated class
+ * @author Robert Field
+ */
+public class OuterImportSnippetWrap extends OuterWrap {
+
+    private final Snippet snippet;
+
+    OuterImportSnippetWrap(Wrap wrap, Snippet snippet) {
+        super(wrap);
+        this.snippet = snippet;
+    }
+
+    @Override
+    Diag wrapDiag(Diagnostic<? extends JavaFileObject> d) {
+        return new WrappedDiagnostic(d) {
+
+            @Override
+            Snippet snippetOrNull() {
+                return snippet;
+            }
+        };
+    }
+
+    @Override
+    public String toString() {
+        return "OISW(" + w + ")";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/OuterSnippetsClassWrap.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2016, 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 jdk.jshell;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
+import jdk.jshell.Wrap.CompoundWrap;
+
+/**
+ * The outer wrap for a set of snippets wrapped in a generated class
+ * @author Robert Field
+ */
+public class OuterSnippetsClassWrap extends OuterWrap {
+
+    private final String className;
+    private final LinkedHashMap<Wrap, Snippet> wrapToSnippet;
+
+    OuterSnippetsClassWrap(String className, CompoundWrap w, List<Snippet> snippets, List<Wrap> wraps) {
+        super(w);
+        assert snippets == null || snippets.size() == wraps.size();
+        this.className = className;
+        wrapToSnippet = new LinkedHashMap<>();
+        for (int i = 0; i < snippets.size(); ++i) {
+            wrapToSnippet.put(wraps.get(i), snippets.get(i));
+        }
+    }
+
+    public Snippet wrapLineToSnippet(int wline) {
+        Wrap wrap = ((CompoundWrap)w).wrapLineToWrap(wline);
+        return wrapToSnippet.get(wrap);
+    }
+
+    @Override
+    Diag wrapDiag(Diagnostic<? extends JavaFileObject> d) {
+        return new WrappedDiagnostic(d) {
+
+            @Override
+            Snippet snippetOrNull() {
+                Wrap wrap = ((CompoundWrap) w).wrapIndexToWrap(diag.getPosition());
+                Snippet sn = wrapToSnippet.get(wrap);
+                if (sn != null) {
+                    return sn;
+                } else {
+                    return super.snippetOrNull();
+                }
+            }
+        };
+    }
+
+    int ordinal(Snippet sn) {
+        int i = 0;
+        for (Snippet si : wrapToSnippet.values()) {
+            if (si == sn) {
+                return i;
+            }
+            ++i;
+        }
+        return -1;
+    }
+
+    @Override
+    public String className() {
+        return className;
+    }
+
+    @Override
+    public String toString() {
+        return "OSCW(" + className + ":" + w + ")";
+    }
+}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/OuterWrap.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/OuterWrap.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015-2016, 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,47 +25,23 @@
 
 package jdk.jshell;
 
-import jdk.jshell.Wrap.CompoundWrap;
-import static jdk.jshell.Util.*;
 import java.util.Locale;
 import javax.tools.Diagnostic;
 import javax.tools.JavaFileObject;
-import jdk.jshell.MemoryFileManager.SourceMemoryJavaFileObject;
-import static jdk.internal.jshell.debug.InternalDebugControl.DBG_GEN;
+import jdk.internal.jshell.remote.RemoteCodes;
+import static jdk.jshell.Util.*;
+import static jdk.internal.jshell.remote.RemoteCodes.REPL_PACKAGE;
 
 /**
  *
  * @author Robert Field
  */
-final class OuterWrap implements GeneralWrap {
-
-    private final String packageName;
-    private final String className;
-    private final String userSource;
-    private final GeneralWrap w;
-    private final Wrap guts;
+class OuterWrap implements GeneralWrap {
 
-    public static OuterWrap wrapInClass(String packageName, String className,
-             String imports, String userSource, Wrap guts) {
-        GeneralWrap kw = new CompoundWrap(
-                imports
-                + "class " + className + " {\n",
-                guts,
-                "}\n");
-        return new OuterWrap(packageName, className, userSource, kw, guts);
-    }
+    protected final Wrap w;
 
-    public static OuterWrap wrapImport(String userSource, Wrap guts) {
-        return new OuterWrap("", "", userSource, guts, guts);
-    }
-
-    private OuterWrap(String packageName, String className, String userSource,
-            GeneralWrap w, Wrap guts) {
-        this.packageName = packageName;
-        this.className = className;
-        this.userSource = userSource;
-        this.w = w;
-        this.guts = guts;
+    OuterWrap(Wrap wrap) {
+        this.w = wrap;
     }
 
     @Override
@@ -114,19 +90,28 @@
     }
 
     public String className() {
-        return className;
+        return REPL_DOESNOTMATTER_CLASS_NAME;
     }
 
     public String classFullName() {
-        return packageName + "." + className;
+        return REPL_PACKAGE + "." + className();
+    }
+
+    @Override
+    public int hashCode() {
+        return className().hashCode();
     }
 
-    public String getUserSource() {
-        return userSource;
+    @Override
+    public boolean equals(Object o) {
+        return (o instanceof OuterWrap)
+                ? className().equals(((OuterWrap) o).className())
+                : false;
     }
 
-    Wrap guts() {
-        return guts;
+    @Override
+    public String toString() {
+        return "OW(" + w + ")";
     }
 
     Diag wrapDiag(Diagnostic<? extends JavaFileObject> d) {
@@ -135,7 +120,7 @@
 
     class WrappedDiagnostic extends Diag {
 
-        private final Diagnostic<? extends JavaFileObject> diag;
+        final Diagnostic<? extends JavaFileObject> diag;
 
         WrappedDiagnostic(Diagnostic<? extends JavaFileObject> diag) {
             this.diag = diag;
@@ -172,25 +157,13 @@
         }
 
         @Override
-        Unit unitOrNull() {
-            JavaFileObject fo = diag.getSource();
-            if (fo instanceof SourceMemoryJavaFileObject) {
-                SourceMemoryJavaFileObject sfo = (SourceMemoryJavaFileObject) fo;
-                if (sfo.getOrigin() instanceof Unit) {
-                    return (Unit) sfo.getOrigin();
-                }
-            }
-            return null;
-        }
-
-        @Override
         boolean isResolutionError() {
             if (!super.isResolutionError()) {
                 return false;
             }
             for (String line : diag.getMessage(PARSED_LOCALE).split("\\r?\\n")) {
                 if (line.trim().startsWith("location:")) {
-                    if (!line.contains(REPL_CLASS_PREFIX)) {
+                    if (!line.contains(RemoteCodes.REPL_CLASS_PREFIX)) {
                         // Resolution error must occur within a REPL class or it is not resolvable
                         return false;
                     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/OuterWrapMap.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2016, 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 jdk.jshell;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.stream.Collectors;
+import jdk.jshell.Wrap.CompoundWrap;
+import static jdk.internal.jshell.remote.RemoteCodes.PREFIX_PATTERN;
+import static jdk.internal.jshell.remote.RemoteCodes.REPL_CLASS_PREFIX;
+import static jdk.jshell.Util.REPL_DOESNOTMATTER_CLASS_NAME;
+import static jdk.jshell.Util.asLetters;
+
+/**
+ *
+ * @author Robert Field
+ */
+public class OuterWrapMap {
+
+    private final JShell state;
+    private final Map<String,OuterSnippetsClassWrap> classOuters = new HashMap<>();
+
+    OuterWrapMap(JShell state) {
+        this.state = state;
+    }
+
+    OuterSnippetsClassWrap getOuter(String className) {
+        Matcher matcher = PREFIX_PATTERN.matcher(className);
+        String cn;
+        if (matcher.find() && (cn = matcher.group("class")) != null) {
+            return classOuters.get(cn);
+        }
+        return null;
+    }
+
+    private CompoundWrap wrappedInClass(String className, String imports, List<Wrap> wraps) {
+        List<Object> elems = new ArrayList<>(wraps.size() + 2);
+        elems.add(imports +
+                "class " + className + " {\n");
+        elems.addAll(wraps);
+        elems.add("}\n");
+        return new CompoundWrap(elems.toArray());
+    }
+
+    OuterWrap wrapInClass(Set<Key> except, Collection<Snippet> plus,
+            List<Snippet> snippets, List<Wrap> wraps) {
+        String imports = state.maps.packageAndImportsExcept(except, plus);
+        // className is unique to the set of snippets and their version (seq)
+        String className = REPL_CLASS_PREFIX + snippets.stream()
+                .sorted((sn1, sn2) -> sn1.key().index() - sn2.key().index())
+                .map(sn -> "" + sn.key().index() + asLetters(sn.sequenceNumber()))
+                .collect(Collectors.joining("_"));
+        CompoundWrap w = wrappedInClass(className, imports, wraps);
+        OuterSnippetsClassWrap now = new OuterSnippetsClassWrap(className, w, snippets, wraps);
+        classOuters.put(className, now);
+        return now;
+    }
+
+    OuterWrap wrapInTrialClass(Wrap wrap) {
+        String imports = state.maps.packageAndImportsExcept(null, null);
+        CompoundWrap w = wrappedInClass(REPL_DOESNOTMATTER_CLASS_NAME, imports,
+                Collections.singletonList(wrap));
+        return new OuterWrap(w);
+    }
+
+    OuterWrap wrapImport(Wrap guts, Snippet sn) {
+        return new OuterImportSnippetWrap(guts, sn);
+    }
+}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Snippet.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Snippet.java	Thu Apr 28 23:08:16 2016 -0700
@@ -28,8 +28,6 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
-import static jdk.jshell.Util.REPL_CLASS_PREFIX;
-import static jdk.jshell.Util.asLetters;
 
 /**
  * A Snippet represents a snippet of Java source code as passed to
@@ -503,7 +501,6 @@
     private final SubKind subkind;
 
     private int seq;
-    private String className;
     private String id;
     private OuterWrap outer;
     private Status status;
@@ -615,7 +612,6 @@
 
     final void setSequenceNumber(int seq) {
         this.seq = seq;
-        this.className = REPL_CLASS_PREFIX + key().index() + asLetters(seq);
     }
 
     void setOuterWrap(OuterWrap outer) {
@@ -653,7 +649,11 @@
     }
 
     String className() {
-        return className;
+        return outer.className();
+    }
+
+    String classFullName() {
+        return outer.classFullName();
     }
 
     /**
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SnippetEvent.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SnippetEvent.java	Thu Apr 28 23:08:16 2016 -0700
@@ -44,7 +44,7 @@
 
     SnippetEvent(Snippet snippet, Status previousStatus, Status status,
             boolean isSignatureChange, Snippet causeSnippet,
-            String value, Exception exception) {
+            String value, JShellException exception) {
         this.snippet = snippet;
         this.previousStatus = previousStatus;
         this.status = status;
@@ -60,7 +60,7 @@
     private final boolean isSignatureChange;
     private final Snippet causeSnippet;
     private final String value;
-    private final Exception exception;
+    private final JShellException exception;
 
     /**
      * The Snippet which has changed
@@ -121,7 +121,7 @@
      * during execution, otherwise <code>null</code>.
      * @return the exception or <code>null</code>.
      */
-    public Exception exception() {
+    public JShellException exception() {
         return exception;
     }
 
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SnippetMaps.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SnippetMaps.java	Thu Apr 28 23:08:16 2016 -0700
@@ -38,8 +38,9 @@
 import java.util.stream.Stream;
 
 import static java.util.stream.Collectors.toList;
-import static jdk.internal.jshell.remote.RemoteCodes.prefixPattern;
+import static jdk.internal.jshell.remote.RemoteCodes.PREFIX_PATTERN;
 import static jdk.internal.jshell.debug.InternalDebugControl.DBG_DEP;
+import static jdk.internal.jshell.remote.RemoteCodes.REPL_PACKAGE;
 
 /**
  * Maintain relationships between the significant entities: Snippets,
@@ -48,7 +49,6 @@
  */
 final class SnippetMaps {
 
-    private String packageName;
     private final List<Snippet> keyIndexToSnippet = new ArrayList<>();
     private final Set<Snippet> snippets = new LinkedHashSet<>();
     private final Map<String, Set<Integer>> dependencies = new HashMap<>();
@@ -81,6 +81,13 @@
     }
 
     Snippet getSnippet(int ki) {
+        Snippet sn = getSnippetDeadOrAlive(ki);
+        return (sn != null && !sn.status().isActive)
+                ? null
+                : sn;
+    }
+
+    Snippet getSnippetDeadOrAlive(int ki) {
         if (ki >= keyIndexToSnippet.size()) {
             return null;
         }
@@ -91,21 +98,9 @@
         return new ArrayList<>(snippets);
     }
 
-    void setPackageName(String n) {
-        packageName = n;
-    }
-
-    String packageName() {
-        return packageName;
-    }
-
-    String classFullName(Snippet sn) {
-        return packageName + "." + sn.className();
-    }
-
     String packageAndImportsExcept(Set<Key> except, Collection<Snippet> plus) {
         StringBuilder sb = new StringBuilder();
-        sb.append("package ").append(packageName()).append(";\n");
+        sb.append("package ").append(REPL_PACKAGE).append(";\n");
         for (Snippet si : keyIndexToSnippet) {
             if (si != null && si.status().isDefined && (except == null || !except.contains(si.key()))) {
                 sb.append(si.importLine(state));
@@ -137,7 +132,7 @@
         }
         List<Snippet> deps = new ArrayList<>();
         for (Integer dss : depset) {
-            Snippet dep = getSnippet(dss);
+            Snippet dep = getSnippetDeadOrAlive(dss);
             if (dep != null) {
                 deps.add(dep);
                 state.debug(DBG_DEP, "Found dependency %s -> %s\n", snip.name(), dep.name());
@@ -161,7 +156,7 @@
     }
 
     String fullClassNameAndPackageToClass(String full, String pkg) {
-        Matcher mat = prefixPattern.matcher(full);
+        Matcher mat = PREFIX_PATTERN.matcher(full);
         if (mat.lookingAt()) {
             return full.substring(mat.end());
         }
@@ -195,6 +190,6 @@
     private Stream<ImportSnippet> importSnippets() {
         return state.keyMap.importKeys()
                 .map(key -> (ImportSnippet)getSnippet(key))
-                .filter(sn -> state.status(sn).isDefined);
+                .filter(sn -> sn != null && state.status(sn).isDefined);
     }
 }
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java	Thu Apr 28 23:08:16 2016 -0700
@@ -211,11 +211,6 @@
         throw new InternalError();
     }
 
-    private OuterWrap wrapInClass(Wrap guts) {
-        String imports = proc.maps.packageAndImportsExcept(null, null);
-        return OuterWrap.wrapInClass(proc.maps.packageName(), REPL_DOESNOTMATTER_CLASS_NAME, imports, "", guts);
-    }
-
     private Tree.Kind guessKind(String code) {
         ParseTask pt = proc.taskFactory.new ParseTask(code);
         List<? extends Tree> units = pt.units();
@@ -258,13 +253,13 @@
         OuterWrap codeWrap;
         switch (guessKind(code)) {
             case IMPORT:
-                codeWrap = OuterWrap.wrapImport(null, Wrap.simpleWrap(code + "any.any"));
+                codeWrap = proc.outerMap.wrapImport(Wrap.simpleWrap(code + "any.any"), null);
                 break;
             case METHOD:
-                codeWrap = wrapInClass(Wrap.classMemberWrap(code));
+                codeWrap = proc.outerMap.wrapInTrialClass(Wrap.classMemberWrap(code));
                 break;
             default:
-                codeWrap = wrapInClass(Wrap.methodWrap(code));
+                codeWrap = proc.outerMap.wrapInTrialClass(Wrap.methodWrap(code));
                 break;
         }
         String requiredPrefix = identifier;
@@ -946,7 +941,7 @@
         if (guessKind(code) == Kind.IMPORT)
             return null;
 
-        OuterWrap codeWrap = wrapInClass(Wrap.methodWrap(code));
+        OuterWrap codeWrap = proc.outerMap.wrapInTrialClass(Wrap.methodWrap(code));
         AnalyzeTask at = proc.taskFactory.new AnalyzeTask(codeWrap);
         SourcePositions sp = at.trees().getSourcePositions();
         CompilationUnitTree topLevel = at.firstCuTree();
@@ -1064,7 +1059,7 @@
             case INTERFACE: case ANNOTATION_TYPE: case VARIABLE:
                 return null;
             default:
-                codeWrap = wrapInClass(Wrap.methodWrap(code));
+                codeWrap = proc.outerMap.wrapInTrialClass(Wrap.methodWrap(code));
                 break;
         }
         AnalyzeTask at = proc.taskFactory.new AnalyzeTask(codeWrap);
@@ -1104,10 +1099,10 @@
             case IMPORT:
                 return new QualifiedNames(Collections.emptyList(), -1, true, false);
             case METHOD:
-                codeWrap = wrapInClass(Wrap.classMemberWrap(code));
+                codeWrap = proc.outerMap.wrapInTrialClass(Wrap.classMemberWrap(code));
                 break;
             default:
-                codeWrap = wrapInClass(Wrap.methodWrap(code));
+                codeWrap = proc.outerMap.wrapInTrialClass(Wrap.methodWrap(code));
                 break;
         }
         AnalyzeTask at = proc.taskFactory.new AnalyzeTask(codeWrap);
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, 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
@@ -148,23 +148,12 @@
                 public String getMessage(Locale locale) {
                     return expunge(d.getMessage(locale));
                 }
-
-                @Override
-                Unit unitOrNull() {
-                    return null;
-                }
             };
         }
     }
 
     private class WrapSourceHandler implements SourceHandler<OuterWrap> {
 
-        final OuterWrap wrap;
-
-        WrapSourceHandler(OuterWrap wrap) {
-            this.wrap = wrap;
-        }
-
         @Override
         public JavaFileObject sourceToFileObject(MemoryFileManager fm, OuterWrap w) {
             return fm.createSourceFileObject(w, w.classFullName(), w.wrapped());
@@ -172,24 +161,9 @@
 
         @Override
         public Diag diag(Diagnostic<? extends JavaFileObject> d) {
-            return wrap.wrapDiag(d);
-        }
-    }
-
-    private class UnitSourceHandler implements SourceHandler<Unit> {
-
-        @Override
-        public JavaFileObject sourceToFileObject(MemoryFileManager fm, Unit u) {
-            return fm.createSourceFileObject(u,
-                    state.maps.classFullName(u.snippet()),
-                    u.snippet().outerWrap().wrapped());
-        }
-
-        @Override
-        public Diag diag(Diagnostic<? extends JavaFileObject> d) {
             SourceMemoryJavaFileObject smjfo = (SourceMemoryJavaFileObject) d.getSource();
-            Unit u = (Unit) smjfo.getOrigin();
-            return u.snippet().outerWrap().wrapDiag(d);
+            OuterWrap w = (OuterWrap) smjfo.getOrigin();
+            return w.wrapDiag(d);
         }
     }
 
@@ -242,13 +216,12 @@
         private final Iterable<? extends CompilationUnitTree> cuts;
 
         AnalyzeTask(final OuterWrap wrap) {
-            this(Stream.of(wrap),
-                    new WrapSourceHandler(wrap),
-                    "-XDshouldStopPolicy=FLOW", "-proc:none");
+            this(Collections.singletonList(wrap));
         }
 
-        AnalyzeTask(final Collection<Unit> units) {
-            this(units.stream(), new UnitSourceHandler(),
+        AnalyzeTask(final Collection<OuterWrap> wraps) {
+            this(wraps.stream(),
+                    new WrapSourceHandler(),
                     "-XDshouldStopPolicy=FLOW", "-Xlint:unchecked", "-XaddExports:jdk.jshell/jdk.internal.jshell.remote=ALL-UNNAMED", "-proc:none");
         }
 
@@ -287,10 +260,10 @@
      */
     class CompileTask extends BaseTask {
 
-        private final Map<Unit, List<OutputMemoryJavaFileObject>> classObjs = new HashMap<>();
+        private final Map<OuterWrap, List<OutputMemoryJavaFileObject>> classObjs = new HashMap<>();
 
-        CompileTask(Collection<Unit> units) {
-            super(units.stream(), new UnitSourceHandler(),
+        CompileTask(final Collection<OuterWrap> wraps) {
+            super(wraps.stream(), new WrapSourceHandler(),
                     "-Xlint:unchecked", "-XaddExports:jdk.jshell/jdk.internal.jshell.remote=ALL-UNNAMED", "-proc:none");
         }
 
@@ -302,8 +275,8 @@
         }
 
 
-        List<ClassInfo> classInfoList(Unit u) {
-            List<OutputMemoryJavaFileObject> l = classObjs.get(u);
+        List<ClassInfo> classInfoList(OuterWrap w) {
+            List<OutputMemoryJavaFileObject> l = classObjs.get(w);
             if (l == null) return Collections.emptyList();
             return l.stream()
                     .map(fo -> state.classTracker.classInfo(fo.getName(), fo.getBytes()))
@@ -315,11 +288,11 @@
             //debug("listenForNewClassFile %s loc=%s kind=%s\n", className, location, kind);
             if (location == CLASS_OUTPUT) {
                 state.debug(DBG_GEN, "Compiler generating class %s\n", className);
-                Unit u = ((sibling instanceof SourceMemoryJavaFileObject)
-                        && (((SourceMemoryJavaFileObject) sibling).getOrigin() instanceof Unit))
-                        ? (Unit) ((SourceMemoryJavaFileObject) sibling).getOrigin()
+                OuterWrap w = ((sibling instanceof SourceMemoryJavaFileObject)
+                        && (((SourceMemoryJavaFileObject) sibling).getOrigin() instanceof OuterWrap))
+                        ? (OuterWrap) ((SourceMemoryJavaFileObject) sibling).getOrigin()
                         : null;
-                classObjs.compute(u, (k, v) -> (v == null)? new ArrayList<>() : v)
+                classObjs.compute(w, (k, v) -> (v == null)? new ArrayList<>() : v)
                         .add(jfo);
             }
         }
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/TreeDissector.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/TreeDissector.java	Thu Apr 28 23:08:16 2016 -0700
@@ -162,18 +162,28 @@
         return new Range(start, end);
     }
 
-    Tree firstClassMember() {
-        if (targetClass != null) {
-            //TODO: missing classes
-            for (Tree mem : targetClass.getMembers()) {
-                if (mem.getKind() == Tree.Kind.VARIABLE) {
-                    return mem;
-                }
-                if (mem.getKind() == Tree.Kind.METHOD) {
-                    MethodTree mt = (MethodTree) mem;
-                    if (!isDoIt(mt.getName()) && !mt.getName().toString().equals("<init>")) {
+    MethodTree method(MethodSnippet msn) {
+        if (targetClass == null) {
+            return null;
+        }
+        OuterWrap ow = msn.outerWrap();
+        if (!(ow instanceof OuterSnippetsClassWrap)) {
+            return null;
+        }
+        int ordinal = ((OuterSnippetsClassWrap) ow).ordinal(msn);
+        if (ordinal < 0) {
+            return null;
+        }
+        int count = 0;
+        String name = msn.name();
+        for (Tree mem : targetClass.getMembers()) {
+            if (mem.getKind() == Tree.Kind.METHOD) {
+                MethodTree mt = (MethodTree) mem;
+                if (mt.getName().toString().equals(name)) {
+                    if (count == ordinal) {
                         return mt;
                     }
+                    ++count;
                 }
             }
         }
@@ -244,8 +254,8 @@
         return ei;
     }
 
-    String typeOfMethod() {
-        Tree unitTree = firstClassMember();
+    String typeOfMethod(MethodSnippet msn) {
+        Tree unitTree = method(msn);
         if (unitTree instanceof JCMethodDecl) {
             JCMethodDecl mtree = (JCMethodDecl) unitTree;
             Type mt = types().erasure(mtree.type);
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Unit.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Unit.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, 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
@@ -68,7 +68,7 @@
     private final DiagList generatedDiagnostics;
 
     private int seq;
-    private int seqInitial;
+    private String classNameInitial;
     private Wrap activeGuts;
     private Status status;
     private Status prevStatus;
@@ -95,7 +95,7 @@
         this.generatedDiagnostics = generatedDiagnostics;
 
         this.seq = isNew? 0 : siOld.sequenceNumber();
-        this.seqInitial = seq;
+        this.classNameInitial = isNew? "<none>" : siOld.className();
         this.prevStatus = (isNew || isDependency)
                 ? si.status()
                 : siOld.status();
@@ -136,28 +136,50 @@
         return isDependency;
     }
 
-    boolean isNew() {
-        return isNew;
-    }
-
-    void initialize(Collection<Unit> working) {
+    void initialize() {
         isAttemptingCorral = false;
         dependenciesNeeded = false;
         toRedefine = null; // assure NPE if classToLoad not called
         activeGuts = si.guts();
         markOldDeclarationOverwritten();
-        setWrap(working, working);
     }
 
-    void setWrap(Collection<Unit> except, Collection<Unit> plus) {
-        si.setOuterWrap(isImport()
-                ? OuterWrap.wrapImport(si.source(), activeGuts)
-                : state.eval.wrapInClass(si,
-                        except.stream().map(u -> u.snippet().key()).collect(toSet()),
-                        activeGuts,
-                        plus.stream().map(u -> u.snippet())
-                                .filter(sn -> sn != si)
-                                .collect(toList())));
+    // Set the outer wrap of our Snippet
+    void setWrap(Collection<Unit> exceptUnit, Collection<Unit> plusUnfiltered) {
+        if (isImport()) {
+            si.setOuterWrap(state.outerMap.wrapImport(activeGuts, si));
+        } else {
+            // Collect Units for be wrapped together.  Just this except for overloaded methods
+            List<Unit> units;
+            if (snippet().kind() == Kind.METHOD) {
+                String name = ((MethodSnippet) snippet()).name();
+                units = plusUnfiltered.stream()
+                        .filter(u -> u.snippet().kind() == Kind.METHOD &&
+                                 ((MethodSnippet) u.snippet()).name().equals(name))
+                        .collect(toList());
+            } else {
+                units = Collections.singletonList(this);
+            }
+            // Keys to exclude from imports
+            Set<Key> except = exceptUnit.stream()
+                    .map(u -> u.snippet().key())
+                    .collect(toSet());
+            // Snippets to add to imports
+            Collection<Snippet> plus = plusUnfiltered.stream()
+                    .filter(u -> !units.contains(u))
+                    .map(u -> u.snippet())
+                    .collect(toList());
+            // Snippets to wrap in an outer
+            List<Snippet> snippets = units.stream()
+                    .map(u -> u.snippet())
+                    .collect(toList());
+            // Snippet wraps to wrap in an outer
+            List<Wrap> wraps = units.stream()
+                    .map(u -> u.activeGuts)
+                    .collect(toList());
+            // Set the outer wrap for this snippet
+            si.setOuterWrap(state.outerMap.wrapInClass(except, plus, snippets, wraps));
+        }
     }
 
     void setDiagnostics(AnalyzeTask ct) {
@@ -302,11 +324,13 @@
 
     private boolean sigChanged() {
         return (status.isDefined != prevStatus.isDefined)
-                || (seq != seqInitial && status.isDefined)
+                || (status.isDefined && !si.className().equals(classNameInitial))
                 || signatureChanged;
     }
 
     Stream<Unit> effectedDependents() {
+        //System.err.printf("effectedDependents sigChanged=%b  dependenciesNeeded=%b   status=%s\n",
+        //       sigChanged(), dependenciesNeeded, status);
         return sigChanged() || dependenciesNeeded || status == RECOVERABLE_NOT_DEFINED
                 ? dependents()
                 : Stream.empty();
@@ -361,7 +385,7 @@
         if (replaceOldEvent != null) secondaryEvents.add(replaceOldEvent);
 
         // Defined methods can overwrite methods of other (equivalent) snippets
-        if (si.kind() == Kind.METHOD && status.isDefined) {
+        if (isNew && si.kind() == Kind.METHOD && status.isDefined) {
             MethodSnippet msi = (MethodSnippet)si;
             String oqpt = msi.qualifiedParameterTypes();
             String nqpt = computeQualifiedParameterTypes(at, msi);
@@ -405,7 +429,7 @@
     }
 
     private String computeQualifiedParameterTypes(AnalyzeTask at, MethodSnippet msi) {
-        String rawSig = TreeDissector.createBySnippet(at, msi).typeOfMethod();
+        String rawSig = TreeDissector.createBySnippet(at, msi).typeOfMethod(msi);
         String signature = expunge(rawSig);
         int paren = signature.lastIndexOf(')');
 
@@ -416,7 +440,7 @@
                 : msi.parameterTypes();
     }
 
-    SnippetEvent event(String value, Exception exception) {
+    SnippetEvent event(String value, JShellException exception) {
         boolean wasSignatureChanged = sigChanged();
         state.debug(DBG_EVNT, "Snippet: %s id: %s before: %s status: %s sig: %b cause: %s\n",
                 si, si.id(), prevStatus, si.status(), wasSignatureChanged, causalSnippet);
@@ -425,7 +449,9 @@
     }
 
     List<SnippetEvent> secondaryEvents() {
-        return secondaryEvents;
+        return secondaryEvents==null
+                ? Collections.emptyList()
+                : secondaryEvents;
     }
 
     @Override
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/UnresolvedReferenceException.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/UnresolvedReferenceException.java	Thu Apr 28 23:08:16 2016 -0700
@@ -38,7 +38,7 @@
  * empty string.
  */
 @SuppressWarnings("serial")             // serialVersionUID intentionally omitted
-public class UnresolvedReferenceException extends Exception {
+public class UnresolvedReferenceException extends JShellException {
 
     final DeclarationSnippet snippet;
 
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Util.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Util.java	Thu Apr 28 23:08:16 2016 -0700
@@ -30,7 +30,8 @@
 import java.util.stream.StreamSupport;
 import javax.lang.model.element.Name;
 import static jdk.internal.jshell.remote.RemoteCodes.DOIT_METHOD_NAME;
-import static jdk.internal.jshell.remote.RemoteCodes.prefixPattern;
+import static jdk.internal.jshell.remote.RemoteCodes.PREFIX_PATTERN;
+import static jdk.internal.jshell.remote.RemoteCodes.REPL_CLASS_PREFIX;
 
 /**
  * Assorted shared utilities.
@@ -38,8 +39,7 @@
  */
 class Util {
 
-    static final String REPL_CLASS_PREFIX = "$REPL";
-    static final String REPL_DOESNOTMATTER_CLASS_NAME = REPL_CLASS_PREFIX+"00DOESNOTMATTER";
+    static final String REPL_DOESNOTMATTER_CLASS_NAME = REPL_CLASS_PREFIX+"DOESNOTMATTER";
 
     static final Locale PARSED_LOCALE = Locale.ROOT;
 
@@ -53,7 +53,7 @@
 
     static String expunge(String s) {
         StringBuilder sb = new StringBuilder();
-        for (String comp : prefixPattern.split(s)) {
+        for (String comp : PREFIX_PATTERN.split(s)) {
             sb.append(comp);
         }
         return sb.toString();
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Wrap.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Wrap.java	Thu Apr 28 23:08:16 2016 -0700
@@ -25,6 +25,8 @@
 
 package jdk.jshell;
 
+import java.util.Arrays;
+import static java.util.stream.Collectors.joining;
 import static jdk.internal.jshell.remote.RemoteCodes.DOIT_METHOD_NAME;
 
 /**
@@ -237,6 +239,27 @@
             return 0;
         }
 
+        Wrap wrapIndexToWrap(long wi) {
+            int before = 0;
+            Wrap w = null;
+            for (Object o : os) {
+                if (o instanceof String) {
+                    String s = (String) o;
+                    before += s.length();
+                } else if (o instanceof Wrap) {
+                    w = (Wrap) o;
+                    int len = w.wrapped().length();
+                    if ((wi - before) <= len) {
+                        //System.err.printf("Defer to wrap %s - wi: %d. before; %d   -- %s  >>> %s\n",
+                        //        w, wi, before, w.debugPos(wi - before), w.wrapped());
+                        return w;
+                    }
+                    before += len;
+                }
+            }
+            return w;
+        }
+
         @Override
         public int wrapIndexToSnippetIndex(int wi) {
             int before = 0;
@@ -286,6 +309,25 @@
             return 0;
         }
 
+        Wrap wrapLineToWrap(int wline) {
+            int before = 0;
+            Wrap w = null;
+            for (Object o : os) {
+                if (o instanceof String) {
+                    String s = (String) o;
+                    before += countLines(s);
+                } else if (o instanceof Wrap) {
+                    w = (Wrap) o;
+                    int lns = countLines(w.wrapped());
+                    if ((wline - before) < lns) {
+                        return w;
+                    }
+                    before += lns;
+                }
+            }
+            return w;
+        }
+
         @Override
         public int wrapLineToSnippetLine(int wline) {
             int before = 0;
@@ -315,7 +357,10 @@
             return snlineLast;
         }
 
-
+        @Override
+        public String toString() {
+            return "CompoundWrap(" + Arrays.stream(os).map(u -> u.toString()).collect(joining(",")) + ")";
+        }
     }
 
     private static class RangeWrap extends Wrap {
@@ -404,6 +449,10 @@
             return lastSnline;
         }
 
+        @Override
+        public String toString() {
+            return "RangeWrap(" + range + ")";
+        }
     }
 
     private static class NoWrap extends RangeWrap {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testModules/TestModules.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2016, 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 8154119
+ * @summary Test modules support in javadoc.
+ * @author bpatel
+ * @library ../lib
+ * @modules jdk.javadoc/jdk.javadoc.internal.tool
+ * @build JavadocTester
+ * @run main TestModules
+ */
+
+public class TestModules extends JavadocTester {
+
+    public static void main(String... args) throws Exception {
+        TestModules tester = new TestModules();
+        tester.runTests();
+    }
+
+    @Test
+    void test1() {
+        javadoc("-d", "out",
+                "-modulesourcepath", testSrc,
+                "-addmods", "module1,module2",
+                "testpkgmdl1", "testpkgmdl2");
+        checkExit(Exit.OK);
+        testDescription(true);
+        testNoDescription(false);
+    }
+
+    @Test
+    void test2() {
+        javadoc("-d", "out-html5", "-html5",
+                "-modulesourcepath", testSrc,
+                "-addmods", "module1,module2",
+                "testpkgmdl1", "testpkgmdl2");
+        checkExit(Exit.OK);
+        testHtml5Description(true);
+        testHtml5NoDescription(false);
+    }
+
+    @Test
+    void test3() {
+        javadoc("-d", "out-nocomment", "-nocomment",
+                "-modulesourcepath", testSrc,
+                "-addmods", "module1,module2",
+                "testpkgmdl1", "testpkgmdl2");
+        checkExit(Exit.OK);
+        testDescription(false);
+        testNoDescription(true);
+    }
+
+    @Test
+    void test4() {
+        javadoc("-d", "out-html5-nocomment", "-nocomment", "-html5",
+                "-modulesourcepath", testSrc,
+                "-addmods", "module1,module2",
+                "testpkgmdl1", "testpkgmdl2");
+        checkExit(Exit.OK);
+        testHtml5Description(false);
+        testHtml5NoDescription(true);
+    }
+
+    void testDescription(boolean found) {
+        checkOutput("module1-summary.html", found,
+                "<!-- ============ MODULE DESCRIPTION =========== -->\n"
+                + "<a name=\"module.description\">\n"
+                + "<!--   -->\n"
+                + "</a>\n"
+                + "<div class=\"block\">This is a test description for the module1 module.</div>");
+        checkOutput("module2-summary.html", found,
+                "<!-- ============ MODULE DESCRIPTION =========== -->\n"
+                + "<a name=\"module.description\">\n"
+                + "<!--   -->\n"
+                + "</a>\n"
+                + "<div class=\"block\">This is a test description for the module2 module.</div>");
+    }
+
+    void testNoDescription(boolean found) {
+        checkOutput("module1-summary.html", found,
+                "<div class=\"contentContainer\">\n"
+                + "<ul class=\"blockList\">\n"
+                + "<li class=\"blockList\">\n"
+                + "<table class=\"overviewSummary\" summary=\"Package Summary table, listing packages, and an explanation\">");
+        checkOutput("module2-summary.html", found,
+                "<div class=\"contentContainer\">\n"
+                + "<ul class=\"blockList\">\n"
+                + "<li class=\"blockList\">\n"
+                + "<table class=\"overviewSummary\" summary=\"Package Summary table, listing packages, and an explanation\">");
+    }
+
+    void testHtml5Description(boolean found) {
+        checkOutput("module1-summary.html", found,
+                "<section role=\"region\">\n"
+                + "<!-- ============ MODULE DESCRIPTION =========== -->\n"
+                + "<a id=\"module.description\">\n"
+                + "<!--   -->\n"
+                + "</a>\n"
+                + "<div class=\"block\">This is a test description for the module1 module.</div>\n"
+                + "</section>");
+        checkOutput("module2-summary.html", found,
+                "<section role=\"region\">\n"
+                + "<!-- ============ MODULE DESCRIPTION =========== -->\n"
+                + "<a id=\"module.description\">\n"
+                + "<!--   -->\n"
+                + "</a>\n"
+                + "<div class=\"block\">This is a test description for the module2 module.</div>\n"
+                + "</section>");
+    }
+
+    void testHtml5NoDescription(boolean found) {
+        checkOutput("module1-summary.html", found,
+                "<div class=\"contentContainer\">\n"
+                + "<ul class=\"blockList\">\n"
+                + "<li class=\"blockList\">\n"
+                + "<table class=\"overviewSummary\">");
+        checkOutput("module2-summary.html", found,
+                "<div class=\"contentContainer\">\n"
+                + "<ul class=\"blockList\">\n"
+                + "<li class=\"blockList\">\n"
+                + "<table class=\"overviewSummary\">");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testModules/module1/module-info.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+/**
+  * This is a test description for the module1 module.
+  */
+module module1 {
+    requires module2;
+
+    exports testpkgmdl1;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testModules/module1/testpkgmdl1/TestClassInModule1.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016, 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 testpkgmdl1;
+
+public class TestClassInModule1 {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testModules/module2/module-info.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+/**
+  * This is a test description for the module2 module.
+  */
+module module2 {
+    exports testpkgmdl2;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testModules/module2/testpkgmdl2/TestClassInModule2.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016, 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 testpkgmdl2;
+
+public class TestClassInModule2 {
+}
--- a/langtools/test/jdk/javadoc/doclet/testOrdering/TestOrdering.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/jdk/javadoc/doclet/testOrdering/TestOrdering.java	Thu Apr 28 23:08:16 2016 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8039410 8042601 8042829 8049393 8050031
+ * @bug 8039410 8042601 8042829 8049393 8050031 8155061
  * @summary test to determine if members are ordered correctly
  * @author ksrini
  * @library ../lib/
@@ -72,6 +72,8 @@
         checkOrder("pkg1/class-use/UsedClass.html", expectedInnerClassContructors);
         checkOrder("pkg1/ImplementsOrdering.html", expectedImplementsOrdering);
         checkOrder("pkg1/OverrideOrdering.html", expectedOverrideOrdering);
+        checkOrder("allclasses-noframe.html", expectedAllClasses);
+        checkOrder("allclasses-frame.html", expectedAllClasses);
     }
 
     enum ListOrder { NONE, REVERSE, SHUFFLE };
@@ -179,6 +181,22 @@
     };
     String[] composeTestVectors() {
         List<String> testList = new ArrayList<>();
+
+        testList.addAll(Arrays.asList(expectedPackageOrdering));
+
+        for (String x : expectedMethodOrdering) {
+            testList.add(x);
+            for (int i = 0; i < MAX_PACKAGES; i++) {
+                String wpkg = "add" + i;
+                testList.add(wpkg + "/" + x);
+                String dpkg = wpkg;
+                for (int j = 1; j < MAX_SUBPACKAGES_DEPTH; j++) {
+                    dpkg = dpkg + "/" + "add";
+                    testList.add(dpkg + "/" + x);
+                }
+            }
+        }
+
         for (String x : expectedEnumOrdering) {
             testList.add(x.replace("REPLACE_ME", "&lt;Unnamed&gt;"));
             for (int i = 0; i < MAX_PACKAGES; i++) {
@@ -194,20 +212,9 @@
 
         testList.addAll(Arrays.asList(expectedFieldOrdering));
 
-        for (String x : expectedMethodOrdering) {
-            testList.add(x);
-            for (int i = 0; i < MAX_PACKAGES; i++) {
-                String wpkg = "add" + i;
-                testList.add(wpkg + "/" + x);
-                String dpkg = wpkg;
-                for (int j = 1; j < MAX_SUBPACKAGES_DEPTH; j++) {
-                    dpkg = dpkg + "/" + "add";
-                    testList.add(dpkg + "/" + x);
-                }
-            }
-        }
         return testList.toArray(new String[testList.size()]);
     }
+
     void checkExecutableMemberOrdering(String usePage) {
         String contents = readFile(usePage);
         // check constructors
@@ -309,6 +316,22 @@
         return in.replace("/", ".");
     }
 
+    final String expectedAllClasses[] = {
+        "pkg1/A.html\" title=\"class in pkg1",
+        "pkg1/A.C.html\" title=\"class in pkg1",
+        "pkg1/B.html\" title=\"class in pkg1",
+        "pkg1/B.A.html\" title=\"class in pkg1",
+        "pkg1/C1.html\" title=\"class in pkg1",
+        "pkg1/C2.html\" title=\"class in pkg1",
+        "pkg1/C3.html\" title=\"class in pkg1",
+        "pkg1/C4.html\" title=\"class in pkg1",
+        "pkg1/ImplementsOrdering.html\" title=\"interface in pkg1",
+        "pkg1/MethodOrder.html\" title=\"class in pkg1",
+        "pkg1/OverrideOrdering.html\" title=\"class in pkg1",
+        "pkg1/UsedClass.html\" title=\"class in pkg1"
+
+    };
+
     final String expectedInnerClassContructors[] = {
         "../../pkg1/A.html#A-pkg1.UsedClass-",
         "../../pkg1/B.A.html#A-pkg1.UsedClass-",
@@ -342,12 +365,33 @@
         "../../pkg1/MethodOrder.html#m-java.util.Collection-",
         "../../pkg1/MethodOrder.html#m-java.util.List-"
     };
+
     final String expectedClassUseWithTypeParams[] = {
         "../../pkg1/MethodOrder.html#tpm-pkg1.UsedClass-",
         "../../pkg1/MethodOrder.html#tpm-pkg1.UsedClass-pkg1.UsedClass-",
         "../../pkg1/MethodOrder.html#tpm-pkg1.UsedClass-pkg1.UsedClass:A-",
         "../../pkg1/MethodOrder.html#tpm-pkg1.UsedClass-java.lang.String-"
     };
+
+    final String expectedPackageOrdering[] = {
+        "\"add0/package-summary.html\">add0</a> - package add0",
+        "\"add0/add/package-summary.html\">add0.add</a> - package add0.add",
+        "\"add0/add/add/package-summary.html\">add0.add.add</a> - package add0.add.add",
+        "\"add0/add/add/add/package-summary.html\">add0.add.add.add</a> - package add0.add.add.add",
+        "\"add1/package-summary.html\">add1</a> - package add1",
+        "\"add1/add/package-summary.html\">add1.add</a> - package add1.add",
+        "\"add1/add/add/package-summary.html\">add1.add.add</a> - package add1.add.add",
+        "\"add1/add/add/add/package-summary.html\">add1.add.add.add</a> - package add1.add.add.add",
+        "\"add2/package-summary.html\">add2</a> - package add2",
+        "\"add2/add/package-summary.html\">add2.add</a> - package add2.add",
+        "\"add2/add/add/package-summary.html\">add2.add.add</a> - package add2.add.add",
+        "\"add2/add/add/add/package-summary.html\">add2.add.add.add</a> - package add2.add.add.add",
+        "\"add3/package-summary.html\">add3</a> - package add3",
+        "\"add3/add/package-summary.html\">add3.add</a> - package add3.add",
+        "\"add3/add/add/package-summary.html\">add3.add.add</a> - package add3.add.add",
+        "\"add3/add/add/add/package-summary.html\">add3.add.add.add</a> - package add3.add.add.add"
+    };
+
     final String expectedMethodOrdering[] = {
         "Add.html#add--",
         "Add.html#add-double-",
@@ -361,10 +405,12 @@
         "Add.html#add-java.lang.Double-",
         "Add.html#add-java.lang.Integer-"
     };
+
     final String expectedEnumOrdering[] = {
         "Add.add.html\" title=\"enum in REPLACE_ME\"",
         "Add.ADD.html\" title=\"enum in REPLACE_ME\""
     };
+
     final String expectedFieldOrdering[] = {
         "Add.html#addadd\"",
         "add0/add/add/add/Add.html#addadd\"",
@@ -418,10 +464,12 @@
         "add3/add/Add.html#ADDADD\"",
         "add3/Add.html#ADDADD\""
     };
+
     final String expectedPackageTreeOrdering[] = {
         "<a href=\"../../add0/add/Add.add.html\" title=\"enum in add0.add\">",
         "<a href=\"../../add0/add/Add.ADD.html\" title=\"enum in add0.add\">"
     };
+
     final String expectedOverviewOrdering[] = {
         "<a href=\"Add.add.html\" title=\"enum in &lt;Unnamed&gt;\">",
         "<a href=\"add0/Add.add.html\" title=\"enum in add0\">",
@@ -458,6 +506,7 @@
         "<a href=\"add3/add/add/Add.ADD.html\" title=\"enum in add3.add.add\">",
         "<a href=\"add3/add/add/add/Add.ADD.html\" title=\"enum in add3.add.add.add\">",
     };
+
     final static String expectedOverviewFrameOrdering[] = {
         "<a href=\"package-frame.html\" target=\"packageFrame\">&lt;unnamed package&gt;</a>",
         "<a href=\"add0/package-frame.html\" target=\"packageFrame\">add0</a>",
@@ -477,11 +526,13 @@
         "<a href=\"add3/add/add/package-frame.html\" target=\"packageFrame\">add3.add.add</a>",
         "<a href=\"add3/add/add/add/package-frame.html\" target=\"packageFrame\">add3.add.add.add</a></li>"
     };
+
     final static String expectedImplementsOrdering[] = {
         "<dd><code>close</code>&nbsp;in interface&nbsp;<code>java.lang.AutoCloseable</code></dd>",
         "<dd><code>close</code>&nbsp;in interface&nbsp;<code>java.nio.channels.Channel</code></dd>",
         "<dd><code>close</code>&nbsp;in interface&nbsp;<code>java.io.Closeable</code></dd>"
     };
+
     final static String expectedOverrideOrdering[] = {
         "<dd><code>iterator</code>&nbsp;in interface&nbsp;<code>java.util.Collection&lt;",
         "<dd><code>iterator</code>&nbsp;in interface&nbsp;<code>java.lang.Iterable&lt;"
--- a/langtools/test/jdk/javadoc/tool/6964914/TestStdDoclet.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/jdk/javadoc/tool/6964914/TestStdDoclet.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
  */
 
 import java.io.*;
+import java.util.*;
 
 /**
  * Dummy javadoc comment.
@@ -54,13 +55,21 @@
         // run javadoc in separate process to ensure doclet executed under
         // normal user conditions w.r.t. classloader
         String thisClassName = TestStdDoclet.class.getName();
-        Process p = new ProcessBuilder()
-            .command(javadoc.getPath(),
-                "-J-Xpatch:" + System.getProperty("jdk.launcher.patch.0", ""),
+        List<String> cmdArgs = new ArrayList<>();
+        cmdArgs.add(javadoc.getPath());
+        int i = 0;
+        String prop;
+        while ((prop = System.getProperty("jdk.launcher.patch." + (i++))) != null) {
+            cmdArgs.add("-J-Xpatch:" + prop);
+        }
+        cmdArgs.addAll(Arrays.asList(
                 "-classpath", ".", // insulates us from ambient classpath
                 "-Xdoclint:none",
                 "-package",
-                new File(testSrc, thisClassName + ".java").getPath())
+                new File(testSrc, thisClassName + ".java").getPath()
+        ));
+        Process p = new ProcessBuilder()
+            .command(cmdArgs)
             .redirectErrorStream(true)
             .start();
 
--- a/langtools/test/jdk/javadoc/tool/6964914/TestUserDoclet.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/jdk/javadoc/tool/6964914/TestUserDoclet.java	Thu Apr 28 23:08:16 2016 -0700
@@ -30,7 +30,10 @@
 
 import java.io.*;
 
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
+import java.util.List;
 import java.util.Locale;
 import java.util.Set;
 
@@ -63,12 +66,20 @@
         // run javadoc in separate process to ensure doclet executed under
         // normal user conditions w.r.t. classloader
         String thisClassName = TestUserDoclet.class.getName();
-        Process p = new ProcessBuilder()
-            .command(javadoc.getPath(),
-                "-J-Xpatch:" + System.getProperty("jdk.launcher.patch.0", ""),
+        List<String> cmdArgs = new ArrayList<>();
+        cmdArgs.add(javadoc.getPath());
+        int i = 0;
+        String prop;
+        while ((prop = System.getProperty("jdk.launcher.patch." + (i++))) != null) {
+            cmdArgs.add("-J-Xpatch:" + prop);
+        }
+        cmdArgs.addAll(Arrays.asList(
                 "-doclet", thisClassName,
                 "-docletpath", testClasses.getPath(),
-                new File(testSrc, thisClassName + ".java").getPath())
+                new File(testSrc, thisClassName + ".java").getPath()
+        ));
+        Process p = new ProcessBuilder()
+            .command(cmdArgs)
             .redirectErrorStream(true)
             .start();
 
--- a/langtools/test/jdk/javadoc/tool/EnsureNewOldDoclet.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/jdk/javadoc/tool/EnsureNewOldDoclet.java	Thu Apr 28 23:08:16 2016 -0700
@@ -23,96 +23,349 @@
 
 /*
  * @test
- * @bug 8035473
- * @summary make sure the new doclet is invoked by default, and -Xold
+ * @bug 8035473 8154482
+ * @summary make sure the javadoc tool responds correctly to Xold,
+ *          old doclets and taglets.
+ * @library /tools/lib
+ * @build toolbox.ToolBox toolbox.TestRunner
+ * @run main EnsureNewOldDoclet
  */
 
 import java.io.*;
-import java.util.ArrayList;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import com.sun.javadoc.Tag;
+import com.sun.source.doctree.DocTree;
+
+import toolbox.*;
+
 
 /**
- * Dummy javadoc comment.
+ * This test ensures the doclet responds correctly when given
+ * various conditions that force a fall back to the old javadoc
+ * tool. The following condition in the order described will
+ * force a dispatch to the old tool, -Xold, old doclet and old taglet.
+ *
  */
-public class EnsureNewOldDoclet {
+public class EnsureNewOldDoclet extends TestRunner {
+
+    final ToolBox tb;
+    final File testSrc;
+    final Path javadocPath;
+    final ExecTask task;
+    final String testClasses;
+    final PrintStream ostream;
 
-    final File javadoc;
-    final File testSrc;
-    final String thisClassName;
+    final static String CLASS_NAME = "EnsureNewOldDoclet";
+    final static String OLD_DOCLET_CLASS_NAME = CLASS_NAME + "$OldDoclet";
+    final static String NEW_DOCLET_CLASS_NAME = CLASS_NAME + "$NewDoclet"; //unused
+    final static String OLD_TAGLET_CLASS_NAME = CLASS_NAME + "$OldTaglet";
+    final static String NEW_TAGLET_CLASS_NAME = CLASS_NAME + "$NewTaglet";
+
+    final static Pattern OLD_HEADER = Pattern.compile("^Standard Doclet \\(Old\\) version.*");
+    final static Pattern NEW_HEADER = Pattern.compile("^Standard Doclet version.*");
+
+
+    final static String OLD_DOCLET_MARKER = "OLD_DOCLET_MARKER";
+    final static String OLD_TAGLET_MARKER = "Registered: OldTaglet";
+
+    final static String NEW_DOCLET_MARKER = "NEW_DOCLET_MARKER";
+    final static String NEW_TAGLET_MARKER = "Registered Taglet " + CLASS_NAME + "\\$NewTaglet";
 
-    final static Pattern Expected1 = Pattern.compile("^Standard Doclet \\(Next\\) version.*");
-    final static Pattern Expected2 = Pattern.compile("^Standard Doclet version.*");
+    final static Pattern WARN_TEXT = Pattern.compile("Users are strongly recommended to migrate" +
+                                                    " to the new APIs.");
+    final static String OLD_DOCLET_ERROR = "java.lang.NoSuchMethodException: " +
+            CLASS_NAME +"\\$NewTaglet";
+    final static Pattern NEW_DOCLET_ERROR = Pattern.compile(".*java.lang.ClassCastException.*Taglet " +
+            CLASS_NAME + "\\$OldTaglet.*");
+
+    final static String OLD_STDDOCLET = "com.sun.tools.doclets.standard.Standard";
+    final static String NEW_STDDOCLET = "jdk.javadoc.internal.doclets.standard.Standard";
+
 
-    public EnsureNewOldDoclet() {
-        File javaHome = new File(System.getProperty("java.home"));
-        if (javaHome.getName().endsWith("jre"))
-            javaHome = javaHome.getParentFile();
-        javadoc = new File(new File(javaHome, "bin"), "javadoc");
-        testSrc = new File(System.getProperty("test.src"));
-        thisClassName = EnsureNewOldDoclet.class.getName();
+    public EnsureNewOldDoclet() throws Exception {
+        super(System.err);
+        ostream = System.err;
+        testClasses = System.getProperty("test.classes");
+        tb = new ToolBox();
+        javadocPath = tb.getJDKTool("javadoc");
+        task = new ExecTask(tb, javadocPath);
+        testSrc = new File("Foo.java");
+        generateSample(testSrc);
+    }
+
+    void generateSample(File testSrc) throws Exception {
+        String nl = System.getProperty("line.separator");
+        String src = Arrays.asList(
+            "/**",
+            " * A test class to test javadoc. Nothing more nothing less.",
+            " */",
+            " public class Foo{}").stream().collect(Collectors.joining(nl));
+        tb.writeFile(testSrc.getPath(), src);
     }
 
     public static void main(String... args) throws Exception {
-        EnsureNewOldDoclet test = new EnsureNewOldDoclet();
-        test.run1();
-        test.run2();
+        new EnsureNewOldDoclet().runTests();
+    }
+
+    // input: nothing, default mode
+    // outcome: new tool and new doclet
+    @Test
+    public void testDefault() throws Exception {
+        setArgs("-classpath", ".", // insulates us from ambient classpath
+                  testSrc.toString());
+        Task.Result tr = task.run(Task.Expect.SUCCESS);
+        List<String> out = tr.getOutputLines(Task.OutputKind.STDOUT);
+        checkOutput(testName, out, NEW_HEADER);
+    }
+
+    // input: -Xold
+    // outcome: old tool
+    @Test
+    public void testXold() throws Exception {
+        setArgs("-Xold",
+                "-classpath", ".", // ambient classpath insulation
+                testSrc.toString());
+        Task.Result tr = task.run(Task.Expect.SUCCESS);
+        List<String> out = tr.getOutputLines(Task.OutputKind.STDOUT);
+        List<String> err = tr.getOutputLines(Task.OutputKind.STDERR);
+        checkOutput(testName, out, OLD_HEADER);
+        checkOutput(testName, err, WARN_TEXT);
+    }
+
+    // input: old doclet
+    // outcome: old tool
+    @Test
+    public void testOldDoclet() throws Exception {
+        setArgs("-classpath", ".", // ambient classpath insulation
+                "-doclet",
+                OLD_DOCLET_CLASS_NAME,
+                "-docletpath",
+                testClasses,
+                testSrc.toString());
+        Task.Result tr = task.run(Task.Expect.SUCCESS);
+        List<String> out = tr.getOutputLines(Task.OutputKind.STDOUT);
+        List<String> err = tr.getOutputLines(Task.OutputKind.STDERR);
+        checkOutput(testName, out, OLD_DOCLET_MARKER);
+        checkOutput(testName, err, WARN_TEXT);
+    }
+
+    // input: old taglet
+    // outcome: old tool
+    @Test
+    public void testOldTaglet() throws Exception {
+        setArgs("-classpath", ".", // ambient classpath insulation
+            "-taglet",
+            OLD_TAGLET_CLASS_NAME,
+            "-tagletpath",
+            testClasses,
+            testSrc.toString());
+        Task.Result tr = task.run(Task.Expect.SUCCESS);
+        List<String> out = tr.getOutputLines(Task.OutputKind.STDOUT);
+        List<String> err = tr.getOutputLines(Task.OutputKind.STDERR);
+        checkOutput(testName, out, OLD_TAGLET_MARKER);
+        checkOutput(testName, err, WARN_TEXT);
     }
 
-    // make sure new doclet is invoked by default
-    void run1() throws Exception {
-        List<String> output = doTest(javadoc.getPath(),
-                "-classpath", ".", // insulates us from ambient classpath
-                "-Xdoclint:none",
-                "-package",
-                new File(testSrc, thisClassName + ".java").getPath());
-        System.out.println(output);
-        for (String x : output) {
-            if (Expected1.matcher(x).matches()) {
+    // input: new doclet and old taglet
+    // outcome: new doclet with failure
+    @Test
+    public void testNewDocletOldTaglet() throws Exception {
+        setArgs("-classpath", ".", // ambient classpath insulation
+                "-doclet",
+                NEW_STDDOCLET,
+                "-taglet",
+                OLD_TAGLET_CLASS_NAME,
+                "-tagletpath",
+                testClasses,
+                testSrc.toString());
+        Task.Result tr = task.run(Task.Expect.FAIL, 1);
+        //Task.Result tr = task.run();
+        List<String> out = tr.getOutputLines(Task.OutputKind.STDOUT);
+        List<String> err = tr.getOutputLines(Task.OutputKind.STDERR);
+        checkOutput(testName, out, NEW_HEADER);
+        checkOutput(testName, err, NEW_DOCLET_ERROR);
+    }
+
+    // input: old doclet and old taglet
+    // outcome: old doclet and old taglet should register
+    @Test
+    public void testOldDocletOldTaglet() throws Exception {
+        setArgs("-classpath", ".", // ambient classpath insulation
+                "-doclet",
+                OLD_STDDOCLET,
+                "-taglet",
+                OLD_TAGLET_CLASS_NAME,
+                "-tagletpath",
+                testClasses,
+                testSrc.toString());
+        Task.Result tr = task.run(Task.Expect.SUCCESS);
+        List<String> out = tr.getOutputLines(Task.OutputKind.STDOUT);
+        List<String> err = tr.getOutputLines(Task.OutputKind.STDERR);
+        checkOutput(testName, out, OLD_HEADER);
+        checkOutput(testName, out, OLD_TAGLET_MARKER);
+        checkOutput(testName, err, WARN_TEXT);
+    }
+
+    // input: new doclet and new taglet
+    // outcome: new doclet and new taglet should register
+    @Test
+    public void testNewDocletNewTaglet() throws Exception {
+        setArgs("-classpath", ".", // ambient classpath insulation
+                "-doclet",
+                NEW_STDDOCLET,
+                "-taglet",
+                NEW_TAGLET_CLASS_NAME,
+                "-tagletpath",
+                testClasses,
+                testSrc.toString());
+        Task.Result tr = task.run(Task.Expect.SUCCESS);
+        List<String> out = tr.getOutputLines(Task.OutputKind.STDOUT);
+        List<String> err = tr.getOutputLines(Task.OutputKind.STDERR);
+        checkOutput(testName, out, NEW_HEADER);
+        checkOutput(testName, out, NEW_TAGLET_MARKER);
+    }
+
+    // input: old doclet and new taglet
+    // outcome: old doclet and error
+    @Test
+    public void testOldDocletNewTaglet() throws Exception {
+        setArgs("-classpath", ".", // ambient classpath insulation
+                "-doclet",
+                OLD_STDDOCLET,
+                "-taglet",
+                NEW_TAGLET_CLASS_NAME,
+                "-tagletpath",
+                testClasses,
+                testSrc.toString());
+        Task.Result tr = task.run(Task.Expect.FAIL, 1);
+        List<String> out = tr.getOutputLines(Task.OutputKind.STDOUT);
+        List<String> err = tr.getOutputLines(Task.OutputKind.STDERR);
+        checkOutput(testName, out, OLD_HEADER);
+        checkOutput(testName, err, WARN_TEXT);
+        checkOutput(testName, err, OLD_DOCLET_ERROR);
+    }
+
+    void setArgs(String... args) {
+        ostream.println("cmds: " + Arrays.asList(args));
+        task.args(args);
+    }
+
+    void checkOutput(String testCase, List<String> content, String toFind) throws Exception {
+        checkOutput(testCase, content, Pattern.compile(".*" + toFind + ".*"));
+    }
+
+    void checkOutput(String testCase, List<String> content, Pattern toFind) throws Exception {
+        ostream.println("---" + testCase + "---");
+        content.stream().forEach(x -> System.out.println(x));
+        for (String x : content) {
+            ostream.println(x);
+            if (toFind.matcher(x).matches()) {
                 return;
             }
         }
-        throw new Exception("run1: Expected string not found:");
+        throw new Exception(testCase + ": Expected string not found: " +  toFind);
     }
 
-    // make sure the old doclet is invoked with -Xold
-    void run2() throws Exception {
-        List<String> output = doTest(javadoc.getPath(),
-                "-Xold",
-                "-classpath", ".", // insulates us from ambient classpath
-                "-Xdoclint:none",
-                "-package",
-                new File(testSrc, thisClassName + ".java").getPath());
-
-        for (String x : output) {
-            if (Expected2.matcher(x).matches()) {
-                throw new Exception("run2: Expected string not found");
-            }
-            return;
+    public static class OldDoclet extends com.sun.javadoc.Doclet {
+        public static boolean start(com.sun.javadoc.RootDoc root) {
+            System.out.println(OLD_DOCLET_MARKER);
+            return true;
         }
     }
 
-    /**
-     * More dummy comments.
-     */
-    List<String> doTest(String... args) throws Exception {
-        List<String> output = new ArrayList<>();
-        // run javadoc in separate process to ensure doclet executed under
-        // normal user conditions w.r.t. classloader
-        Process p = new ProcessBuilder()
-                .command(args)
-                .redirectErrorStream(true)
-                .start();
-        try (BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
-            String line = in.readLine();
-            while (line != null) {
-                output.add(line.trim());
-                line = in.readLine();
-            }
+    public static class OldTaglet implements com.sun.tools.doclets.Taglet {
+
+        public static void register(Map map) {
+            EnsureNewOldDoclet.OldTaglet tag = new OldTaglet();
+            com.sun.tools.doclets.Taglet t = (com.sun.tools.doclets.Taglet) map.get(tag.getName());
+            System.out.println(OLD_TAGLET_MARKER);
+        }
+
+        @Override
+        public boolean inField() {
+            return true;
+        }
+
+        @Override
+        public boolean inConstructor() {
+            return true;
+        }
+
+        @Override
+        public boolean inMethod() {
+            return true;
+        }
+
+        @Override
+        public boolean inOverview() {
+            return true;
+        }
+
+        @Override
+        public boolean inPackage() {
+            return true;
+        }
+
+        @Override
+        public boolean inType() {
+            return true;
+        }
+
+        @Override
+        public boolean isInlineTag() {
+            return true;
         }
-        int rc = p.waitFor();
-        if (rc != 0)
-            throw new Exception("javadoc failed, rc:" + rc);
-        return output;
+
+        @Override
+        public String getName() {
+            return "OldTaglet";
+        }
+
+        @Override
+        public String toString(Tag tag) {
+            return getName();
+        }
+
+        @Override
+        public String toString(Tag[] tags) {
+            return getName();
+        }
+    }
+
+    public static class NewTaglet implements jdk.javadoc.doclet.taglet.Taglet {
+
+        @Override
+        public Set<Location> getAllowedLocations() {
+            return Collections.emptySet();
+        }
+
+        @Override
+        public boolean isInlineTag() {
+            return true;
+        }
+
+        @Override
+        public String getName() {
+            return "NewTaglet";
+        }
+
+        @Override
+        public String toString(DocTree tag) {
+            return tag.toString();
+        }
+
+        @Override
+        public String toString(List<? extends DocTree> tags) {
+            return tags.toString();
+        }
+
     }
 }
--- a/langtools/test/jdk/javadoc/tool/sampleapi/lib/sampleapi/SampleApi.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/jdk/javadoc/tool/sampleapi/lib/sampleapi/SampleApi.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, 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
@@ -53,5 +53,8 @@
         public Fault(String msg) {
             super(msg);
         }
+        public Fault(String msg, Throwable th) {
+            super(msg, th);
+        }
     }
 }
--- a/langtools/test/jdk/javadoc/tool/sampleapi/lib/sampleapi/generator/DocCommentGenerator.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/jdk/javadoc/tool/sampleapi/lib/sampleapi/generator/DocCommentGenerator.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, 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
@@ -32,6 +32,8 @@
 import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.util.List;
+import java.util.HashMap;
+import java.util.Map;
 
 class DocCommentGenerator {
 
@@ -99,14 +101,25 @@
         LITERAL("@literal", "Use < and > brackets instead of &lt; and &gt; escapes."),
         CODE("@code", "(i) -> new Abc<Object>((i > 0) ? (i << 1) : 0)"),
         LINK("@link", ""),
-        VALUE("@value", "");
+        VALUE("@value", ""),
+        INDEX("@index", "", true);
 
         String tagName;
         String tagValue;
+        boolean counted;
+        Map<String, Integer> counters;
 
         InlineTag(String tagName, String tagValue) {
+            this(tagName, tagValue, false);
+        }
+
+        InlineTag(String tagName, String tagValue, boolean counted) {
             this.tagName = tagName;
             this.tagValue = tagValue;
+            this.counted = counted;
+            if (counted) {
+                counters = new HashMap<>();
+            }
         }
 
         public String toString() {
@@ -114,9 +127,14 @@
         }
 
         public String value(String value) {
+            String name = ((tagValue.length() != 0) ? " " + tagValue : "")
+                   + ((value.length() != 0) ? " " + value : "");
+            if (counted && !counters.containsKey(name)) {
+                counters.put(name, 0);
+            }
             return "{" + tagName
-                   + ((tagValue.length() != 0) ? " " + tagValue : "")
-                   + ((value.length() != 0) ? " " + value : "")
+                   + name
+                   + (counted ? "_" + counters.put(name, counters.get(name) + 1) : "")
                    + "}";
         }
     }
@@ -179,7 +197,8 @@
     //
 
     public String getPackageComment() {
-        return Text.LOREMIPSUM
+        return InlineTag.INDEX.value("PackageCommentLabel") + " "
+               + Text.LOREMIPSUM
                + "\n <p>" + Text.LIEUROPANLINGUES
                + "\n" + Text.CODE
                + "\n" + LinkTag.nextLink()
@@ -192,7 +211,9 @@
     static int serialValIdx = 0;
 
     public String getBaseComment(JCClassDecl baseDecl, boolean toplevel) {
-        String buildComment = Text.LIEUROPANLINGUES + "\n";
+        String buildComment = InlineTag.INDEX.value("BaseCommentLabel") + " ";
+
+        buildComment += Text.LIEUROPANLINGUES + "\n";
 
         buildComment += "<p>It is possible to see inlined code:\n"
                         + InlineTag.CODE
@@ -237,8 +258,9 @@
     }
 
     public String getConstComment() {
-        String buildComment = Text.NOWISTHETIME + " " + Text.BROWNFOX + "\n";
+        String buildComment = InlineTag.INDEX.value("ConstCommentLabel") + " ";
 
+        buildComment += Text.NOWISTHETIME + " " + Text.BROWNFOX + "\n";
         buildComment += LinkTag.nextLink() + "\n";
         buildComment += LinkTag.nextSee() + "\n";
         buildComment += Tag.SINCE + "\n";
@@ -249,8 +271,9 @@
     public String getFieldComment(JCClassDecl baseDecl,
                                   JCVariableDecl varDecl,
                                   boolean isFxStyle) {
-        String buildComment = Text.BROWNFOX + "<p>" + Text.NOWISTHETIME + "\n";
+        String buildComment = InlineTag.INDEX.value("FieldCommentLabel") + " ";
 
+        buildComment += Text.BROWNFOX + "<p>" + Text.NOWISTHETIME + "\n";
         Set<Modifier> mods = varDecl.getModifiers().getFlags();
         String varName = varDecl.getName().toString();
 
@@ -299,7 +322,9 @@
     public String getMethodComment(JCClassDecl baseDecl,
                                    JCMethodDecl methodDecl,
                                    boolean isFxStyle) {
-        String buildComment = Text.BROWNFOX + "\n<p>" + Text.THISPANGRAM + "\n";
+        String buildComment = InlineTag.INDEX.value("MethodCommentLabel") + " ";
+
+        buildComment += Text.BROWNFOX + "\n<p>" + Text.THISPANGRAM + "\n";
 
         buildComment += "<p>" + LinkTag.nextLink() + "\n";
 
--- a/langtools/test/jdk/javadoc/tool/sampleapi/lib/sampleapi/generator/PackageGenerator.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/jdk/javadoc/tool/sampleapi/lib/sampleapi/generator/PackageGenerator.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, 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
@@ -125,7 +125,7 @@
                 processTopLevel((Element)node);
             }
         } catch (ParserConfigurationException | SAXException | IOException e) {
-            throw new Fault("Error parsing dataset " + dsName);
+            throw new Fault("Error parsing dataset " + dsName, e);
         }
 
         fx = false;
--- a/langtools/test/jdk/jshell/ClassesTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/jdk/jshell/ClassesTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -47,6 +47,7 @@
 import static jdk.jshell.Snippet.Status.DROPPED;
 import static jdk.jshell.Snippet.Status.REJECTED;
 import static jdk.jshell.Snippet.Status.OVERWRITTEN;
+import static jdk.jshell.Snippet.Status.NONEXISTENT;
 import static jdk.jshell.Snippet.SubKind.*;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
@@ -83,7 +84,7 @@
         TypeDeclSnippet c1 = (TypeDeclSnippet) assertDeclareFail("class A { void f() { return g(); } }", "compiler.err.prob.found.req");
         assertTypeDeclSnippet(c1, "A", REJECTED, CLASS_SUBKIND, 0, 2);
         TypeDeclSnippet c2 = classKey(assertEval("class A { int f() { return g(); } }",
-                ste(c1, REJECTED, RECOVERABLE_DEFINED, true, null)));
+                ste(c1, NONEXISTENT, RECOVERABLE_DEFINED, true, null)));
         assertTypeDeclSnippet(c2, "A", RECOVERABLE_DEFINED, CLASS_SUBKIND, 1, 0);
         assertDrop(c2,
                 ste(c2, RECOVERABLE_DEFINED, DROPPED, true, null));
@@ -176,6 +177,7 @@
         assertActiveKeys();
     }
 
+    //8154496: test3 update: sig change should false
     public void classesRedeclaration3() {
         Snippet a = classKey(assertEval("class A { }"));
         assertClasses(clazz(KullaTesting.ClassType.CLASS, "A"));
@@ -190,7 +192,7 @@
                 ste(MAIN_SNIPPET, VALID, VALID, true, null),
                 ste(test1, VALID, VALID, true, MAIN_SNIPPET),
                 ste(test2, VALID, VALID, true, MAIN_SNIPPET),
-                ste(test3, VALID, VALID, false, MAIN_SNIPPET),
+                ste(test3, VALID, VALID, true, MAIN_SNIPPET),
                 ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
         assertClasses(clazz(KullaTesting.ClassType.INTERFACE, "A"));
         assertMethods(method("()A", "test"), method("(A)void", "test"), method("(int)void", "test"));
@@ -201,8 +203,7 @@
         Snippet b = classKey(assertEval("class B extends A { }",
                 added(RECOVERABLE_NOT_DEFINED)));
         Snippet a = classKey(assertEval("class A extends B { }", DiagCheck.DIAG_IGNORE, DiagCheck.DIAG_IGNORE,
-                added(RECOVERABLE_NOT_DEFINED),
-                ste(b, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, MAIN_SNIPPET)));
+                added(REJECTED)));
         /***
         assertDeclareFail("class A extends B { }", "****",
                 added(REJECTED),
--- a/langtools/test/jdk/jshell/DropTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/jdk/jshell/DropTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -57,10 +57,10 @@
         assertActiveKeys();
 
         method = methodKey(assertEval("int mu() { return x * 4; }",
-                ste(MAIN_SNIPPET, DROPPED, RECOVERABLE_DEFINED, true, null),
+                added(RECOVERABLE_DEFINED),
                 ste(clazz, RECOVERABLE_DEFINED, VALID, false, MAIN_SNIPPET)));
         assertEval("int x = 10;", "10",
-                ste(MAIN_SNIPPET, DROPPED, VALID, true, null),
+                added(VALID),
                 ste(method, RECOVERABLE_DEFINED, VALID, false, MAIN_SNIPPET));
         PersistentSnippet c0 = varKey(assertEval("C c0 = new C();"));
         assertEval("c0.v();", "\"#40\"");
@@ -189,12 +189,11 @@
         assertDrop(c,
                 DiagCheck.DIAG_OK,
                 DiagCheck.DIAG_ERROR,
-                ste(c, RECOVERABLE_NOT_DEFINED, DROPPED, false, null),
-                ste(d, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, c));
+                ste(c, RECOVERABLE_NOT_DEFINED, DROPPED, false, null));
         assertEval("interface A {}", null, null,
-                DiagCheck.DIAG_OK, DiagCheck.DIAG_ERROR,
-                ste(a, DROPPED, VALID, true, null),
-                ste(b, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, MAIN_SNIPPET));
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                added(VALID));
         assertClasses();
         assertActiveKeys();
     }
--- a/langtools/test/jdk/jshell/KullaTesting.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/jdk/jshell/KullaTesting.java	Thu Apr 28 23:08:16 2016 -0700
@@ -651,7 +651,7 @@
                 DiagCheck.DIAG_WARNING, DiagCheck.DIAG_IGNORE, mainInfo, updates);
         SnippetEvent e = events.get(0);
         List<Diag> diagnostics = getState().diagnostics(e.snippet());
-        assertDiagnostic(input, diagnostics.get(0), expectedDiagnostic);
+        if (expectedDiagnostic != null) assertDiagnostic(input, diagnostics.get(0), expectedDiagnostic);
         return e.snippet();
     }
 
--- a/langtools/test/jdk/jshell/MethodsTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/jdk/jshell/MethodsTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, 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
@@ -58,7 +58,7 @@
         MethodSnippet m1 = (MethodSnippet) assertDeclareFail("void f() { return g(); }", "compiler.err.prob.found.req");
         assertMethodDeclSnippet(m1, "f", "()void", REJECTED, 0, 2);
         MethodSnippet m2 = methodKey(assertEval("int f() { return g(); }",
-                ste(m1, REJECTED, RECOVERABLE_DEFINED, true, null)));
+                added(RECOVERABLE_DEFINED)));
         assertMethodDeclSnippet(m1, "f", "()void", REJECTED, 0, 2);
         assertMethodDeclSnippet(m2, "f", "()int", RECOVERABLE_DEFINED, 1, 0);
     }
@@ -115,6 +115,26 @@
         assertActiveKeys();
     }
 
+    /***
+    public void methodOverloadDependent() {
+        assertEval("String m(String s) { return s + s; }");
+        assertEval("String m(double d) { return m(\"#\" + d); }");
+        assertEval("String m(int x) { return m(2.25 * x); }");
+        assertEval("String m() { return m(3); }");
+        assertMethods(
+                method("(String)String", "m"),
+                method("(double)String", "m"),
+                method("(int)String", "m"),
+                method("()String", "m")
+        );
+        assertEval("m();", "\"#6.75#6.75\"");
+        assertEval("m(2);", "\"#4.5#4.5\"");
+        assertEval("m(3.14);", "\"#3.14#3.14\"");
+        assertEval("m(\"hi\");", "\"hihi\"");
+        assertActiveKeys();
+    }
+    ***/
+
     public void methodsRedeclaration1() {
         Snippet x = methodKey(assertEval("int x() { return 10; }"));
         Snippet y = methodKey(assertEval("String y() { return \"\"; }"));
@@ -149,8 +169,7 @@
 
         assertEval("double b() { return 3.14159; }",
                 ste(MAIN_SNIPPET, VALID, VALID, true, null),
-                ste(b, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
-                ste(c, VALID, VALID, false, MAIN_SNIPPET));
+                ste(b, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
         assertMethods(method("()int", "a"), method("()double", "b"), method("()double", "c"));
         assertEval("c();", "3.14159");
         assertActiveKeys();
@@ -202,7 +221,7 @@
         assertActiveKeys();
 
         assertDeclareFail("int f() {}", "compiler.err.missing.ret.stmt",
-                ste(MAIN_SNIPPET, REJECTED, REJECTED, false, null));
+                added(REJECTED));
         assertNumberOfActiveMethods(0);
         assertActiveKeys();
 
--- a/langtools/test/jdk/jshell/ReplaceTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/jdk/jshell/ReplaceTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -97,8 +97,7 @@
         assertEval("mu() == 0.0;", "true");
         assertEval("double x = 2.5;",
                 ste(MAIN_SNIPPET, VALID, VALID, true, null),
-                ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
-                ste(musn, VALID, VALID, false, MAIN_SNIPPET));
+                ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
         Collection<MethodSnippet> meths = getState().methods();
         assertEquals(meths.size(), 1);
         assertTrue(musn == meths.iterator().next(), "Identity must not change");
@@ -115,8 +114,7 @@
         assertEval("d();", "1060.0");
         assertEval("int a() { return 5; }",
                 ste(MAIN_SNIPPET, VALID, VALID, true, null),
-                ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
-                ste(b, VALID, VALID, false, MAIN_SNIPPET));
+                ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
         assertEval("d();", "1150.0");
         assertActiveKeys();
     }
@@ -127,8 +125,7 @@
         assertEval("m();", "7");
         assertEval("class C { int x = 99; int f() { return x; } }",
                 ste(MAIN_SNIPPET, VALID, VALID, true, null),
-                ste(c, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
-                ste(m, VALID, VALID, false, MAIN_SNIPPET));
+                ste(c, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
         assertEval("m();", "99");
         assertActiveKeys();
     }
@@ -140,8 +137,7 @@
         assertEval("new A().a == 0.0;", "true");
         assertEval("double x = 2.5;",
                 ste(MAIN_SNIPPET, VALID, VALID, true, null),
-                ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
-                ste(c, VALID, VALID, false, MAIN_SNIPPET));
+                ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
         Collection<TypeDeclSnippet> classes = getState().types();
         assertEquals(classes.size(), 1);
         assertTrue(c == classes.iterator().next(), "Identity must not change");
@@ -157,8 +153,7 @@
         assertEval("new A().a == 0.0;", "true");
         assertEval("double x() { return 2.5; }",
                 ste(MAIN_SNIPPET, VALID, VALID, true, null),
-                ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
-                ste(c, VALID, VALID, false, MAIN_SNIPPET));
+                ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
         assertEval("x();", "2.5");
         Collection<TypeDeclSnippet> classes = getState().types();
         assertEquals(classes.size(), 1);
@@ -875,18 +870,15 @@
         MethodSnippet k1 = methodKey(assertEval(ms1, added(VALID)));
         VarSnippet xd = varKey(assertEval(xsd,
                 ste(MAIN_SNIPPET, VALID, VALID, true, null),
-                ste(xi, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
-                ste(k1, VALID, VALID, false, MAIN_SNIPPET)));
+                ste(xi, VALID, OVERWRITTEN, false, MAIN_SNIPPET)));
         MethodSnippet k2 = methodKey(assertEval(ms2,
                 ste(MAIN_SNIPPET, VALID, VALID, true, null), //TODO: technically, should be false
                 ste(k1, VALID, OVERWRITTEN, false, MAIN_SNIPPET)));
         VarSnippet xi2 = varKey(assertEval(xsi,
                 ste(MAIN_SNIPPET, VALID, VALID, true, null),
-                ste(xd, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
-                ste(k2, VALID, VALID, false, MAIN_SNIPPET)));
+                ste(xd, VALID, OVERWRITTEN, false, MAIN_SNIPPET)));
         varKey(assertEval(xsd,
                 ste(MAIN_SNIPPET, VALID, VALID, true, null),
-                ste(xi2, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
-                ste(k2, VALID, VALID, false, MAIN_SNIPPET)));
+                ste(xi2, VALID, OVERWRITTEN, false, MAIN_SNIPPET)));
     }
 }
--- a/langtools/test/jdk/jshell/SnippetStatusListenerTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/jdk/jshell/SnippetStatusListenerTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -65,7 +65,7 @@
         getState().unsubscribe(subscription1);
 
         assertDrop(f, DiagCheck.DIAG_IGNORE, DiagCheck.DIAG_IGNORE, ste(f, REJECTED, DROPPED, false, null));
-        assertEval("void f() { }", ste(MAIN_SNIPPET, DROPPED, VALID, true, null));
+        assertEval("void f() { }", added(VALID));
         assertEvalException("throw new RuntimeException();");
         assertEquals(listener1.getEvents(), events1, "Checking that unsubscribed listener does not get events");
 
--- a/langtools/test/jdk/jshell/SnippetTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/jdk/jshell/SnippetTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -142,8 +142,7 @@
         assertActiveKeys();
         assertEval("double f() { return 0.0; }",
                 ste(MAIN_SNIPPET, VALID, VALID, true, null),
-                ste(f, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
-                ste(g, VALID, VALID, false, MAIN_SNIPPET));
+                ste(f, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
         assertKeys(method("()void", "g"), clazz(KullaTesting.ClassType.INTERFACE, "A"),
                 method("()double", "f"));
         assertActiveKeys();
--- a/langtools/test/jdk/jshell/StartOptionTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/jdk/jshell/StartOptionTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -22,7 +22,7 @@
  */
 
 /*
- * @test
+ * @test 8151754
  * @summary Testing start-up options.
  * @modules jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.main
@@ -34,6 +34,7 @@
  */
 
 import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
 import java.io.PrintStream;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Path;
@@ -47,6 +48,7 @@
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
 
 @Test
 public class StartOptionTest {
@@ -55,9 +57,24 @@
     private ByteArrayOutputStream err;
 
     private JShellTool getShellTool() {
-        return new JShellTool(null, new PrintStream(out), new PrintStream(err), null, null, null,
-                              null, new ReplToolTesting.MemoryPreferences(),
-                              Locale.ROOT);
+        class NoOutputAllowedStream extends OutputStream {
+            private final String label;
+            NoOutputAllowedStream(String label) {
+               this.label = label;
+            }
+            @Override
+            public void write(int b) { fail("Unexpected output to: " + label); }
+        }
+        return new JShellTool(
+                new TestingInputStream(),
+                new PrintStream(out),
+                new PrintStream(err),
+                new PrintStream(new NoOutputAllowedStream("console")),
+                new TestingInputStream(),
+                new PrintStream(new NoOutputAllowedStream("userout")),
+                new PrintStream(new NoOutputAllowedStream("usererr")),
+                new ReplToolTesting.MemoryPreferences(),
+                Locale.ROOT);
     }
 
     private String getOutput() {
@@ -133,6 +150,12 @@
     }
 
     @Test
+    public void testNegFeedbackOption() throws Exception {
+        start("", "Argument to -feedback missing. Mode required.", "-feedback");
+        start("", "Does not match any current feedback mode: blorp -- -feedback blorp", "-feedback", "blorp");
+    }
+
+    @Test
     public void testVersion() throws Exception {
         start(s -> assertTrue(s.startsWith("jshell")), null, "-version");
     }
--- a/langtools/test/jdk/jshell/ToolFormatTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/jdk/jshell/ToolFormatTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8148316 8148317 8151755 8152246
+ * @bug 8148316 8148317 8151755 8152246 8153551
  * @summary Tests for output customization
  * @library /tools/lib
  * @modules jdk.compiler/com.sun.tools.javac.api
@@ -155,6 +155,12 @@
         }
     }
 
+    public void testShowFeedbackModes() {
+        test(
+                (a) -> assertCommandOutputContains(a, "/set feedback", "normal")
+        );
+    }
+
     public void testSetNewModeQuiet() {
         try {
             test(
--- a/langtools/test/jdk/jshell/ToolSimpleTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/jdk/jshell/ToolSimpleTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8153716 8143955
+ * @bug 8153716 8143955 8151754 8150382
  * @summary Simple jshell tool tests
  * @modules jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.main
@@ -349,4 +349,39 @@
             System.setProperty("java.awt.headless", prevHeadless==null? "false" : prevHeadless);
         }
     }
+
+    public void testOptionQ() {
+        test(new String[]{"-q", "-nostartup"},
+                (a) -> assertCommand(a, "1+1", "$1 ==> 2"),
+                (a) -> assertCommand(a, "int x = 5", "")
+        );
+    }
+
+    public void testOptionQq() {
+        test(new String[]{"-qq", "-nostartup"},
+                (a) -> assertCommand(a, "1+1", "")
+        );
+    }
+
+    public void testOptionV() {
+        test(new String[]{"-v", "-nostartup"},
+                (a) -> assertCommand(a, "1+1",
+                        "$1 ==> 2\n" +
+                        "|  created scratch variable $1 : int")
+        );
+    }
+
+    public void testOptionFeedback() {
+        test(new String[]{"-feedback", "concise", "-nostartup"},
+                (a) -> assertCommand(a, "1+1", "$1 ==> 2"),
+                (a) -> assertCommand(a, "int x = 5", "")
+        );
+    }
+
+    public void testOptionR() {
+        test(new String[]{"-R-Dthe.sound=blorp", "-nostartup"},
+                (a) -> assertCommand(a, "System.getProperty(\"the.sound\")",
+                        "$1 ==> \"blorp\"")
+        );
+    }
 }
--- a/langtools/test/jdk/jshell/VariablesTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/jdk/jshell/VariablesTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -83,7 +83,7 @@
     public void testVarValue2() {
         VarSnippet v1 = (VarSnippet) assertDeclareFail("int a = 0.0;", "compiler.err.prob.found.req");
         badVarValue(v1);
-        VarSnippet v2 = varKey(assertEval("int a = 0;", ste(v1, REJECTED, VALID, true, null)));
+        VarSnippet v2 = varKey(assertEval("int a = 0;", added(VALID)));
         assertDrop(v2, ste(MAIN_SNIPPET, VALID, DROPPED, true, null));
         badVarValue(v2);
     }
@@ -111,7 +111,7 @@
         VarSnippet v1 = (VarSnippet) assertDeclareFail("int a = 0.0;", "compiler.err.prob.found.req");
         assertVariableDeclSnippet(v1, "a", "int", REJECTED, SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND, 0, 1);
         VarSnippet v2 = varKey(assertEval("int a = 0;",
-                ste(v1, REJECTED, VALID, true, null)));
+                added(VALID)));
         assertVariableDeclSnippet(v2, "a", "int", VALID, SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND, 0, 0);
         assertDrop(v2, ste(MAIN_SNIPPET, VALID, DROPPED, true, null));
         assertVariableDeclSnippet(v2, "a", "int", DROPPED, SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND, 0, 0);
--- a/langtools/test/tools/javac/6520152/T.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/6520152/T.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2016, 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.Serializable;
 
 public class T {
--- a/langtools/test/tools/javac/6520152/T6520152.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/6520152/T6520152.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2016, 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     6520152
--- a/langtools/test/tools/javac/6521805/T6521805e.out	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/6521805/T6521805e.out	Thu Apr 28 23:08:16 2016 -0700
@@ -1,2 +1,2 @@
-Sub.java:8:11: compiler.err.synthetic.name.conflict: this$0, p.Inner
+Sub.java:10:11: compiler.err.synthetic.name.conflict: this$0, p.Inner
 1 error
--- a/langtools/test/tools/javac/6521805/p/Outer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/6521805/p/Outer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,3 +1,5 @@
+/* /nodynamiccopyright/ */
+
 package p;
 
 class Outer {
--- a/langtools/test/tools/javac/6521805/p/Sub.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/6521805/p/Sub.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,3 +1,5 @@
+/* /nodynamiccopyright/ */
+
 package p;
 
 class Inner extends Outer.Super {
--- a/langtools/test/tools/javac/6547131/T.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/6547131/T.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2016, 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     6547131
--- a/langtools/test/tools/javac/6589361/T6589361.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/6589361/T6589361.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2016, 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     6589361
--- a/langtools/test/tools/javac/6668794/badSource/Test.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/6668794/badSource/Test.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * @test /nodynamiccopyight/
+ * @test /nodynamiccopyright/
  * @bug 6668794 6668796
  * @summary javac puts localized text in raw diagnostics
  *      bad diagnostic "bad class file" given for source files
--- a/langtools/test/tools/javac/CaptureInSubtype.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/CaptureInSubtype.java	Thu Apr 28 23:08:16 2016 -0700
@@ -33,7 +33,7 @@
 
 
     public static class ShowFlaw extends SuperOfShowFlaw {
-        static Flaw<Number> fn =  new Flaw<Number>(new Integer(3));
+        static Flaw<Number> fn =  new Flaw<Number>(Integer.valueOf(3));
 
         Flaw<?> m(){return fn;}
     }
--- a/langtools/test/tools/javac/OverrideChecks/T4721069.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/OverrideChecks/T4721069.java	Thu Apr 28 23:08:16 2016 -0700
@@ -12,7 +12,7 @@
     static class T {
         static void f(I i) {
             if (i == null) {
-                Integer x = new Integer(2);
+                Integer x = Integer.valueOf(2);
             } else {
                 I x = i;
                 x.getClass();
--- a/langtools/test/tools/javac/SerialWarn.java	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-/*
- * @test /nodynamiccopyright/
- * @bug 4854628
- * @summary include Throwable subclasses in missing serialVersionUID warning
- * @author gafter
- *
- * @compile                    -Werror SerialWarn.java
- * @compile/fail/ref=SerialWarn.out -XDrawDiagnostics -Xlint:serial -Werror SerialWarn.java
- */
-
-class SerialWarn extends Throwable {}
--- a/langtools/test/tools/javac/SerialWarn.out	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-SerialWarn.java:11:1: compiler.warn.missing.SVUID: SerialWarn
-- compiler.err.warnings.and.werror
-1 error
-1 warning
--- a/langtools/test/tools/javac/T6554097.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/T6554097.java	Thu Apr 28 23:08:16 2016 -0700
@@ -3,24 +3,27 @@
  * @bug     6554097
  * @summary "final" confuses at-SuppressWarnings
  * @compile T6554097.java
- * @compile/fail/ref=T6554097.out -XDrawDiagnostics -Werror -Xlint:serial T6554097.java
+ * @compile/fail/ref=T6554097.out -XDrawDiagnostics -Werror -Xlint:rawtypes T6554097.java
  */
 
+import java.util.ArrayList;
+
 class T6554097 {
-    @SuppressWarnings("serial") final Throwable[] v1 = { new Throwable() {} };
-    @SuppressWarnings("serial")       Throwable[] v2 = { new Throwable() {} };
+
+    @SuppressWarnings("unchecked") final ArrayList[] v1 = { new ArrayList() {} };
+    @SuppressWarnings("unchecked")       ArrayList[] v2 = { new ArrayList() {} };
 
     public static void m1() throws Throwable {
-            @SuppressWarnings("serial") final Throwable[] v3 = { new Throwable() {} };
-            @SuppressWarnings("serial")       Throwable[] v4 = { new Throwable() {} };
+            @SuppressWarnings("unchecked") final ArrayList[] v3 = { new ArrayList() {} };
+            @SuppressWarnings("unchecked")       ArrayList[] v4 = { new ArrayList() {} };
     }
 
-    final Throwable[] v5 = { new Throwable() {} };
-          Throwable[] v6 = { new Throwable() {} };
+    final ArrayList[] v5 = { new ArrayList() {} };
+          ArrayList[] v6 = { new ArrayList() {} };
 
     public static void m2() throws Throwable {
-        final Throwable[] v7 = { new Throwable() {} };
-                  Throwable[] v8 = { new Throwable() {} };
+        final ArrayList[] v7 = { new ArrayList() {} };
+              ArrayList[] v8 = { new ArrayList() {} };
     }
 }
 
--- a/langtools/test/tools/javac/T6554097.out	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/T6554097.out	Thu Apr 28 23:08:16 2016 -0700
@@ -1,7 +1,19 @@
-T6554097.java:18:46: compiler.warn.missing.SVUID: compiler.misc.anonymous.class: T6554097$5
-T6554097.java:19:46: compiler.warn.missing.SVUID: compiler.misc.anonymous.class: T6554097$6
-T6554097.java:22:50: compiler.warn.missing.SVUID: compiler.misc.anonymous.class: T6554097$7
-T6554097.java:23:54: compiler.warn.missing.SVUID: compiler.misc.anonymous.class: T6554097$8
+T6554097.java:13:42: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:13:65: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:14:42: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:14:65: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:17:50: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:17:73: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:18:50: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:18:73: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:21:11: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:21:34: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:22:11: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:22:34: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:25:15: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:25:38: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:26:15: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
+T6554097.java:26:38: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
 - compiler.err.warnings.and.werror
 1 error
-4 warnings
+16 warnings
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/TryWithResources/TwrAvoidNullCheck.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2016, 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 7020499
+ * @summary Verify that try-with-resources desugaring is not generating unnecessary null checks
+ * @library /tools/lib
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ *          jdk.compiler/com.sun.tools.javac.code
+ *          jdk.compiler/com.sun.tools.javac.comp
+ *          jdk.compiler/com.sun.tools.javac.main
+ *          jdk.compiler/com.sun.tools.javac.tree
+ *          jdk.compiler/com.sun.tools.javac.util
+ * @build toolbox.ToolBox toolbox.JavacTask TwrAvoidNullCheck
+ * @run main TwrAvoidNullCheck
+ */
+
+import java.io.IOException;
+import java.util.Arrays;
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.comp.AttrContext;
+import com.sun.tools.javac.comp.Env;
+import com.sun.tools.javac.comp.Lower;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.JCBinary;
+import com.sun.tools.javac.tree.TreeInfo;
+import com.sun.tools.javac.tree.TreeMaker;
+import com.sun.tools.javac.tree.TreeScanner;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Context.Factory;
+import com.sun.tools.javac.util.List;
+
+import toolbox.ToolBox;
+
+public class TwrAvoidNullCheck {
+    public static void main(String... args) throws IOException {
+        new TwrAvoidNullCheck().run();
+    }
+    void run() throws IOException {
+        run("new Test()", false);
+        run("null", true);
+        run("System.getProperty(\"test\") != null ? new Test() : null", true);
+    }
+    void run(String resourceSpecification, boolean expected) throws IOException {
+        String template = "public class Test implements AutoCloseable {\n" +
+                          "    void t() {\n" +
+                          "        try (Test resource = RESOURCE) { }\n" +
+                          "    }\n" +
+                          "    public void close() { }\n" +
+                          "}\n";
+        String code = template.replace("RESOURCE", resourceSpecification);
+        Context ctx = new Context();
+        DumpLower.preRegister(ctx);
+        Iterable<ToolBox.JavaSource> files = Arrays.asList(new ToolBox.JavaSource(code));
+        JavacTask task = JavacTool.create().getTask(null, null, null, null, null, files, ctx);
+        task.call();
+
+        boolean hasNullCheck = ((DumpLower) DumpLower.instance(ctx)).hasNullCheck;
+
+        if (hasNullCheck != expected) {
+            throw new IllegalStateException("expected: " + expected +
+                                            "; actual: " + hasNullCheck +
+                                            "; code: " + code);
+        }
+    }
+
+    static class DumpLower extends Lower {
+
+        public static void preRegister(Context ctx) {
+            ctx.put(lowerKey, new Factory<Lower>() {
+                @Override
+                public Lower make(Context c) {
+                    return new DumpLower(c);
+                }
+            });
+        }
+
+        public DumpLower(Context context) {
+            super(context);
+        }
+
+        boolean hasNullCheck;
+
+        @Override
+        public List<JCTree> translateTopLevelClass(Env<AttrContext> env, JCTree cdef, TreeMaker make) {
+            List<JCTree> result = super.translateTopLevelClass(env, cdef, make);
+
+            new TreeScanner() {
+                @Override
+                public void visitBinary(JCBinary tree) {
+                    hasNullCheck |= tree.operator.getSimpleName().contentEquals("!=") &&
+                                    "resource".equals(String.valueOf(TreeInfo.name(tree.lhs))) &&
+                                    TreeInfo.isNull(tree.rhs);
+                    super.visitBinary(tree);
+                }
+            }.scan(result);
+
+            return result;
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/TryWithResources/TwrClose.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2016, 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 7020499
+ * @summary Verify that the close resource code works properly in all cases
+ * @library /tools/lib
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ *          jdk.compiler/com.sun.tools.javac.comp
+ *          jdk.compiler/com.sun.tools.javac.main
+ * @build toolbox.ToolBox TwrClose
+ * @run main TwrClose
+ */
+
+import javax.tools.JavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+
+import com.sun.tools.javac.comp.Lower;
+
+import toolbox.JavacTask;
+import toolbox.ToolBox;
+
+public class TwrClose {
+
+    public static void main(String... args) throws Exception {
+        for (int i = 1; i < Lower.USE_CLOSE_RESOURCE_METHOD_THRESHOLD * 2; i++) {
+            new TwrClose().compile(i);
+        }
+    }
+
+    ToolBox tb = new ToolBox();
+    JavaFileManager fm = ToolProvider.getSystemJavaCompiler()
+                                     .getStandardFileManager(null, null, null);
+
+    void compile(int trysCount) throws Exception {
+        StringBuilder testInvocations = new StringBuilder();
+        StringBuilder testMethods = new StringBuilder();
+
+        for (int i = 0; i < trysCount; i++) {
+            testInvocations.append(TEST_INVOCATIONS_TEMPLATE.replace("#N", Integer.toString(i)));
+            testMethods.append(TEST_METHOD_TEMPLATE.replace("#N", Integer.toString(i)));
+        }
+
+        String sourceCode = FILE_TEMPLATE.replace("#TEST_INVOCATIONS", testInvocations.toString())
+                                         .replace("#TEST_METHODS", testMethods.toString());
+
+        System.err.println("analyzing:");
+        System.err.println(sourceCode);
+
+        try (ToolBox.MemoryFileManager mfm = new ToolBox.MemoryFileManager()) {
+            new JavacTask(tb).fileManager(mfm)
+                             .sources(sourceCode)
+                             .run()
+                             .writeAll();
+            ClassLoader cl = new ClassLoader(TwrClose.class.getClassLoader()) {
+                @Override
+                protected Class<?> findClass(String name) throws ClassNotFoundException {
+                    byte[] data = mfm.getFileBytes(StandardLocation.CLASS_OUTPUT, name);
+                    if (data != null) {
+                        return defineClass(name, data, 0, data.length);
+                    }
+                    return super.findClass(name);
+                }
+            };
+
+            ((Runnable) cl.loadClass("Test").newInstance()).run();
+        }
+    }
+
+    final String TEST_INVOCATIONS_TEMPLATE =
+        "        test#N(false, false, Arrays.asList(\"close\"));\n" +
+        "        test#N(false, true, Arrays.asList(\"close\", \"close-exception\"));\n" +
+        "        test#N(true, false, Arrays.asList(\"close\", \"inTwr\"));\n" +
+        "        test#N(true, true, Arrays.asList(\"close\", \"inTwr\", \"close-exception\"));\n";
+
+    final String TEST_METHOD_TEMPLATE =
+        "    private void test#N(boolean failInTwr, boolean failOnClose,\n" +
+        "                        List<String> expectedMessages) {\n" +
+        "        List<String> messages = new ArrayList<>();\n" +
+        "        try {\n" +
+        "            try (CloseableImpl c = new CloseableImpl(messages, failOnClose)) {\n" +
+        "                if (failInTwr)\n" +
+        "                    throw new IllegalStateException(\"inTwr\");\n" +
+        "            }\n" +
+        "        } catch (IllegalStateException ex) {\n" +
+        "            messages.add(ex.getMessage());\n" +
+        "            for (Throwable t : ex.getSuppressed()) {\n" +
+        "                messages.add(t.getMessage());\n" +
+        "            }\n" +
+        "        }\n" +
+        "        if (!expectedMessages.equals(messages))\n" +
+        "            throw new AssertionError(\"Expected and actual messages differ; expectedMessages=\" +\n" +
+        "                                     expectedMessages + \"; actual=\" + messages);\n" +
+        "    }\n";
+
+    final String FILE_TEMPLATE =
+        "import java.util.*;\n" +
+        "public class Test implements Runnable {\n" +
+        "    public void run() {\n" +
+        "#TEST_INVOCATIONS" +
+        "    }\n" +
+        "#TEST_METHODS" +
+        "    static class CloseableImpl implements AutoCloseable {\n" +
+        "        private final List<String> messages;\n" +
+        "        private final boolean failOnClose;\n" +
+        "        public CloseableImpl(List<String> messages, boolean failOnClose) {\n" +
+        "            this.messages = messages;\n" +
+        "            this.failOnClose = failOnClose;\n" +
+        "        }\n" +
+        "        @Override\n" +
+        "        public void close() {\n" +
+        "            messages.add(\"close\");\n" +
+        "            if (failOnClose)\n" +
+        "                throw new IllegalStateException(\"close-exception\");\n" +
+        "        }\n" +
+        "    }\n" +
+        "}\n";
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/TryWithResources/TwrShareCloseCode.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2016, 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 7020499
+ * @summary Verify that the code that closes the resources is shared by among try-with-resources
+ * @library /tools/lib
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ *          jdk.compiler/com.sun.tools.javac.code
+ *          jdk.compiler/com.sun.tools.javac.comp
+ *          jdk.compiler/com.sun.tools.javac.tree
+ *          jdk.compiler/com.sun.tools.javac.util
+ * @build toolbox.ToolBox TwrShareCloseCode
+ * @run main TwrShareCloseCode
+ */
+
+import java.io.IOException;
+import java.util.Arrays;
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.comp.AttrContext;
+import com.sun.tools.javac.comp.Env;
+import com.sun.tools.javac.comp.Lower;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
+import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
+import com.sun.tools.javac.tree.TreeInfo;
+import com.sun.tools.javac.tree.TreeMaker;
+import com.sun.tools.javac.tree.TreeScanner;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Context.Factory;
+import com.sun.tools.javac.util.List;
+
+import toolbox.ToolBox;
+
+public class TwrShareCloseCode {
+    public static void main(String... args) throws IOException {
+        new TwrShareCloseCode().run();
+    }
+
+    void run() throws IOException {
+        run("try (Test t1 = new Test()) { }", true);
+        run("try (Test t1 = new Test()) { }\n" +
+            "try (Test t2 = new Test()) { }", true);
+        run("try (Test t1 = new Test();\n" +
+            "     Test t2 = new Test()) { }", true);
+        run("try (Test t1 = new Test()) { }\n" +
+            "try (Test t2 = new Test()) { }\n" +
+            "try (Test t3 = new Test()) { }", true);
+        run("try (Test t1 = new Test();\n" +
+            "     Test t2 = new Test();\n" +
+            "     Test t3 = new Test()) { }", false);
+        run("try (Test t1 = new Test()) { }\n" +
+            "try (Test t2 = new Test()) { }\n" +
+            "try (Test t3 = new Test()) { }\n" +
+            "try (Test t4 = new Test()) { }", false);
+
+        run("try (Test t1 = new Test()) { i++; }", true);
+        run("try (Test t1 = new Test()) { i++; }\n" +
+            "try (Test t2 = new Test()) { i++; }", false);
+
+        run("try (Test t1 = new Test(); Test t2 = new Test()) { i++; }", false);
+
+        run("try (Test t1 = new Test()) { i++; }\n" +
+            "try (Test t2 = new Test()) { }", true);
+
+        run("try (Test t1 = new Test()) { i++; }\n" +
+            "try (Test t2 = new Test()) { }\n" +
+            "try (Test t3 = new Test()) { }", false);
+
+        run("try (Test t1 = new Test()) { i++; }\n" +
+            "try (Test t2 = new Test()) { i++; }\n" +
+            "try (Test t3 = new Test()) { }", false);
+    }
+    void run(String trySpec, boolean expected) throws IOException {
+        String template = "public class Test implements AutoCloseable {\n" +
+                          "    void t(int i) {\n" +
+                          "        TRY\n" +
+                          "    }\n" +
+                          "    public void close() { }\n" +
+                          "}\n";
+        String code = template.replace("TRY", trySpec);
+        Context ctx = new Context();
+        DumpLower.preRegister(ctx);
+        Iterable<ToolBox.JavaSource> files = Arrays.asList(new ToolBox.JavaSource(code));
+        JavacTask task = JavacTool.create().getTask(null, null, null, null, null, files, ctx);
+        task.call();
+        boolean actual = ((DumpLower) DumpLower.instance(ctx)).closeSeen;
+
+        if (expected != actual) {
+            throw new IllegalStateException("expected: " + expected + "; actual: " + actual + "; code:\n" + code);
+        }
+    }
+
+    static class DumpLower extends Lower {
+
+        public static void preRegister(Context ctx) {
+            ctx.put(lowerKey, new Factory<Lower>() {
+                @Override
+                public Lower make(Context c) {
+                    return new DumpLower(c);
+                }
+            });
+        }
+
+        public DumpLower(Context context) {
+            super(context);
+        }
+
+        boolean closeSeen;
+
+        @Override
+        public List<JCTree> translateTopLevelClass(Env<AttrContext> env, JCTree cdef, TreeMaker make) {
+            List<JCTree> result = super.translateTopLevelClass(env, cdef, make);
+
+            new TreeScanner() {
+                @Override
+                public void visitMethodDef(JCMethodDecl tree) {
+                    if (!tree.name.contentEquals("t"))
+                        return;
+
+                    super.visitMethodDef(tree);
+                }
+
+                @Override
+                public void visitApply(JCMethodInvocation tree) {
+                    closeSeen |= TreeInfo.symbol(tree.meth).name.contentEquals("close");
+                    super.visitApply(tree);
+                }
+            }.scan(result);
+
+            return result;
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/UnreachableLoopCond.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2016, 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 8155028
+ * @summary javac crashes in silly do-while loop
+ * @compile UnreachableLoopCond.java
+ */
+
+class UnreachableLoopCond {
+
+    public void foo() {
+        Integer i = 100;
+        do {
+            return;
+        } while (i++ < 10);
+    }
+
+    public void goo() {
+        Integer i = 100;
+        do {
+            break;
+        } while (i++ < 10);
+    }
+
+    public void zoo() {
+        Integer i = 100;
+        do {
+            throw new RuntimeException();
+        } while (i++ < 10);
+    }
+
+    public void loo() {
+        Integer i = 100;
+        Integer j = 100;
+        do {
+           do {
+               return;
+           } while (i++ < 10);
+        } while (j++ < 10);
+    }
+
+    public void moo() {
+        Integer i = 100;
+        do {
+            if (true) {
+                return;
+            } else {
+                return;
+            }
+        } while (i++ < 10);
+    }
+
+    public void moo(boolean cond) {
+        Integer i = 100;
+        do {
+            if (cond) {
+                return;
+            } else {
+                return;
+            }
+        } while (i++ < 10);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/T8154270/EraseClassInfoAnnotationValueTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2016 Google Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+
+/*
+ * @test
+ * @bug 8154270
+ * @summary javac wrongly rejects some class literals as annotation element values
+ * @compile EraseClassInfoAnnotationValueTest.java
+ * @compile -implicit:none Other.java
+ * @run main EraseClassInfoAnnotationValueTest
+ */
+public class EraseClassInfoAnnotationValueTest {
+
+  @Retention(RetentionPolicy.RUNTIME)
+  public @interface A {
+    Class<?> value();
+  }
+
+  static class ParametricType<T> {
+
+    @A(Inner.class)
+    public static class Nested {}
+
+    public class Inner {}
+  }
+
+  public static void main(String[] args) {
+    Class<?> clazz = ParametricType.Nested.class.getAnnotation(A.class).value();
+    if (!clazz.equals(ParametricType.Inner.class)) {
+      throw new AssertionError(clazz);
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/T8154270/Other.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016 Google Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Tests separate compilation.
+ */
+public class Other {
+  Class<?> clazz = EraseClassInfoAnnotationValueTest.ParametricType.Nested.class;
+}
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ResourceVariable.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ResourceVariable.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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
@@ -36,9 +36,9 @@
 public class ResourceVariable {
 
     @TADescription(annotation = "TA", type = RESOURCE_VARIABLE,
-            lvarOffset = {10}, lvarLength = {118}, lvarIndex = {1})
+            lvarOffset = {10}, lvarLength = {106}, lvarIndex = {1})
     @TADescription(annotation = "TB", type = RESOURCE_VARIABLE,
-            lvarOffset = {22}, lvarLength = {35}, lvarIndex = {3})
+            lvarOffset = {22}, lvarLength = {31}, lvarIndex = {3})
     public String testResourceVariable() {
         return
                 "public void f() throws IOException {" + lineSeparator() +
@@ -49,7 +49,7 @@
     }
 
     @TADescription(annotation = "RTAs", type = RESOURCE_VARIABLE,
-            lvarOffset = {10}, lvarLength = {30}, lvarIndex = {1})
+            lvarOffset = {10}, lvarLength = {26}, lvarIndex = {1})
     public String testRepeatedAnnotation1() {
         return
                 "public void f() throws IOException {" + lineSeparator() +
@@ -58,7 +58,7 @@
     }
 
     @TADescription(annotation = "RTAs", type = RESOURCE_VARIABLE,
-            lvarOffset = {10}, lvarLength = {30}, lvarIndex = {1})
+            lvarOffset = {10}, lvarLength = {26}, lvarIndex = {1})
     public String testRepeatedAnnotation2() {
         return
                 "public void f() throws IOException {" + lineSeparator() +
@@ -67,9 +67,9 @@
     }
 
     @TADescription(annotation = "TA", type = RESOURCE_VARIABLE,
-            lvarOffset = {10}, lvarLength = {118}, lvarIndex = {1})
+            lvarOffset = {10}, lvarLength = {106}, lvarIndex = {1})
     @TADescription(annotation = "TB", type = RESOURCE_VARIABLE,
-            lvarOffset = {22}, lvarLength = {35}, lvarIndex = {3})
+            lvarOffset = {22}, lvarLength = {31}, lvarIndex = {3})
     public String testSeveralVariablesInTryWithResources() {
         return
                 "public void f() throws IOException {" + lineSeparator() +
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Test.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Test.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,3 +1,25 @@
+/*
+ * Copyright (c) 2016, 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 java.lang.annotation.*;
--- a/langtools/test/tools/javac/api/6731573/Erroneous.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/api/6731573/Erroneous.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,3 +1,5 @@
+/* /nodynamiccopyright/ */
+
 class A {
     boolean b;
     boolean b;
--- a/langtools/test/tools/javac/classfiles/attributes/LineNumberTable/LineNumberTestBase.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/classfiles/attributes/LineNumberTable/LineNumberTestBase.java	Thu Apr 28 23:08:16 2016 -0700
@@ -191,7 +191,7 @@
         CONDITION("int res = \n" +
                 "testField == 2 ?\n" +
                 "10\n" +
-                ":9;", 1, 3, 4), // see issue https://bugs.openjdk.java.net/browse/JDK-8050993
+                ":9;", 2, 3, 4),
         TRY("try{\n" +
                 "    --testField;\n" +
                 "}\n" +
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/LineNumberTable/T8050993.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,53 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8050993
+ * @summary Verify that the condition in the conditional lexpression gets a LineNumberTable entry
+ * @modules jdk.jdeps/com.sun.tools.classfile
+ * @compile -g T8050993.java
+ * @run main T8050993
+ */
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import com.sun.tools.classfile.*;
+
+public class T8050993 {
+    public static void main(String[] args) throws IOException, ConstantPoolException {
+        ClassFile someTestIn = ClassFile.read(T8050993.class.getResourceAsStream("T8050993.class"));
+        Set<Integer> expectedLineNumbers = new HashSet<>(Arrays.asList(49, 50, 47, 48));
+        for (Method m : someTestIn.methods) {
+            if ("method".equals(m.getName(someTestIn.constant_pool))) {
+                Code_attribute code_attribute = (Code_attribute) m.attributes.get(Attribute.Code);
+                for (Attribute at : code_attribute.attributes) {
+                    if (Attribute.LineNumberTable.equals(at.getName(someTestIn.constant_pool))) {
+                        LineNumberTable_attribute att = (LineNumberTable_attribute) at;
+                        Set<Integer> actualLinesNumbers = Arrays.stream(att.line_number_table)
+                                                                .map(e -> e.line_number)
+                                                                .collect(Collectors.toSet());
+                        if (!Objects.equals(expectedLineNumbers, actualLinesNumbers)) {
+                            throw new AssertionError("Expected LineNumber entries not found;" +
+                                                     "actual=" + actualLinesNumbers + ";" +
+                                                     "expected=" + expectedLineNumbers);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public static int field;
+
+    public static String method() {
+        String s =
+                field % 2 == 0 ?
+                "true" + field :
+                "false" + field;
+        return s;
+    }
+
+}
--- a/langtools/test/tools/javac/diags/examples/AnonymousClass.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/diags/examples/AnonymousClass.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, 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
@@ -22,12 +22,15 @@
  */
 
 // key: compiler.misc.anonymous.class
-// key: compiler.warn.missing.SVUID
-// options: -Xlint:serial
+// key: compiler.err.prob.found.req
+// key: compiler.misc.inconvertible.types
+// options: -Xlint:rawtypes
 // run: simple
 
+import java.util.ArrayList;
+
 class AnonymousClass {
-    Exception m() {
-        return new Exception() { };
+     Object m() {
+         return (ArrayList<String>) new ArrayList<Object>() { };
     }
 }
--- a/langtools/test/tools/javac/flow/T8062747.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/flow/T8062747.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2016, 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 8062747
--- a/langtools/test/tools/javac/flow/tests/TestCaseTry.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/flow/tests/TestCaseTry.java	Thu Apr 28 23:08:16 2016 -0700
@@ -52,9 +52,9 @@
         o = "";
     }
 
-    @AliveRange(varName="o", bytecodeStart=22, bytecodeLength=38)
-    @AliveRange(varName="o", bytecodeStart=103, bytecodeLength=3)
-    @AliveRange(varName="o", bytecodeStart=110, bytecodeLength=1)
+    @AliveRange(varName="o", bytecodeStart=22, bytecodeLength=13)
+    @AliveRange(varName="o", bytecodeStart=53, bytecodeLength=3)
+    @AliveRange(varName="o", bytecodeStart=60, bytecodeLength=1)
     void m3() {
         Object o;
         try (BufferedReader br =
@@ -65,8 +65,8 @@
         o = "";
     }
 
-    @AliveRange(varName="o", bytecodeStart=12, bytecodeLength=96)
-    @AliveRange(varName="o", bytecodeStart=112, bytecodeLength=1)
+    @AliveRange(varName="o", bytecodeStart=12, bytecodeLength=46)
+    @AliveRange(varName="o", bytecodeStart=62, bytecodeLength=1)
     void m4() {
         String o;
         try (BufferedReader br =
--- a/langtools/test/tools/javac/generics/Nonlinear.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/generics/Nonlinear.java	Thu Apr 28 23:08:16 2016 -0700
@@ -22,7 +22,7 @@
     // the program.
 
     public static void main (String [] args) {
-        Integer x = new Integer (5);
+        Integer x = Integer.valueOf(5);
         String y = castit (x);
         System.out.println (y);
     }
--- a/langtools/test/tools/javac/generics/odersky/BadTest4.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/generics/odersky/BadTest4.java	Thu Apr 28 23:08:16 2016 -0700
@@ -30,7 +30,7 @@
         static <A> Cell<A> makeCell(A x) { return new Cell<A>(x); }
         static <A> A id(A x) { return x; }
 
-        static Integer i = new Integer(1);
+        static Integer i = Integer.valueOf(1);
         static Number n = i;
 
         public static void main(String[] args) {
--- a/langtools/test/tools/javac/jvm/6397652/com/test/Test$Test$Test.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/jvm/6397652/com/test/Test$Test$Test.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,3 +1,26 @@
+/*
+ * 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.
+ */
+
 package com.test;
 
 public class Test$Test$Test {
--- a/langtools/test/tools/javac/jvm/6397652/com/test/Test$Test.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/jvm/6397652/com/test/Test$Test.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,3 +1,26 @@
+/*
+ * 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.
+ */
+
 package com.test;
 
 public class Test$Test {
--- a/langtools/test/tools/javac/lambda/8074381/T8074381a.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/lambda/8074381/T8074381a.java	Thu Apr 28 23:08:16 2016 -0700
@@ -13,6 +13,7 @@
         boolean m(String s);
     }
 
+    @SuppressWarnings("deprecation")
     void testRaw() {
         Sub s1 = c -> true;
         Sub s2 = Boolean::new;
@@ -22,6 +23,7 @@
         };
     }
 
+    @SuppressWarnings("deprecation")
     void testNonRaw() {
         Sub<Integer> s1 = c -> true;
         Sub<Integer> s2 = Boolean::new;
--- a/langtools/test/tools/javac/lambda/8074381/T8074381a.out	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/lambda/8074381/T8074381a.out	Thu Apr 28 23:08:16 2016 -0700
@@ -1,4 +1,4 @@
-T8074381a.java:17:18: compiler.err.prob.found.req: (compiler.misc.no.suitable.functional.intf.inst: T8074381a.Sub)
 T8074381a.java:18:18: compiler.err.prob.found.req: (compiler.misc.no.suitable.functional.intf.inst: T8074381a.Sub)
-T8074381a.java:19:28: compiler.err.does.not.override.abstract: compiler.misc.anonymous.class: T8074381a$1, m(java.lang.Object), T8074381a.Sup
+T8074381a.java:19:18: compiler.err.prob.found.req: (compiler.misc.no.suitable.functional.intf.inst: T8074381a.Sub)
+T8074381a.java:20:28: compiler.err.does.not.override.abstract: compiler.misc.anonymous.class: T8074381a$1, m(java.lang.Object), T8074381a.Sup
 3 errors
--- a/langtools/test/tools/javac/lambda/TargetType27.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/lambda/TargetType27.java	Thu Apr 28 23:08:16 2016 -0700
@@ -15,6 +15,6 @@
     <A, R> F<A, R> m(F<A, R>  f) { return null; }
 
     void test() {
-        m((String s1) ->  (String s2) ->  new Integer(1));
+        m((String s1) ->  (String s2) -> Integer.valueOf(1));
     }
 }
--- a/langtools/test/tools/javac/lambda/badMemberRefBytecode/Main.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/lambda/badMemberRefBytecode/Main.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2016, 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.Collections;
 
 public class Main {
@@ -6,4 +29,5 @@
         Collections.<String>sort(null, String::compareTo);
     }
 
+
 }
--- a/langtools/test/tools/javac/lambda/badMemberRefBytecode/Use.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/lambda/badMemberRefBytecode/Use.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
 public class Use {
     private Main m;
 }
--- a/langtools/test/tools/javac/lambda/lambdaExecution/TBlock.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/lambda/lambdaExecution/TBlock.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
 /**
  * Performs operations upon an input object which may modify that object and/or
  * external state (other objects).
--- a/langtools/test/tools/javac/modules/AbstractOrInnerClassServiceImplTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/AbstractOrInnerClassServiceImplTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -47,7 +47,7 @@
     }
 
     @Test
-    void testAbstractServiceImpl(Path base) throws Exception {
+    public void testAbstractServiceImpl(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { provides p1.Service with p2.Impl; }",
@@ -68,7 +68,7 @@
     }
 
     @Test
-    void testInnerClassServiceImpl(Path base) throws Exception {
+    public void testInnerClassServiceImpl(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { provides p1.Service with p2.Outer.Inner; }",
@@ -89,7 +89,7 @@
     }
 
     @Test
-    void testInnerInterfaceServiceImpl(Path base) throws Exception {
+    public void testInnerInterfaceServiceImpl(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { provides p1.Service with p2.Outer.Inner; }",
--- a/langtools/test/tools/javac/modules/AddLimitMods.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/AddLimitMods.java	Thu Apr 28 23:08:16 2016 -0700
@@ -79,7 +79,7 @@
     }
 
     @Test
-    void testManual(Path base) throws Exception {
+    public void testManual(Path base) throws Exception {
         Path moduleSrc = base.resolve("module-src");
         Path m1 = moduleSrc.resolve("m1");
 
@@ -176,7 +176,7 @@
     }
 
     @Test
-    void testAllModulePath(Path base) throws Exception {
+    public void testAllModulePath(Path base) throws Exception {
         if (Files.isDirectory(base))
             tb.cleanDirectory(base);
 
@@ -284,7 +284,7 @@
     }
 
     @Test
-    void testRuntime2Compile(Path base) throws Exception {
+    public void testRuntime2Compile(Path base) throws Exception {
         Path classpathSrc = base.resolve("classpath-src");
         Path classpathOut = base.resolve("classpath-out");
 
--- a/langtools/test/tools/javac/modules/AddReadsTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/AddReadsTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -58,7 +58,7 @@
     }
 
     @Test
-    void testAddReads(Path base) throws Exception {
+    public void testAddReads(Path base) throws Exception {
         Path src = base.resolve("src");
         Path src_m1 = src.resolve("m1");
         tb.writeJavaFiles(src_m1,
@@ -150,7 +150,7 @@
     }
 
     @Test
-    void testAddReadsUnnamedModule(Path base) throws Exception {
+    public void testAddReadsUnnamedModule(Path base) throws Exception {
         Path jar = prepareTestJar(base);
 
         Path moduleSrc = base.resolve("module-src");
@@ -175,7 +175,7 @@
     }
 
     @Test
-    void testAddReadsUnnamedModulePackageConflict(Path base) throws Exception {
+    public void testAddReadsUnnamedModulePackageConflict(Path base) throws Exception {
         Path jar = prepareTestJar(base);
 
         Path moduleSrc = base.resolve("module-src");
@@ -202,7 +202,7 @@
     }
 
     @Test
-    void testAddReadsUnnamedToJavaBase(Path base) throws Exception {
+    public void testAddReadsUnnamedToJavaBase(Path base) throws Exception {
         Path jar = prepareTestJar(base);
         Path src = base.resolve("src");
         Path classes = base.resolve("classes");
@@ -223,7 +223,7 @@
     }
 
     @Test
-    void testAddReadsToJavaBase(Path base) throws Exception {
+    public void testAddReadsToJavaBase(Path base) throws Exception {
         Path src = base.resolve("src");
         Path classes = base.resolve("classes");
 
@@ -275,7 +275,7 @@
     }
 
     @Test
-    void testX(Path base) throws Exception {
+    public void testX(Path base) throws Exception {
         Path src = base.resolve("src");
         Path src_m1 = src.resolve("m1");
         tb.writeJavaFiles(src_m1,
--- a/langtools/test/tools/javac/modules/AnnotationProcessing.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/AnnotationProcessing.java	Thu Apr 28 23:08:16 2016 -0700
@@ -68,7 +68,7 @@
     }
 
     @Test
-    void testAPSingleModule(Path base) throws Exception {
+    public void testAPSingleModule(Path base) throws Exception {
         Path moduleSrc = base.resolve("module-src");
         Path m1 = moduleSrc.resolve("m1");
 
@@ -95,7 +95,7 @@
     }
 
     @Test
-    void testAPMultiModule(Path base) throws Exception {
+    public void testAPMultiModule(Path base) throws Exception {
         Path moduleSrc = base.resolve("module-src");
         Path m1 = moduleSrc.resolve("m1");
         Path m2 = moduleSrc.resolve("m2");
@@ -196,7 +196,7 @@
     }
 
     @Test
-    void testVerifyUsesProvides(Path base) throws Exception {
+    public void testVerifyUsesProvides(Path base) throws Exception {
         Path moduleSrc = base.resolve("module-src");
         Path m1 = moduleSrc.resolve("m1");
 
@@ -254,7 +254,7 @@
     }
 
     @Test
-    void testPackageNoModule(Path base) throws Exception {
+    public void testPackageNoModule(Path base) throws Exception {
         Path src = base.resolve("src");
         Path classes = base.resolve("classes");
 
--- a/langtools/test/tools/javac/modules/AnnotationProcessorsInModulesTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/AnnotationProcessorsInModulesTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -156,7 +156,7 @@
     Path classes;
 
     @Test
-    void testUseOnlyOneProcessor(Path base) throws Exception {
+    public void testUseOnlyOneProcessor(Path base) throws Exception {
         initialization(base);
         String log = new JavacTask(tb)
                 .options("-processormodulepath", processorCompiledModules.toString(),
@@ -172,7 +172,7 @@
     }
 
     @Test
-    void testAnnotationProcessorExecutionOrder(Path base) throws Exception {
+    public void testAnnotationProcessorExecutionOrder(Path base) throws Exception {
         initialization(base);
         List<String> log = new JavacTask(tb)
                 .options("-processormodulepath", processorCompiledModules.toString(),
@@ -202,7 +202,7 @@
     }
 
     @Test
-    void testErrorOutputIfOneProcessorNameIsIncorrect(Path base) throws Exception {
+    public void testErrorOutputIfOneProcessorNameIsIncorrect(Path base) throws Exception {
         initialization(base);
         String log = new JavacTask(tb)
                 .options("-XDrawDiagnostics", "-processormodulepath", processorCompiledModules.toString(),
@@ -218,7 +218,7 @@
     }
 
     @Test
-    void testOptionsExclusion(Path base) throws Exception {
+    public void testOptionsExclusion(Path base) throws Exception {
         initialization(base);
         List<String> log = new JavacTask(tb)
                 .options("-XDrawDiagnostics", "-processormodulepath", processorCompiledModules.toString(),
--- a/langtools/test/tools/javac/modules/AutomaticModules.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/AutomaticModules.java	Thu Apr 28 23:08:16 2016 -0700
@@ -48,7 +48,7 @@
     }
 
     @Test
-    void testSimple(Path base) throws Exception {
+    public void testSimple(Path base) throws Exception {
         Path legacySrc = base.resolve("legacy-src");
         tb.writeJavaFiles(legacySrc,
                           "package api; import java.awt.event.ActionListener; public abstract class Api implements ActionListener {}");
@@ -98,7 +98,7 @@
     }
 
     @Test
-    void testUnnamedModule(Path base) throws Exception {
+    public void testUnnamedModule(Path base) throws Exception {
         Path legacySrc = base.resolve("legacy-src");
         tb.writeJavaFiles(legacySrc,
                           "package api; public abstract class Api { public void run(CharSequence str) { } private void run(base.Base base) { } }",
@@ -156,7 +156,7 @@
     }
 
     @Test
-    void testModuleInfoFromClassFileDependsOnAutomatic(Path base) throws Exception {
+    public void testModuleInfoFromClassFileDependsOnAutomatic(Path base) throws Exception {
         Path automaticSrc = base.resolve("automaticSrc");
         tb.writeJavaFiles(automaticSrc, "package api; public class Api {}");
         Path automaticClasses = base.resolve("automaticClasses");
--- a/langtools/test/tools/javac/modules/DoclintOtherModules.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/DoclintOtherModules.java	Thu Apr 28 23:08:16 2016 -0700
@@ -47,7 +47,7 @@
     }
 
     @Test
-    void testSimple(Path base) throws Exception {
+    public void testSimple(Path base) throws Exception {
         Path src = base.resolve("src");
         Path m1 = src.resolve("m1");
         Path m2 = src.resolve("m2");
--- a/langtools/test/tools/javac/modules/DuplicateClassTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/DuplicateClassTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -47,7 +47,7 @@
     }
 
     @Test
-    void testSimple(Path base) throws Exception {
+    public void testSimple(Path base) throws Exception {
         Path m1 = base.resolve("m1");
         Path m2 = base.resolve("m2");
         tb.writeJavaFiles(m1,
--- a/langtools/test/tools/javac/modules/EdgeCases.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/EdgeCases.java	Thu Apr 28 23:08:16 2016 -0700
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @bug 8154283
  * @summary tests for multi-module mode compilation
  * @library /tools/lib
  * @modules
@@ -57,7 +58,6 @@
 import toolbox.JarTask;
 import toolbox.JavacTask;
 import toolbox.Task;
-import toolbox.ToolBox;
 
 public class EdgeCases extends ModuleTestBase {
 
@@ -66,7 +66,7 @@
     }
 
     @Test
-    void testAddExportUndefinedModule(Path base) throws Exception {
+    public void testAddExportUndefinedModule(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src, "package test; import undef.Any; public class Test {}");
         Path classes = base.resolve("classes");
@@ -89,7 +89,7 @@
     }
 
     @Test
-    void testModuleSymbolOutterMostClass(Path base) throws Exception {
+    public void testModuleSymbolOutterMostClass(Path base) throws Exception {
         JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
         try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) {
             Path moduleSrc = base.resolve("module-src");
@@ -110,7 +110,7 @@
     }
 
     @Test
-    void testParseEnterAnalyze(Path base) throws Exception {
+    public void testParseEnterAnalyze(Path base) throws Exception {
         JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
         try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) {
             Path moduleSrc = base.resolve("module-src");
@@ -148,7 +148,7 @@
     }
 
     @Test
-    void testModuleImplicitModuleBoundaries(Path base) throws Exception {
+    public void testModuleImplicitModuleBoundaries(Path base) throws Exception {
         Path src = base.resolve("src");
         Path src_m1 = src.resolve("m1");
         tb.writeJavaFiles(src_m1,
@@ -180,7 +180,7 @@
     }
 
     @Test
-    void testAssignClassToAutomaticModule(Path base) throws Exception {
+    public void testAssignClassToAutomaticModule(Path base) throws Exception {
         //check that if a ClassSymbol belongs to an automatic module, it is properly assigned and not
         //duplicated when being accessed through a classfile.
         Path automaticSrc = base.resolve("automaticSrc");
@@ -239,7 +239,7 @@
     }
 
     @Test
-    void testEmptyImplicitModuleInfo(Path base) throws Exception {
+    public void testEmptyImplicitModuleInfo(Path base) throws Exception {
         Path src = base.resolve("src");
         Path src_m1 = src.resolve("m1");
         Files.createDirectories(src_m1);
@@ -269,4 +269,39 @@
 
     }
 
+    @Test
+    public void testClassPackageClash(Path base) throws Exception {
+        Path src = base.resolve("src");
+        Path src_m1 = src.resolve("m1");
+        tb.writeJavaFiles(src_m1,
+                          "module m1 { exports test.m1; }",
+                          "package test.m1;\n" +
+                          "public class Test {}\n");
+        Path src_m2 = src.resolve("m2");
+        tb.writeJavaFiles(src_m2,
+                          "module m2 { requires m1; }",
+                          "package test;\n" +
+                          "public class m1 {}\n");
+        Path classes = base.resolve("classes");
+        tb.createDirectories(classes);
+
+        List<String> log = new JavacTask(tb)
+                .options("-modulesourcepath", src.toString(),
+                         "-XDrawDiagnostics")
+                .outdir(classes)
+                .files(findJavaFiles(src))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+
+        List<String> expected = Arrays.asList(
+            "m1.java:2:8: compiler.err.clash.with.pkg.of.same.name: kindname.class, test.m1",
+            "1 error"
+        );
+
+        if (!expected.equals(log)) {
+            throw new IllegalStateException(log.toString());
+        }
+    }
+
 }
--- a/langtools/test/tools/javac/modules/GraphsTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/GraphsTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -28,7 +28,8 @@
  * @modules
  *      jdk.compiler/com.sun.tools.javac.api
  *      jdk.compiler/com.sun.tools.javac.main
- * @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask ModuleTestBase
+ * @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask toolbox.ModuleBuilder
+ *      ModuleTestBase
  * @run main GraphsTest
  */
 
@@ -41,6 +42,7 @@
 
 import toolbox.JarTask;
 import toolbox.JavacTask;
+import toolbox.ModuleBuilder;
 import toolbox.Task;
 import toolbox.ToolBox;
 
@@ -69,11 +71,11 @@
      *
      */
     @Test
-    void diamond(Path base) throws Exception {
+    public void diamond(Path base) throws Exception {
 
         Path modules = Files.createDirectories(base.resolve("modules"));
 
-        new ModuleBuilder("J")
+        new ModuleBuilder(tb, "J")
                 .exports("openJ")
                 .classes("package openJ; public class J { }")
                 .classes("package closedJ; public class J { }")
@@ -87,25 +89,25 @@
                 .run()
                 .writeAll();
 
-        new ModuleBuilder("O")
+        new ModuleBuilder(tb, "O")
                 .exports("openO")
                 .requiresPublic("J", jarModules)
                 .classes("package openO; public class O { openJ.J j; }")
                 .classes("package closedO; public class O { }")
                 .build(modules);
-        new ModuleBuilder("N")
+        new ModuleBuilder(tb, "N")
                 .requiresPublic("O", modules, jarModules)
                 .exports("openN")
                 .classes("package openN; public class N { }")
                 .classes("package closedN; public class N { }")
                 .build(modules);
-        new ModuleBuilder("L")
+        new ModuleBuilder(tb, "L")
                 .requiresPublic("O", modules, jarModules)
                 .exports("openL")
                 .classes("package openL; public class L { }")
                 .classes("package closedL; public class L { }")
                 .build(modules);
-        ModuleBuilder m = new ModuleBuilder("M");
+        ModuleBuilder m = new ModuleBuilder(tb, "M");
         //positive case
         Path positiveSrc = m
                 .requires("N", modules)
@@ -178,14 +180,14 @@
     @Test
     public void reexportOfQualifiedExport(Path base) throws Exception {
         Path modules = base.resolve("modules");
-        new ModuleBuilder("M")
+        new ModuleBuilder(tb, "M")
                 .requiresPublic("N")
                 .write(modules);
-        new ModuleBuilder("N")
+        new ModuleBuilder(tb, "N")
                 .exportsTo("pack", "M")
                 .classes("package pack; public class Clazz { }")
                 .write(modules);
-        new ModuleBuilder("L")
+        new ModuleBuilder(tb, "L")
                 .requires("M")
                 .classes("package p; public class A { A(pack.Clazz cl){} } ")
                 .write(modules);
--- a/langtools/test/tools/javac/modules/HelloWorldTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/HelloWorldTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -58,7 +58,7 @@
         + HELLO_WORLD;
 
     @Test
-    void testLegacyMode(Path base) throws Exception {
+    public void testLegacyMode(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src, HELLO_WORLD);
 
@@ -85,7 +85,7 @@
     }
 
     @Test
-    void testUnnamedModule(Path base) throws Exception {
+    public void testUnnamedModule(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src, HELLO_WORLD);
 
@@ -101,7 +101,7 @@
     }
 
     @Test
-    void testSingleModule(Path base) throws Exception {
+    public void testSingleModule(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeFile(src.resolve("module-info.java"), "module m { }");
         tb.writeJavaFiles(src, PKG_HELLO_WORLD);
@@ -121,7 +121,7 @@
     }
 
     @Test
-    void testModuleSourcePath(Path base) throws Exception {
+    public void testModuleSourcePath(Path base) throws Exception {
         Path src = base.resolve("src");
         Path src_m1 = src.resolve("m1");
         tb.writeFile(src_m1.resolve("module-info.java"), "module m1 { }");
--- a/langtools/test/tools/javac/modules/MOptionTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/MOptionTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -47,7 +47,7 @@
     }
 
     @Test
-    void testOneModule(Path base) throws Exception {
+    public void testOneModule(Path base) throws Exception {
         Path src = base.resolve("src");
         Path m1 = src.resolve("m1");
         Path build = base.resolve("build");
@@ -112,7 +112,7 @@
     }
 
     @Test
-    void testNoOutputDir(Path base) throws Exception {
+    public void testNoOutputDir(Path base) throws Exception {
         Path src = base.resolve("src");
         Path m1 = src.resolve("m1");
         Path build = base.resolve("build");
@@ -135,7 +135,7 @@
     }
 
     @Test
-    void testNoModuleSourcePath(Path base) throws Exception {
+    public void testNoModuleSourcePath(Path base) throws Exception {
         Path src = base.resolve("src");
         Path m1 = src.resolve("m1");
         Path build = base.resolve("build");
@@ -158,7 +158,7 @@
     }
 
     @Test
-    void testMultiModule(Path base) throws Exception {
+    public void testMultiModule(Path base) throws Exception {
         Path src = base.resolve("src");
         Path m1 = src.resolve("m1");
         Path m2 = src.resolve("m2");
--- a/langtools/test/tools/javac/modules/ModuleFinderTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/ModuleFinderTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -48,7 +48,7 @@
     }
 
     @Test
-    void testDuplicateModulesOnPath(Path base) throws Exception {
+    public void testDuplicateModulesOnPath(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src, "module m1 { }");
 
--- a/langtools/test/tools/javac/modules/ModuleInfoTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/ModuleInfoTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -51,7 +51,7 @@
      * Check error message if module declaration not in module-info.java.
      */
     @Test
-    void testModuleDeclNotInModuleJava(Path base) throws Exception {
+    public void testModuleDeclNotInModuleJava(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeFile(src.resolve("M.java"), "module M { }");
         String log = new JavacTask(tb)
@@ -69,7 +69,7 @@
      * Verify that a package private class can be put in module-info.java.
      */
     @Test
-    void testNotModuleDeclInModuleJava_1(Path base) throws Exception {
+    public void testNotModuleDeclInModuleJava_1(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeFile(src.resolve("module-info.java"), "class C { }");
         new JavacTask(tb)
@@ -83,7 +83,7 @@
      * Verify that a public class cannot be put in module-info.java.
      */
     @Test
-    void testNotModuleDeclInModuleJava_2(Path base) throws Exception {
+    public void testNotModuleDeclInModuleJava_2(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeFile(src.resolve("module-info.java"), "public class C { }");
         String log = new JavacTask(tb)
@@ -101,7 +101,7 @@
      * Verify that only one module decl can be put in module-info.java.
      */
     @Test
-    void testSingleModuleDecl(Path base) throws Exception {
+    public void testSingleModuleDecl(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src, "module M1 { } /*...*/ module M2 { }");
         String log = new JavacTask(tb)
@@ -119,7 +119,7 @@
      * Verify that missing requires are reported.
      */
     @Test
-    void testRequiresNotFound(Path base) throws Exception {
+    public void testRequiresNotFound(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src, "module M1 { requires M2; }");
         String log = new JavacTask(tb)
@@ -137,7 +137,7 @@
      * Verify that missing exports are reported.
      */
     @Test
-    void testExportsNotFound(Path base) throws Exception {
+    public void testExportsNotFound(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src, "module M1 { exports p to M2; }");
         String log = new JavacTask(tb)
@@ -155,7 +155,7 @@
      * Verify that a simple loop is detected.
      */
     @Test
-    void testRequiresSelf(Path base) throws Exception {
+    public void testRequiresSelf(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src, "module M { requires M; }");
         String log = new JavacTask(tb)
@@ -173,7 +173,7 @@
      * Verify that a multi-module loop is detected.
      */
     @Test
-    void testRequiresLoop(Path base) throws Exception {
+    public void testRequiresLoop(Path base) throws Exception {
         Path src = base.resolve("src");
         Path src_m1 = src.resolve("m1");
         tb.writeFile(src_m1.resolve("module-info.java"), "module m1 { requires m2; }");
@@ -201,7 +201,7 @@
      * Verify that a multi-module loop is detected.
      */
     @Test
-    void testRequiresPublicLoop(Path base) throws Exception {
+    public void testRequiresPublicLoop(Path base) throws Exception {
         Path src = base.resolve("src");
         Path src_m1 = src.resolve("m1");
         tb.writeFile(src_m1.resolve("module-info.java"), "module m1 { requires m2; }");
@@ -229,7 +229,7 @@
      * Verify that duplicate requires are detected.
      */
     @Test
-    void testDuplicateRequires(Path base) throws Exception {
+    public void testDuplicateRequires(Path base) throws Exception {
         Path src = base.resolve("src");
         Path src_m1 = src.resolve("m1");
         tb.writeFile(src_m1.resolve("module-info.java"), "module m1 { }");
@@ -255,7 +255,7 @@
      * Verify that duplicate exported packages are detected.
      */
     @Test
-    void testDuplicateExports_packages(Path base) throws Exception {
+    public void testDuplicateExports_packages(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src, "module m1 { exports p; exports p; }");
 
@@ -278,7 +278,7 @@
      * Verify that duplicate exported packages are detected.
      */
     @Test
-    void testDuplicateExports_packages2(Path base) throws Exception {
+    public void testDuplicateExports_packages2(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src.resolve("m1"), "module m1 { exports p; exports p to m2; }");
         tb.writeJavaFiles(src.resolve("m2"), "module m2 { }");
@@ -302,7 +302,7 @@
      * Verify that duplicate exported packages are detected.
      */
     @Test
-    void testDuplicateExports_modules(Path base) throws Exception {
+    public void testDuplicateExports_modules(Path base) throws Exception {
         Path src = base.resolve("src");
         Path src_m1 = src.resolve("m1");
         tb.writeFile(src_m1.resolve("module-info.java"), "module m1 { }");
--- a/langtools/test/tools/javac/modules/ModuleInfoTreeAccess.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/ModuleInfoTreeAccess.java	Thu Apr 28 23:08:16 2016 -0700
@@ -61,7 +61,7 @@
     }
 
     @Test
-    void testTreePathForModuleDecl(Path base) throws Exception {
+    public void testTreePathForModuleDecl(Path base) throws Exception {
 
         JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
         try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) {
--- a/langtools/test/tools/javac/modules/ModulePathTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/ModulePathTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -30,7 +30,8 @@
  *      jdk.compiler/com.sun.tools.javac.main
  *      jdk.jdeps/com.sun.tools.javap
  *      jdk.jlink/jdk.tools.jmod
- * @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask ModuleTestBase
+ * @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask toolbox.ModuleBuilder
+ *      ModuleTestBase
  * @run main ModulePathTest
  */
 
@@ -41,6 +42,7 @@
 
 import toolbox.JarTask;
 import toolbox.JavacTask;
+import toolbox.ModuleBuilder;
 import toolbox.Task;
 import toolbox.ToolBox;
 
@@ -54,7 +56,7 @@
     }
 
     @Test
-    void testNotExistsOnPath(Path base) throws Exception {
+    public void testNotExistsOnPath(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src, "class C { }");
 
@@ -71,7 +73,7 @@
     }
 
     @Test
-    void testNotADirOnPath_1(Path base) throws Exception {
+    public void testNotADirOnPath_1(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src, "class C { }");
         tb.writeFile("dummy.txt", "");
@@ -89,7 +91,7 @@
     }
 
     @Test
-    void testNotADirOnPath_2(Path base) throws Exception {
+    public void testNotADirOnPath_2(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src, "class C { }");
         tb.writeFile("dummy.jimage", "");
@@ -107,7 +109,7 @@
     }
 
     @Test
-    void testExplodedModuleOnPath(Path base) throws Exception {
+    public void testExplodedModuleOnPath(Path base) throws Exception {
         Path modSrc = base.resolve("modSrc");
         tb.writeJavaFiles(modSrc,
                 "module m1 { exports p; }",
@@ -137,7 +139,7 @@
     }
 
     @Test
-    void testBadExplodedModuleOnPath(Path base) throws Exception {
+    public void testBadExplodedModuleOnPath(Path base) throws Exception {
         Path modClasses = base.resolve("modClasses");
         tb.writeFile(modClasses.resolve("module-info.class"), "module m1 { }");
 
@@ -162,7 +164,7 @@
     }
 
     @Test
-    void testAutoJarOnPath(Path base) throws Exception {
+    public void testAutoJarOnPath(Path base) throws Exception {
         Path jarSrc = base.resolve("jarSrc");
         tb.writeJavaFiles(jarSrc,
                 "package p; public class CC { }");
@@ -195,7 +197,7 @@
     }
 
     @Test
-    void testModJarOnPath(Path base) throws Exception {
+    public void testModJarOnPath(Path base) throws Exception {
         Path jarSrc = base.resolve("jarSrc");
         tb.writeJavaFiles(jarSrc,
                 "module m1 { exports p; }",
@@ -231,7 +233,7 @@
     }
 
     @Test
-    void testBadJarOnPath(Path base) throws Exception {
+    public void testBadJarOnPath(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src, "class C { }");
         tb.writeFile("dummy.jar", "");
@@ -249,7 +251,7 @@
     }
 
     @Test
-    void testJModOnPath(Path base) throws Exception {
+    public void testJModOnPath(Path base) throws Exception {
         Path jmodSrc = base.resolve("jmodSrc");
         tb.writeJavaFiles(jmodSrc,
                 "module m1 { exports p; }",
@@ -282,7 +284,7 @@
     }
 
     @Test
-    void testBadJModOnPath(Path base) throws Exception {
+    public void testBadJModOnPath(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src, "class C { }");
         tb.writeFile("dummy.jmod", "");
@@ -300,9 +302,9 @@
     }
 
     @Test
-    void relativePath(Path base) throws Exception {
+    public void relativePath(Path base) throws Exception {
         final Path modules = base.resolve("modules");
-        new ModuleBuilder("m1").build(modules);
+        new ModuleBuilder(tb, "m1").build(modules);
 
         Path src = base.resolve("src");
         tb.writeJavaFiles(src, "module m2 { requires m1; }", "class A { }");
@@ -316,9 +318,9 @@
     }
 
     @Test
-    void duplicatePaths_1(Path base) throws Exception {
+    public void duplicatePaths_1(Path base) throws Exception {
         final Path modules = base.resolve("modules");
-        new ModuleBuilder("m1").build(modules);
+        new ModuleBuilder(tb, "m1").build(modules);
 
         Path src = base.resolve("src");
         tb.writeJavaFiles(src, "module m2 { requires m1; }", "class A { }");
@@ -332,9 +334,9 @@
     }
 
     @Test
-    void duplicatePaths_2(Path base) throws Exception {
+    public void duplicatePaths_2(Path base) throws Exception {
         final Path modules = base.resolve("modules");
-        new ModuleBuilder("m1").build(modules);
+        new ModuleBuilder(tb, "m1").build(modules);
 
         Path src = base.resolve("src");
         tb.writeJavaFiles(src, "module m2 { requires m1; }", "class A { }");
@@ -349,15 +351,15 @@
     }
 
     @Test
-    void oneModuleHidesAnother(Path base) throws Exception {
+    public void oneModuleHidesAnother(Path base) throws Exception {
         final Path module = base.resolve("modules");
-        new ModuleBuilder("m1")
+        new ModuleBuilder(tb, "m1")
                 .exports("pkg1")
                 .classes("package pkg1; public class E { }")
                 .build(module);
 
         final Path deepModuleDir = module.resolve("deepModuleDir");
-        new ModuleBuilder("m1")
+        new ModuleBuilder(tb, "m1")
                 .exports("pkg2")
                 .classes("package pkg2; public class E { }")
                 .build(deepModuleDir);
@@ -374,19 +376,19 @@
     }
 
     @Test
-    void modulesInDifferentContainers(Path base) throws Exception {
+    public void modulesInDifferentContainers(Path base) throws Exception {
         final Path modules = base.resolve("modules");
-        new ModuleBuilder("m1")
+        new ModuleBuilder(tb, "m1")
                 .exports("one")
                 .classes("package one; public class A { }")
                 .build(modules);
 
-        new ModuleBuilder("m2")
+        new ModuleBuilder(tb, "m2")
                 .requires("m1", modules)
                 .build(base.resolve("tmp"));
         jar(base.resolve("tmp/m2"), modules.resolve("m2.jar"));
 
-        new ModuleBuilder("m3")
+        new ModuleBuilder(tb, "m3")
                 .requires("m2", modules)
                 .build(base.resolve("tmp"));
         jmod(base.resolve("tmp/m3"), modules.resolve("m3.jmod"));
--- a/langtools/test/tools/javac/modules/ModuleSourcePathTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/ModuleSourcePathTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -56,7 +56,7 @@
     }
 
     @Test
-    void testSourcePathConflict(Path base) throws Exception {
+    public void testSourcePathConflict(Path base) throws Exception {
         Path sp = base.resolve("src");
         Path msp = base.resolve("srcmodules");
 
@@ -74,7 +74,7 @@
     }
 
     @Test
-    void testUnnormalizedPath1(Path base) throws Exception {
+    public void testUnnormalizedPath1(Path base) throws Exception {
         Path src = base.resolve("src");
         Path src_m1 = src.resolve("m1");
         tb.writeJavaFiles(src_m1, "module m1 { }");
@@ -91,7 +91,7 @@
     }
 
     @Test
-    void testUnnormalizedPath2(Path base) throws Exception {
+    public void testUnnormalizedPath2(Path base) throws Exception {
         Path src = base.resolve("src");
         Path src_m1 = src.resolve("m1");
         tb.writeJavaFiles(src_m1, "module m1 { }");
@@ -115,7 +115,7 @@
     }
 
     @Test
-    void regularBraces(Path base) throws Exception {
+    public void regularBraces(Path base) throws Exception {
         generateModules(base, "src1", "src2/inner_dir");
 
         final Path modules = base.resolve("modules");
@@ -136,7 +136,7 @@
     }
 
     @Test
-    void mismatchedBraces(Path base) throws Exception {
+    public void mismatchedBraces(Path base) throws Exception {
         final List<String> sourcePaths = Arrays.asList(
                 "{",
                 "}",
@@ -165,7 +165,7 @@
     }
 
     @Test
-    void deepBraces(Path base) throws Exception {
+    public void deepBraces(Path base) throws Exception {
         String[] modulePaths = {"src/src1",
                 "src/src2",
                 "src/src3",
@@ -197,7 +197,7 @@
     }
 
     @Test
-    void fileInPath(Path base) throws Exception {
+    public void fileInPath(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src.resolve("kettle$"), "module kettle$ { }", "package electric; class Heater { }");
         tb.writeFile(base.resolve("dummy.txt"), "");
@@ -218,7 +218,7 @@
     }
 
     @Test
-    void noAlternative(Path base) throws Exception {
+    public void noAlternative(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src.resolve("kettle$"), "module kettle$ { }", "package electric; class Heater { }");
 
@@ -238,7 +238,7 @@
     }
 
     @Test
-    void noChoice(Path base) throws Exception {
+    public void noChoice(Path base) throws Exception {
         tb.writeJavaFiles(base.resolve("kettle$"), "module kettle$ { }", "package electric; class Heater { }");
 
         final Path modules = base.resolve("modules");
@@ -257,7 +257,7 @@
     }
 
     @Test
-    void nestedModules(Path src) throws Exception {
+    public void nestedModules(Path src) throws Exception {
         Path carModule = src.resolve("car");
         tb.writeJavaFiles(carModule, "module car { }", "package light; class Headlight { }");
         tb.writeJavaFiles(carModule.resolve("engine"), "module engine { }", "package flat; class Piston { }");
@@ -277,7 +277,7 @@
     }
 
     @Test
-    void relativePaths(Path base) throws Exception {
+    public void relativePaths(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src.resolve("kettle"), "module kettle { }", "package electric; class Heater { }");
 
@@ -296,7 +296,7 @@
     }
 
     @Test
-    void duplicatePaths(Path base) throws Exception {
+    public void duplicatePaths(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src.resolve("m1"), "module m1 { }", "package a; class A { }");
 
@@ -315,7 +315,7 @@
     }
 
     @Test
-    void notExistentPaths(Path base) throws Exception {
+    public void notExistentPaths(Path base) throws Exception {
         tb.writeJavaFiles(base.resolve("m1"), "module m1 { requires m0; }", "package a; class A { }");
 
         final Path modules = base.resolve("modules");
@@ -334,7 +334,7 @@
     }
 
     @Test
-    void notExistentPathShouldBeSkipped(Path base) throws Exception {
+    public void notExistentPathShouldBeSkipped(Path base) throws Exception {
         tb.writeJavaFiles(base.resolve("m1"), "module m1 { }", "package a; class A { }");
 
         final Path modules = base.resolve("modules");
@@ -352,7 +352,7 @@
     }
 
     @Test
-    void commas(Path base) throws Exception {
+    public void commas(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src.resolve("m1"), "module m1 { }", "package a; class A { }");
 
@@ -371,7 +371,7 @@
     }
 
     @Test
-    void asterisk(Path base) throws Exception {
+    public void asterisk(Path base) throws Exception {
         tb.writeJavaFiles(base.resolve("kettle").resolve("classes"), "module kettle { }",
                 "package electric; class Heater { }");
 
@@ -391,7 +391,7 @@
     }
 
     @Test
-    void asteriskInDifferentSets(Path base) throws Exception {
+    public void asteriskInDifferentSets(Path base) throws Exception {
         Path src = base.resolve("src");
         final Path module = src.resolve("kettle");
         tb.writeJavaFiles(module.resolve("classes"), "module kettle { }", "package electric; class Heater { }");
@@ -417,7 +417,7 @@
     }
 
     @Test
-    void asteriskIllegalUse(Path base) throws Exception {
+    public void asteriskIllegalUse(Path base) throws Exception {
         final List<String> sourcePaths = Arrays.asList(
                 "*",
                 "**",
--- a/langtools/test/tools/javac/modules/ModuleTestBase.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/ModuleTestBase.java	Thu Apr 28 23:08:16 2016 -0700
@@ -43,19 +43,20 @@
 import java.util.stream.Collectors;
 
 import toolbox.JavacTask;
+import toolbox.TestRunner;
 import toolbox.ToolBox;
 
 /**
  * Base class for module tests.
  */
-public class ModuleTestBase {
+public class ModuleTestBase extends TestRunner {
     protected ToolBox tb;
-    protected PrintStream out;
     private int errors;
 
-    /** Marker annotation for test methods to be invoked by runTests. */
-    @Retention(RetentionPolicy.RUNTIME)
-    @interface Test { }
+    ModuleTestBase() {
+        super(System.err);
+        tb = new ToolBox();
+    }
 
     /**
      * Run all methods annotated with @Test, and throw an exception if any
@@ -63,47 +64,12 @@
      *
      * @throws Exception if any errors occurred
      */
-    void runTests() throws Exception {
-        if (tb == null)
-            tb = new ToolBox();
-        out = System.err;
-
-        for (Method m: getClass().getDeclaredMethods()) {
-            Annotation a = m.getAnnotation(Test.class);
-            if (a != null) {
-                try {
-                    out.println("Running test " + m.getName());
-                    Path baseDir = Paths.get(m.getName());
-                    m.invoke(this, new Object[] { baseDir });
-                } catch (InvocationTargetException e) {
-                    Throwable cause = e.getCause();
-                    error("Exception: " + e.getCause());
-                    cause.printStackTrace(out);
-                }
-                out.println();
-            }
-        }
-        if (errors > 0)
-            throw new Exception(errors + " errors occurred");
+    protected void runTests() throws Exception {
+        runTests(m -> new Object[] { Paths.get(m.getName()) });
     }
 
-    // move to ToolBox?
-    // change returntyp to List<Path> -- means updating ToolBox methods
     Path[] findJavaFiles(Path... paths) throws IOException {
-        Set<Path> files = new TreeSet<>();
-        for (Path p : paths) {
-            Files.walkFileTree(p, new SimpleFileVisitor<Path>() {
-                @Override
-                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
-                        throws IOException {
-                    if (file.getFileName().toString().endsWith(".java")) {
-                        files.add(file);
-                    }
-                    return FileVisitResult.CONTINUE;
-                }
-            });
-        }
-        return files.toArray(new Path[files.size()]);
+        return tb.findJavaFiles(paths);
     }
 
     void error(String message) {
@@ -111,79 +77,4 @@
         errors++;
     }
 
-    public class ModuleBuilder {
-
-        private final String name;
-        private String requires = "";
-        private String exports = "";
-        private String uses = "";
-        private String provides = "";
-        private String modulePath = "";
-        private List<String> content = new ArrayList<>();
-
-        public ModuleBuilder(String name) {
-            this.name = name;
-        }
-
-        public ModuleBuilder requiresPublic(String requires, Path... modulePath) {
-            return requires("public " + requires, modulePath);
-        }
-
-        public ModuleBuilder requires(String requires, Path... modulePath) {
-            this.requires += "    requires " + requires + ";\n";
-            this.modulePath += Arrays.stream(modulePath)
-                    .map(Path::toString)
-                    .collect(Collectors.joining(File.pathSeparator));
-            return this;
-        }
-
-        public ModuleBuilder exportsTo(String pkg, String module) {
-            return exports(pkg + " to " + module);
-        }
-
-        public ModuleBuilder exports(String pkg) {
-            this.exports += "    exports " + pkg + ";\n";
-            return this;
-        }
-
-        public ModuleBuilder uses(String uses) {
-            this.uses += "    uses " + uses + ";\n";
-            return this;
-        }
-
-        public ModuleBuilder provides(String service, String implementation) {
-            this.provides += "    provides " + service + " with " + implementation + ";\n";
-            return this;
-        }
-
-        public ModuleBuilder classes(String... content) {
-            this.content.addAll(Arrays.asList(content));
-            return this;
-        }
-
-        public Path write(Path where) throws IOException {
-            Files.createDirectories(where);
-            List<String> sources = new ArrayList<>();
-            sources.add("module " + name + "{"
-                    + requires
-                    + exports
-                    + uses
-                    + provides
-                    + "}");
-            sources.addAll(content);
-            Path moduleSrc = where.resolve(name + "/src");
-            tb.writeJavaFiles(moduleSrc, sources.toArray(new String[]{}));
-            return moduleSrc;
-        }
-
-        public void build(Path where) throws IOException {
-            Path moduleSrc = write(where);
-            new JavacTask(tb)
-                    .outdir(where.resolve(name))
-                    .options("-mp", modulePath)
-                    .files(findJavaFiles(moduleSrc))
-                    .run()
-                    .writeAll();
-        }
-    }
 }
--- a/langtools/test/tools/javac/modules/ModulesAndClassPathTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/ModulesAndClassPathTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -55,7 +55,7 @@
     }
 
     @Test
-    void testModulesAndClassPath(Path base) throws Exception {
+    public void testModulesAndClassPath(Path base) throws Exception {
         Path jar = prepareTestJar(base);
 
         Path moduleSrc = base.resolve("module-src");
@@ -106,7 +106,7 @@
     }
 
     @Test
-    void testImplicitSourcePathModuleInfo(Path base) throws Exception {
+    public void testImplicitSourcePathModuleInfo(Path base) throws Exception {
         Path jar = prepareTestJar(base);
 
         Path moduleSrc = base.resolve("module-src");
@@ -139,7 +139,7 @@
     }
 
     @Test
-    void testModuleInfoFromOutput(Path base) throws Exception {
+    public void testModuleInfoFromOutput(Path base) throws Exception {
         Path jar = prepareTestJar(base);
 
         Path moduleSrc = base.resolve("module-src");
@@ -221,7 +221,7 @@
     }
 
     @Test
-    void testClassOutputVisibleForIncrementalCompilation(Path base) throws Exception {
+    public void testClassOutputVisibleForIncrementalCompilation(Path base) throws Exception {
         Path moduleSrc = base.resolve("module-src");
         Path m1 = moduleSrc.resolve("m1");
 
--- a/langtools/test/tools/javac/modules/MultiModuleModeTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/MultiModuleModeTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -49,7 +49,7 @@
     }
 
     @Test
-    void testDuplicateModules(Path base) throws Exception {
+    public void testDuplicateModules(Path base) throws Exception {
         Path src = base.resolve("src");
         Path src_m1 = src.resolve("m1");
         tb.writeJavaFiles(src_m1, "module m1 { }");
@@ -72,7 +72,7 @@
     }
 
     @Test
-    void testCantFindModule(Path base) throws Exception {
+    public void testCantFindModule(Path base) throws Exception {
         Path src = base.resolve("src");
         Path src_m1 = src.resolve("m1");
         tb.writeJavaFiles(src_m1, "module m1 { }");
@@ -95,7 +95,7 @@
     }
 
     @Test
-    void testModuleNameMismatch(Path base) throws Exception {
+    public void testModuleNameMismatch(Path base) throws Exception {
         Path src = base.resolve("src");
         Path src_m1 = src.resolve("m1");
         tb.writeJavaFiles(src_m1, "module m2 { }");
@@ -116,7 +116,7 @@
     }
 
     @Test
-    void testImplicitModuleSource(Path base) throws Exception {
+    public void testImplicitModuleSource(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src.resolve("m1"), "module m1 { }");
         tb.writeJavaFiles(src.resolve("m2"), "module m2 { requires m1; }");
@@ -132,7 +132,7 @@
     }
 
     @Test
-    void testImplicitModuleClass(Path base) throws Exception {
+    public void testImplicitModuleClass(Path base) throws Exception {
         Path src1 = base.resolve("src1");
         tb.writeJavaFiles(src1.resolve("m1"), "module m1 { }");
         Path modules1 = base.resolve("modules1");
--- a/langtools/test/tools/javac/modules/NPECompilingModuleInfoTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/NPECompilingModuleInfoTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -45,7 +45,7 @@
     }
 
     @Test
-    void testCompileNoError(Path base) throws Exception {
+    public void testCompileNoError(Path base) throws Exception {
         Path mod = base.resolve("mod");
         tb.writeJavaFiles(mod, "module mod { exports pkg; }");
         Path pkg = mod.resolve("pkg");
--- a/langtools/test/tools/javac/modules/NPEEmptyFileTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/NPEEmptyFileTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -45,7 +45,7 @@
     }
 
     @Test
-    void compileEmptyFile(Path base) throws Exception {
+    public void compileEmptyFile(Path base) throws Exception {
         Path modules = base.resolve("modules");
         Files.createDirectories(modules);
         Path emptyJavaFile = base.resolve("Test.java");
--- a/langtools/test/tools/javac/modules/OutputDirTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/OutputDirTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -60,7 +60,7 @@
     }
 
     @Test
-    void testError(Path base) throws Exception {
+    public void testError(Path base) throws Exception {
         String log = new JavacTask(tb)
                 .options("-XDrawDiagnostics",
                         "-modulesourcepath", src.toString())
@@ -74,7 +74,7 @@
     }
 
     @Test
-    void testProcOnly(Path base) throws IOException {
+    public void testProcOnly(Path base) throws IOException {
         new JavacTask(tb)
                 .options("-XDrawDiagnostics",
                         "-proc:only",
@@ -85,7 +85,7 @@
     }
 
     @Test
-    void testClassOutDir(Path base) throws IOException {
+    public void testClassOutDir(Path base) throws IOException {
         Path classes = base.resolve("classes");
         new JavacTask(tb)
                 .options("-XDrawDiagnostics",
@@ -97,7 +97,7 @@
     }
 
     @Test
-    void testExplodedOutDir(Path base) throws Exception {
+    public void testExplodedOutDir(Path base) throws Exception {
         Path modSrc = base.resolve("modSrc");
         tb.writeJavaFiles(modSrc,
                 "module m1 { exports p; }",
@@ -131,7 +131,7 @@
     }
 
     @Test
-    void testInExplodedOutDir(Path base) throws Exception {
+    public void testInExplodedOutDir(Path base) throws Exception {
         Path modSrc = base.resolve("modSrc");
         tb.writeJavaFiles(modSrc,
                 "module m1 { exports p; }",
--- a/langtools/test/tools/javac/modules/PackageConflictTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/PackageConflictTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -28,7 +28,7 @@
  * @modules
  *      jdk.compiler/com.sun.tools.javac.api
  *      jdk.compiler/com.sun.tools.javac.main
- * @build toolbox.ToolBox toolbox.JavacTask ModuleTestBase
+ * @build toolbox.ToolBox toolbox.JavacTask toolbox.ModuleBuilder ModuleTestBase
  * @run main PackageConflictTest
  */
 
@@ -38,6 +38,7 @@
 import java.util.List;
 
 import toolbox.JavacTask;
+import toolbox.ModuleBuilder;
 import toolbox.Task;
 import toolbox.ToolBox;
 
@@ -48,7 +49,7 @@
     }
 
     @Test
-    void testSimple(Path base) throws Exception {
+    public void testSimple(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "package java.util; public class MyList { }");
@@ -68,7 +69,7 @@
     }
 
     @Test
-    void testDisjoint(Path base) throws Exception {
+    public void testDisjoint(Path base) throws Exception {
         Path m1 = base.resolve("m1");
         Path m2 = base.resolve("m2");
         tb.writeJavaFiles(m1,
@@ -89,7 +90,7 @@
     }
 
     @Test
-    void testConflictInDependencies(Path base) throws Exception {
+    public void testConflictInDependencies(Path base) throws Exception {
         Path m1 = base.resolve("m1");
         Path m2 = base.resolve("m2");
         Path m3 = base.resolve("m3");
@@ -123,13 +124,13 @@
     }
 
     @Test
-    void testSimple2(Path base) throws Exception {
+    public void testSimple2(Path base) throws Exception {
         Path modules = base.resolve("modules");
-        new ModuleBuilder("N")
+        new ModuleBuilder(tb, "N")
                 .exports("pack")
                 .classes("package pack; public class A { }")
                 .build(modules);
-        new ModuleBuilder("M")
+        new ModuleBuilder(tb, "M")
                 .requires("N")
                 .classes("package pack; public class B { pack.A f; }")
                 .write(modules);
@@ -147,14 +148,14 @@
     }
 
     @Test
-    void testPrivateConflict(Path base) throws Exception {
+    public void testPrivateConflict(Path base) throws Exception {
         Path modules = base.resolve("modules");
-        new ModuleBuilder("N")
+        new ModuleBuilder(tb, "N")
                 .exports("publ")
                 .classes("package pack; public class A { }")
                 .classes("package publ; public class B { }")
                 .write(modules);
-        new ModuleBuilder("M")
+        new ModuleBuilder(tb, "M")
                 .requires("N")
                 .classes("package pack; public class C { publ.B b; }")
                 .write(modules);
@@ -173,14 +174,14 @@
     }
 
     @Test
-    void testPrivateConflictOnModulePath(Path base) throws Exception {
+    public void testPrivateConflictOnModulePath(Path base) throws Exception {
         Path modules = base.resolve("modules");
-        new ModuleBuilder("N")
+        new ModuleBuilder(tb, "N")
                 .exports("publ")
                 .classes("package pack; public class A { }")
                 .classes("package publ; public class B { }")
                 .build(modules);
-        new ModuleBuilder("M")
+        new ModuleBuilder(tb, "M")
                 .requires("N")
                 .classes("package pack; public class C { publ.B b; }")
                 .write(modules);
@@ -199,17 +200,17 @@
     }
 
     @Test
-    void testRequiresConflictExports(Path base) throws Exception {
+    public void testRequiresConflictExports(Path base) throws Exception {
         Path modules = base.resolve("modules");
-        new ModuleBuilder("M")
+        new ModuleBuilder(tb, "M")
                 .exports("pack")
                 .classes("package pack; public class A { }")
                 .build(modules);
-        new ModuleBuilder("N")
+        new ModuleBuilder(tb, "N")
                 .exports("pack")
                 .classes("package pack; public class B { }")
                 .build(modules);
-        new ModuleBuilder("K")
+        new ModuleBuilder(tb, "K")
                 .requires("M")
                 .requires("N")
                 .classes("package pkg; public class C { pack.A a; pack.B b; }")
@@ -231,18 +232,18 @@
     }
 
     @Test
-    void testQulifiedExportsToDifferentModules(Path base) throws Exception {
+    public void testQulifiedExportsToDifferentModules(Path base) throws Exception {
         Path modules = base.resolve("modules");
-        new ModuleBuilder("U").write(modules);
-        new ModuleBuilder("M")
+        new ModuleBuilder(tb, "U").write(modules);
+        new ModuleBuilder(tb, "M")
                 .exports("pkg to U")
                 .classes("package pkg; public class A { public static boolean flagM; }")
                 .write(modules);
-        new ModuleBuilder("N")
+        new ModuleBuilder(tb, "N")
                 .exports("pkg to K")
                 .classes("package pkg; public class A { public static boolean flagN; }")
                 .write(modules);
-        ModuleBuilder moduleK = new ModuleBuilder("K");
+        ModuleBuilder moduleK = new ModuleBuilder(tb, "K");
         moduleK.requires("M")
                 .requires("N")
                 .classes("package p; public class DependsOnN { boolean f = pkg.A.flagN; } ")
--- a/langtools/test/tools/javac/modules/PackageMultipleModules.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/PackageMultipleModules.java	Thu Apr 28 23:08:16 2016 -0700
@@ -49,7 +49,7 @@
     }
 
     @Test
-    void testSimple(Path base) throws Exception {
+    public void testSimple(Path base) throws Exception {
         Path m1 = base.resolve("m1");
         Path m2 = base.resolve("m2");
         tb.writeJavaFiles(m1,
--- a/langtools/test/tools/javac/modules/PluginsInModulesTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/PluginsInModulesTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -127,7 +127,7 @@
     Path classes;
 
     @Test
-    void testUseOnlyOneProcessor(Path base) throws Exception {
+    public void testUseOnlyOneProcessor(Path base) throws Exception {
         initialization(base);
         List<String> log = new JavacTask(tb)
                 .options("-processormodulepath", processorCompiledModules.toString(),
--- a/langtools/test/tools/javac/modules/ProvidesTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/ProvidesTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -48,7 +48,7 @@
     }
 
     @Test
-    void testSimple(Path base) throws Exception {
+    public void testSimple(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { provides p1.C1 with p2.C2; }",
@@ -65,7 +65,7 @@
     }
 
     @Test
-    void testMulti(Path base) throws Exception {
+    public void testMulti(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src.resolve("m1"),
                 "module m1 { exports p1; }",
@@ -86,7 +86,7 @@
     }
 
     @Test
-    void testMissingWith(Path base) throws Exception {
+    public void testMissingWith(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { provides p.C; }",
@@ -108,7 +108,7 @@
     }
 
     @Test
-    void testDuplicateProvides(Path base) throws Exception {
+    public void testDuplicateProvides(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { provides p1.C1 with p2.C2; provides p1.C1 with p2.C2; }",
@@ -126,7 +126,7 @@
     }
 
     @Test
-    void testMissingService(Path base) throws Exception {
+    public void testMissingService(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { provides p.Missing with p.C; }",
@@ -151,7 +151,7 @@
     }
 
     @Test
-    void testProvidesFromAnotherModule(Path base) throws Exception {
+    public void testProvidesFromAnotherModule(Path base) throws Exception {
         Path modules = base.resolve("modules");
         tb.writeJavaFiles(modules.resolve("M"),
                 "module M { exports p; }",
@@ -177,7 +177,7 @@
     }
 
     @Test
-    void testServiceIsNotImplemented(Path base) throws Exception {
+    public void testServiceIsNotImplemented(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { provides p.A with p.B; }",
@@ -200,7 +200,7 @@
     }
 
     @Test
-    void testMissingImplementation(Path base) throws Exception {
+    public void testMissingImplementation(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { provides p.C with p.Impl; }",
@@ -222,7 +222,7 @@
     }
 
     @Test
-    void testSeveralImplementations(Path base) throws Exception {
+    public void testSeveralImplementations(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { provides p.C with p.Impl1; provides p.C with p.Impl2; }",
@@ -238,7 +238,7 @@
     }
 
     @Test
-    void testOneImplementationsForServices(Path base) throws Exception {
+    public void testOneImplementationsForServices(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { provides p.Service1 with p.Impl; provides p.Service2 with p.Impl; }",
@@ -254,7 +254,7 @@
     }
 
     @Test
-    void testAbstractImplementation(Path base) throws Exception {
+    public void testAbstractImplementation(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { provides p1.C1 with p2.C2; }",
@@ -277,7 +277,7 @@
     }
 
     @Test
-    void testInterfaceImplementation(Path base) throws Exception {
+    public void testInterfaceImplementation(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { provides p1.Service with p2.Impl; }",
@@ -300,7 +300,7 @@
     }
 
     @Test
-    void testProtectedImplementation(Path base) throws Exception {
+    public void testProtectedImplementation(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { provides p1.C1 with p2.C2; }",
@@ -323,7 +323,7 @@
     }
 
     @Test
-    void testNoNoArgConstructor(Path base) throws Exception {
+    public void testNoNoArgConstructor(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { uses p1.C1; provides p1.C1 with p2.C2; }",
@@ -346,7 +346,7 @@
     }
 
     @Test
-    void testPrivateNoArgConstructor(Path base) throws Exception {
+    public void testPrivateNoArgConstructor(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { uses p1.C1; provides p1.C1 with p2.C2; }",
@@ -369,7 +369,7 @@
     }
 
     @Test
-    void testServiceIndirectlyImplemented(Path base) throws Exception {
+    public void testServiceIndirectlyImplemented(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { provides p1.C1 with p2.C3; }",
@@ -385,7 +385,7 @@
     }
 
     @Test
-    void testServiceImplementationInnerClass(Path base) throws Exception {
+    public void testServiceImplementationInnerClass(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { provides p1.C1 with p2.C2.Inner; }",
@@ -408,7 +408,7 @@
     }
 
     @Test
-    void testServiceDefinitionInnerClass(Path base) throws Exception {
+    public void testServiceDefinitionInnerClass(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { provides p1.C1.InnerDefinition with p2.C2; }",
--- a/langtools/test/tools/javac/modules/QueryBeforeEnter.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/QueryBeforeEnter.java	Thu Apr 28 23:08:16 2016 -0700
@@ -65,7 +65,7 @@
     }
 
     @Test
-    void testEmpty(Path base) throws Exception {
+    public void testEmpty(Path base) throws Exception {
         JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
         com.sun.source.util.JavacTask task =
             (com.sun.source.util.JavacTask) javaCompiler.getTask(null, null, null, null, null, null);
@@ -75,7 +75,7 @@
     }
 
     @Test
-    void testUnnamed(Path base) throws Exception {
+    public void testUnnamed(Path base) throws Exception {
         Path moduleSrc = base.resolve("module-src");
         Path m1 = moduleSrc.resolve("m1");
 
@@ -151,7 +151,7 @@
     }
 
     @Test
-    void testSingleNamed(Path base) throws Exception {
+    public void testSingleNamed(Path base) throws Exception {
         Path moduleSrc = base.resolve("module-src");
         Path m1 = moduleSrc.resolve("m1");
 
@@ -226,7 +226,7 @@
     }
 
     @Test
-    void testMultiModule(Path base) throws Exception {
+    public void testMultiModule(Path base) throws Exception {
         Path modulePathSrc = base.resolve("module-path-src");
         Path m1 = modulePathSrc.resolve("m1");
 
@@ -311,7 +311,7 @@
     }
 
     @Test
-    void testTooSoon(Path base) throws Exception {
+    public void testTooSoon(Path base) throws Exception {
         Path src = base.resolve("src");
 
         tb.writeJavaFiles(src,
--- a/langtools/test/tools/javac/modules/RepeatedUsesAndProvidesTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/RepeatedUsesAndProvidesTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -46,7 +46,7 @@
     }
 
     @Test
-    void testDuplicateUses(Path base) throws Exception {
+    public void testDuplicateUses(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { uses p1.C1; uses p1.C1; }",
@@ -66,7 +66,7 @@
     }
 
     @Test
-    void testDuplicateProvides(Path base) throws Exception {
+    public void testDuplicateProvides(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { provides p1.C1 with p2.C2; provides p1.C1 with p2.C2; }",
--- a/langtools/test/tools/javac/modules/ReportNonExistentPackageTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/ReportNonExistentPackageTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -46,7 +46,7 @@
     }
 
     @Test
-    void testExportUnknownPackage(Path base) throws Exception {
+    public void testExportUnknownPackage(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src, "module m { exports p1; }");
         Path classes = base.resolve("classes");
@@ -64,7 +64,7 @@
     }
 
     @Test
-    void testExportEmptyPackage(Path base) throws Exception {
+    public void testExportEmptyPackage(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { exports p1; }",
@@ -84,7 +84,7 @@
     }
 
     @Test
-    void testPackageWithMemberWOPackageDeclaration(Path base) throws Exception {
+    public void testPackageWithMemberWOPackageDeclaration(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src, "module m { exports p1; }");
         Path p1 = src.resolve("p1");
--- a/langtools/test/tools/javac/modules/RequiresPublicTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/RequiresPublicTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -47,7 +47,7 @@
     }
 
     @Test
-    void testJavaSE_OK(Path base) throws Exception {
+    public void testJavaSE_OK(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { requires java.se; }",
@@ -66,7 +66,7 @@
     }
 
     @Test
-    void testJavaSE_Fail(Path base) throws Exception {
+    public void testJavaSE_Fail(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { requires java.se; }",
@@ -90,7 +90,7 @@
     }
 
     @Test
-    void testComplex_OK(Path base) throws Exception {
+    public void testComplex_OK(Path base) throws Exception {
         Path src = getComplexSrc(base, "", "");
         Path classes = base.resolve("classes");
         Files.createDirectories(classes);
@@ -104,7 +104,7 @@
     }
 
     @Test
-    void testComplex_Fail(Path base) throws Exception {
+    public void testComplex_Fail(Path base) throws Exception {
         Path src = getComplexSrc(base,
                 "import p5.C5; import p6.C6; import p7.C7;\n",
                 "C5 c5; C6 c6; C7 c7;\n");
--- a/langtools/test/tools/javac/modules/ResolveTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/ResolveTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -45,7 +45,7 @@
     }
 
     @Test
-    void testMissingSimpleTypeUnnamedModule(Path base) throws Exception {
+    public void testMissingSimpleTypeUnnamedModule(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src, "class C { D d; }");
 
@@ -62,7 +62,7 @@
     }
 
     @Test
-    void testMissingSimpleTypeNamedModule(Path base) throws Exception {
+    public void testMissingSimpleTypeNamedModule(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { }",
@@ -81,7 +81,7 @@
     }
 
     @Test
-    void testUnexportedTypeUnreadableModule(Path base) throws Exception {
+    public void testUnexportedTypeUnreadableModule(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src.resolve("m1"),
                 "module m1 { }",
@@ -105,7 +105,7 @@
     }
 
     @Test
-    void testUnexportedTypeReadableModule(Path base) throws Exception {
+    public void testUnexportedTypeReadableModule(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src.resolve("m1"),
                 "module m1 { }",
@@ -129,7 +129,7 @@
     }
 
     @Test
-    void testQualifiedExportedTypeReadableModule(Path base) throws Exception {
+    public void testQualifiedExportedTypeReadableModule(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src.resolve("m1"),
                 "module m1 { exports p1 to m3; }",
@@ -155,7 +155,7 @@
     }
 
     @Test
-    void testExportedTypeUnreadableModule(Path base) throws Exception {
+    public void testExportedTypeUnreadableModule(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src.resolve("m1"),
                 "module m1 { exports p1; }",
@@ -179,7 +179,7 @@
     }
 
     @Test
-    void testExportedTypeReadableModule(Path base) throws Exception {
+    public void testExportedTypeReadableModule(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src.resolve("m1"),
                 "module m1 { exports p1; }",
@@ -199,7 +199,7 @@
     }
 
     @Test
-    void testExportedTypeReadableModule2(Path base) throws Exception {
+    public void testExportedTypeReadableModule2(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src.resolve("m1"),
                 "module m1 { exports p1 to m2; }",
--- a/langtools/test/tools/javac/modules/ServiceInStaticClassErrorTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/ServiceInStaticClassErrorTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -48,7 +48,7 @@
     }
 
     @Test
-    void testError(Path base) throws Exception {
+    public void testError(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { provides p1.I with p1.Outer.A; }",
--- a/langtools/test/tools/javac/modules/ServiceProvidedButNotExportedOrUsedTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/ServiceProvidedButNotExportedOrUsedTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -49,7 +49,7 @@
     }
 
     @Test
-    void testWarning(Path base) throws Exception {
+    public void testWarning(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { provides p1.C1 with p2.C2; }",
@@ -76,7 +76,7 @@
     }
 
     @Test
-    void testImplementationMustBeInSameModuleAsProvidesDirective(Path base) throws Exception {
+    public void testImplementationMustBeInSameModuleAsProvidesDirective(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src.resolve("m1"),
                 "module m1 { exports p1; }",
--- a/langtools/test/tools/javac/modules/SingleModuleModeTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/SingleModuleModeTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -59,7 +59,7 @@
     }
 
     @Test
-    void testTooManyModules(Path base) throws Exception {
+    public void testTooManyModules(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src.resolve("m1"), "module m1 { }");
         tb.writeJavaFiles(src.resolve("m2"), "module m2 { }");
@@ -76,7 +76,7 @@
     }
 
     @Test
-    void testImplicitModuleSource(Path base) throws Exception {
+    public void testImplicitModuleSource(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { }",
@@ -90,7 +90,7 @@
     }
 
     @Test
-    void testImplicitModuleClass(Path base) throws Exception {
+    public void testImplicitModuleClass(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { }",
@@ -112,7 +112,7 @@
     }
 
     @Test
-    void testImplicitModuleClassAP(Path base) throws Exception {
+    public void testImplicitModuleClassAP(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { uses java.lang.Runnable; }",
@@ -137,7 +137,7 @@
     }
 
     @Test
-    void testImplicitModuleSourceAP(Path base) throws Exception {
+    public void testImplicitModuleSourceAP(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { uses java.lang.Runnable; }",
--- a/langtools/test/tools/javac/modules/SubpackageTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/SubpackageTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -52,7 +52,7 @@
     }
 
     @Test // based on JDK-8075435
-    void testUnnamedModule(Path base) throws Exception {
+    public void testUnnamedModule(Path base) throws Exception {
         Path libsrc = base.resolve("lib/src");
         tb.writeJavaFiles(libsrc,
             "package p; public class E extends Error { }");
@@ -83,7 +83,7 @@
     }
 
     @Test
-    void testSimpleMulti(Path base) throws Exception {
+    public void testSimpleMulti(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src.resolve("mp"),
                 "module mp { exports p; }",
--- a/langtools/test/tools/javac/modules/UpgradeModulePathTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/UpgradeModulePathTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -28,7 +28,7 @@
  * @modules
  *      jdk.compiler/com.sun.tools.javac.api
  *      jdk.compiler/com.sun.tools.javac.main
- * @build toolbox.ToolBox toolbox.JavacTask ModuleTestBase
+ * @build toolbox.ToolBox toolbox.JavacTask toolbox.ModuleBuilder ModuleTestBase
  * @run main UpgradeModulePathTest
  */
 
@@ -36,6 +36,7 @@
 import java.nio.file.Path;
 
 import toolbox.JavacTask;
+import toolbox.ModuleBuilder;
 import toolbox.Task;
 import toolbox.ToolBox;
 
@@ -47,15 +48,15 @@
     }
 
     @Test
-    void simpleUsage(Path base) throws Exception {
+    public void simpleUsage(Path base) throws Exception {
         final Path module = base.resolve("modules");
-        new ModuleBuilder("m1")
+        new ModuleBuilder(tb, "m1")
                 .exports("pkg1")
                 .classes("package pkg1; public class E { }")
                 .build(module);
 
         final Path upgradeModule = base.resolve("upgradeModule");
-        new ModuleBuilder("m1")
+        new ModuleBuilder(tb, "m1")
                 .exports("pkg2")
                 .classes("package pkg2; public class E { }")
                 .build(upgradeModule);
@@ -73,15 +74,15 @@
     }
 
     @Test
-    void onlyUpgradeModulePath(Path base) throws Exception {
+    public void onlyUpgradeModulePath(Path base) throws Exception {
         final Path module = base.resolve("modules");
-        new ModuleBuilder("m1")
+        new ModuleBuilder(tb, "m1")
                 .exports("pkg1")
                 .classes("package pkg1; public class E { }")
                 .build(module);
 
         final Path upgradeModule = base.resolve("upgradeModule");
-        new ModuleBuilder("m1")
+        new ModuleBuilder(tb, "m1")
                 .exports("pkg2")
                 .classes("package pkg2; public class E { }")
                 .build(upgradeModule);
@@ -98,15 +99,15 @@
     }
 
     @Test
-    void withModuleSourcePath(Path base) throws Exception {
+    public void withModuleSourcePath(Path base) throws Exception {
         final Path module = base.resolve("modules");
-        new ModuleBuilder("m1")
+        new ModuleBuilder(tb, "m1")
                 .exports("pkg1")
                 .classes("package pkg1; public class E { }")
                 .build(module);
 
         final Path upgradeModule = base.resolve("upgradeModule");
-        new ModuleBuilder("m1")
+        new ModuleBuilder(tb, "m1")
                 .exports("pkg2")
                 .classes("package pkg2; public class E { }")
                 .build(upgradeModule);
@@ -115,7 +116,7 @@
         tb.writeJavaFiles(s.resolve("m3"), "module m3 { }");
 
         final Path upgradeModule3 = base.resolve("upgradeModule");
-        new ModuleBuilder("m3")
+        new ModuleBuilder(tb, "m3")
                 .exports("pkg3")
                 .classes("package pkg3; public class E { }")
                 .build(upgradeModule);
@@ -135,15 +136,15 @@
     }
 
     @Test
-    void sameUpgradeAndModulePath(Path base) throws Exception {
+    public void sameUpgradeAndModulePath(Path base) throws Exception {
         final Path module = base.resolve("modules");
-        new ModuleBuilder("m1")
+        new ModuleBuilder(tb, "m1")
                 .exports("pkg1")
                 .classes("package pkg1; public class E { }")
                 .build(module);
 
         final Path upgradeModule = base.resolve("upgradeModule");
-        new ModuleBuilder("m1")
+        new ModuleBuilder(tb, "m1")
                 .exports("pkg2")
                 .classes("package pkg2; public class E { }")
                 .build(upgradeModule);
@@ -161,9 +162,9 @@
     }
 
     @Test
-    void dummyFileInUpgradeModulePath(Path base) throws Exception {
+    public void dummyFileInUpgradeModulePath(Path base) throws Exception {
         final Path module = base.resolve("modules");
-        new ModuleBuilder("m1")
+        new ModuleBuilder(tb, "m1")
                 .exports("pkg1")
                 .classes("package pkg1; public class E { }")
                 .build(module);
@@ -189,24 +190,24 @@
     }
 
     @Test
-    void severalUpgradeModules(Path base) throws Exception {
+    public void severalUpgradeModules(Path base) throws Exception {
         final Path module = base.resolve("modules");
-        new ModuleBuilder("m1")
+        new ModuleBuilder(tb, "m1")
                 .exports("pkg1")
                 .classes("package pkg1; public class A { }")
                 .build(module);
 
-        new ModuleBuilder("m2")
+        new ModuleBuilder(tb, "m2")
                 .exports("pkg2")
                 .classes("package pkg2; public class B { }")
                 .build(module);
 
         Path upgradeModule = base.resolve("upgradeModule");
-        new ModuleBuilder("m2")
+        new ModuleBuilder(tb, "m2")
                 .exports("pkg2")
                 .classes("package pkg2; public class BC { }")
                 .build(upgradeModule);
-        new ModuleBuilder("m3")
+        new ModuleBuilder(tb, "m3")
                 .exports("pkg3")
                 .classes("package pkg3; public class DC { }")
                 .build(upgradeModule);
@@ -240,21 +241,21 @@
     }
 
     @Test
-    void severalUpgradeModulePathsLastWin(Path base) throws Exception {
+    public void severalUpgradeModulePathsLastWin(Path base) throws Exception {
         final Path module = base.resolve("modules");
-        new ModuleBuilder("m1")
+        new ModuleBuilder(tb, "m1")
                 .exports("pkg1")
                 .classes("package pkg1; public class E { }")
                 .build(module);
 
         final Path upgradeModule1 = base.resolve("upgradeModule1");
-        new ModuleBuilder("m1")
+        new ModuleBuilder(tb, "m1")
                 .exports("pkg2")
                 .classes("package pkg2; public class EC1 { }")
                 .build(upgradeModule1);
 
         final Path upgradeModule2 = base.resolve("upgradeModule2");
-        new ModuleBuilder("m1")
+        new ModuleBuilder(tb, "m1")
                 .exports("pkg2")
                 .classes("package pkg2; public class EC2 { }")
                 .build(upgradeModule2);
--- a/langtools/test/tools/javac/modules/UsesTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/UsesTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -28,7 +28,7 @@
  * @modules
  *      jdk.compiler/com.sun.tools.javac.api
  *      jdk.compiler/com.sun.tools.javac.main
- * @build toolbox.ToolBox toolbox.JavacTask ModuleTestBase
+ * @build toolbox.ToolBox toolbox.JavacTask toolbox.ModuleBuilder ModuleTestBase
  * @run main UsesTest
  */
 
@@ -39,6 +39,7 @@
 import java.util.List;
 
 import toolbox.JavacTask;
+import toolbox.ModuleBuilder;
 import toolbox.Task;
 import toolbox.ToolBox;
 
@@ -49,7 +50,7 @@
     }
 
     @Test
-    void testSimple(Path base) throws Exception {
+    public void testSimple(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { uses p.C; }",
@@ -65,7 +66,7 @@
     }
 
     @Test
-    void testSimpleInner(Path base) throws Exception {
+    public void testSimpleInner(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { uses p.C.Inner; }",
@@ -81,7 +82,7 @@
     }
 
     @Test
-    void testSimpleAnnotation(Path base) throws Exception {
+    public void testSimpleAnnotation(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { uses p.C; }",
@@ -97,7 +98,7 @@
     }
 
     @Test
-    void testPrivateService(Path base) throws Exception {
+    public void testPrivateService(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { uses p.C.A; uses p.C; }",
@@ -119,7 +120,7 @@
     }
 
     @Test
-    void testMulti(Path base) throws Exception {
+    public void testMulti(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src.resolve("m1"),
                 "module m1 { exports p; }",
@@ -138,13 +139,13 @@
     }
 
     @Test
-    void testMultiOnModulePath(Path base) throws Exception {
+    public void testMultiOnModulePath(Path base) throws Exception {
         Path modules = base.resolve("modules");
-        new ModuleBuilder("m1")
+        new ModuleBuilder(tb, "m1")
                 .exports("p")
                 .classes("package p; public class C { }")
                 .build(modules);
-        new ModuleBuilder("m2")
+        new ModuleBuilder(tb, "m2")
                 .requires("m1")
                 .uses("p.C")
                 .write(modules);
@@ -158,13 +159,13 @@
     }
 
     @Test
-    void testMultiOnModulePathInner(Path base) throws Exception {
+    public void testMultiOnModulePathInner(Path base) throws Exception {
         Path modules = base.resolve("modules");
-        new ModuleBuilder("m1")
+        new ModuleBuilder(tb, "m1")
                 .exports("p")
                 .classes("package p; public class C { public class Inner { } }")
                 .build(modules);
-        new ModuleBuilder("m2")
+        new ModuleBuilder(tb, "m2")
                 .requires("m1")
                 .uses("p.C.Inner")
                 .write(modules);
@@ -178,7 +179,7 @@
     }
 
     @Test
-    void testDuplicateUses(Path base) throws Exception {
+    public void testDuplicateUses(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src.resolve("m"),
                 "module m { uses p.C; uses p.C; }",
@@ -199,7 +200,7 @@
     }
 
     @Test
-    void testServiceNotExist(Path base) throws Exception {
+    public void testServiceNotExist(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { uses p.NotExist; }",
@@ -220,7 +221,7 @@
     }
 
     @Test
-    void testUsesUnexportedService(Path base) throws Exception {
+    public void testUsesUnexportedService(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src.resolve("m1"),
                 "module m1 { }",
@@ -244,7 +245,7 @@
     }
 
     @Test
-    void testUsesUnexportedButProvidedService(Path base) throws Exception {
+    public void testUsesUnexportedButProvidedService(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src.resolve("m1"),
                 "module m1 { provides p.C with p.C; }",
--- a/langtools/test/tools/javac/modules/XModuleTest.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/modules/XModuleTest.java	Thu Apr 28 23:08:16 2016 -0700
@@ -28,7 +28,7 @@
  * @modules
  *      jdk.compiler/com.sun.tools.javac.api
  *      jdk.compiler/com.sun.tools.javac.main
- * @build toolbox.ToolBox toolbox.JavacTask ModuleTestBase
+ * @build toolbox.ToolBox toolbox.JavacTask toolbox.ModuleBuilder ModuleTestBase
  * @run main XModuleTest
  */
 
@@ -37,7 +37,9 @@
 import java.util.List;
 
 import toolbox.JavacTask;
+import toolbox.ModuleBuilder;
 import toolbox.Task;
+import toolbox.TestRunner;
 import toolbox.ToolBox;
 
 public class XModuleTest extends ModuleTestBase {
@@ -47,7 +49,7 @@
     }
 
     @Test
-    void testCorrectXModule(Path base) throws Exception {
+    public void testCorrectXModule(Path base) throws Exception {
         //note: avoiding use of java.base, as that gets special handling on some places:
         Path src = base.resolve("src");
         tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element { }");
@@ -67,7 +69,7 @@
     }
 
     @Test
-    void testSourcePath(Path base) throws Exception {
+    public void testSourcePath(Path base) throws Exception {
         //note: avoiding use of java.base, as that gets special handling on some places:
         Path src = base.resolve("src");
         tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element, Other { }", "package javax.lang.model.element; interface Other { }");
@@ -87,7 +89,7 @@
     }
 
     @Test
-    void testClassPath(Path base) throws Exception {
+    public void testClassPath(Path base) throws Exception {
         Path cpSrc = base.resolve("cpSrc");
         tb.writeJavaFiles(cpSrc, "package p; public interface Other { }");
         Path cpClasses = base.resolve("cpClasses");
@@ -122,7 +124,7 @@
     }
 
     @Test
-    void testNoModuleInfoOnSourcePath(Path base) throws Exception {
+    public void testNoModuleInfoOnSourcePath(Path base) throws Exception {
         //note: avoiding use of java.base, as that gets special handling on some places:
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
@@ -147,7 +149,7 @@
     }
 
     @Test
-    void testNoModuleInfoInClassOutput(Path base) throws Exception {
+    public void testNoModuleInfoInClassOutput(Path base) throws Exception {
         //note: avoiding use of java.base, as that gets special handling on some places:
         Path srcMod = base.resolve("src-mod");
         tb.writeJavaFiles(srcMod,
@@ -187,7 +189,7 @@
     }
 
     @Test
-    void testModuleSourcePathXModule(Path base) throws Exception {
+    public void testModuleSourcePathXModule(Path base) throws Exception {
         //note: avoiding use of java.base, as that gets special handling on some places:
         Path src = base.resolve("src");
         tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element { }");
@@ -210,7 +212,7 @@
     }
 
     @Test
-    void testXModuleTooMany(Path base) throws Exception {
+    public void testXModuleTooMany(Path base) throws Exception {
         //note: avoiding use of java.base, as that gets special handling on some places:
         Path src = base.resolve("src");
         tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element { }");
@@ -234,9 +236,9 @@
     }
 
     @Test
-    void testWithModulePath(Path base) throws Exception {
+    public void testWithModulePath(Path base) throws Exception {
         Path module = base.resolve("modules");
-        new ModuleBuilder("m1")
+        new ModuleBuilder(tb, "m1")
                 .classes("package pkg1; public interface E { }")
                 .build(module);
 
@@ -251,7 +253,7 @@
                 .writeAll();
 
         //checks module bounds still exist
-        new ModuleBuilder("m2")
+        new ModuleBuilder(tb, "m2")
                 .classes("package pkg2; public interface D { }")
                 .build(module);
 
@@ -275,14 +277,14 @@
     }
 
     @Test
-    void testWithUpgradeModulePath(Path base) throws Exception {
+    public void testWithUpgradeModulePath(Path base) throws Exception {
         Path module = base.resolve("modules");
-        new ModuleBuilder("m1")
+        new ModuleBuilder(tb, "m1")
                 .classes("package pkg1; public interface E { }")
                 .build(module);
 
         Path upgrade = base.resolve("upgrade");
-        new ModuleBuilder("m1")
+        new ModuleBuilder(tb, "m1")
                 .classes("package pkg1; public interface D { }")
                 .build(upgrade);
 
--- a/langtools/test/tools/javac/policy/test3/A.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/policy/test3/A.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,3 +1,5 @@
+/* /nodynamiccopyright/ */
+
 class A {
     void m1() {
         System.err.println("hello");
--- a/langtools/test/tools/javac/positions/T6253161.java	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * @test  /nodynamiccopyright/
- * @bug     6253161
- * @summary Compiler will fail to find the correct location of serial warnings for anonymous inner classes
- * @author  Seetharama Avadhanam
- * @compile -Xlint:serial -XDdev T6253161.java
- * @compile/ref=T6253161.out -Xlint:serial -XDdev -XDrawDiagnostics T6253161.java
- */
-import java.util.List;
-import java.util.ArrayList;
-
-public class T6253161 {
-    @SuppressWarnings("unchecked")
-    public void anonymousMethod(){
-           List list = new ArrayList<String>(){
-           static final long serialVersionUID = 1;
-           List list = new ArrayList<Integer>();
-           public List<Integer> getMyList(){
-                final List floatList = new ArrayList<Float>(){
-                    List integerList = new ArrayList<Float>();
-                    public List<Float> getMyList(){
-                        for(int i=0;i<10;i++)
-                            integerList.add((int)((Float.parseFloat(i+""))+(1.11F)));
-                        return (List)(Object)integerList;
-                    }
-                    public void testMethods(){
-                        //...
-                    }
-                }.getMyList();
-                for(int i=0;i<10;i++)
-                    list.add((Float)(floatList.get(i)) * 11.232F * i);
-                return list;
-            }
-         }.getMyList();
-    }
-}
--- a/langtools/test/tools/javac/positions/T6253161.out	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-T6253161.java:19:62: compiler.warn.missing.SVUID: compiler.misc.anonymous.class: T6253161$1$1
-1 warning
--- a/langtools/test/tools/javac/positions/T6253161a.java	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/*
- * @test  /nodynamiccopyright/
- * @bug     6253161
- * @summary Compiler will fail to find the correct location of serial warnings for anonymous inner classes
- * @author  Seetharama Avadhanam
- * @compile -Xlint:serial -XDdev T6253161a.java
- * @compile/ref=T6253161a.out -Xlint:serial -XDdev -XDrawDiagnostics T6253161a.java
- */
-import java.util.List;
-import java.util.ArrayList;
-
-public class T6253161a {
-    @SuppressWarnings("unchecked")
-    public void anonymousMethod(){
-           List list = new ArrayList<String>(){
-           static final long serialVersionUID = 1;
-           List list = new ArrayList<Integer>();
-           public List<Integer> getMyList(){
-                final List floatList = new ArrayList<Float>(){
-                    // Blank ....
-                };
-                for(int i=0;i<10;i++)
-                    list.add((Float)(floatList.get(i)) * 11.232F * i);
-                return list;
-            }
-         }.getMyList();
-    }
-}
--- a/langtools/test/tools/javac/positions/T6253161a.out	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-T6253161a.java:19:62: compiler.warn.missing.SVUID: compiler.misc.anonymous.class: T6253161a$1$1
-1 warning
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/serial/SerialWarn.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,11 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 4854628
+ * @summary include Throwable subclasses in missing serialVersionUID warning
+ * @author gafter
+ *
+ * @compile                    -Werror SerialWarn.java
+ * @compile/fail/ref=SerialWarn.out -XDrawDiagnostics -Xlint:serial -Werror SerialWarn.java
+ */
+
+class SerialWarn extends Throwable {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/serial/SerialWarn.out	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,4 @@
+SerialWarn.java:11:1: compiler.warn.missing.SVUID: SerialWarn
+- compiler.err.warnings.and.werror
+1 error
+1 warning
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/serial/SerialWarnAnon.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,15 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 7152104
+ * @summary Make sure no warning is emitted for anonymous classes
+ *          without serialVersionUID
+ * @compile SerialWarn.java
+ * @compile -Werror -XDrawDiagnostics -Xlint:serial SerialWarnAnon.java
+ */
+
+class SerialWarnAnon {
+    interface SerialWarnAnonInterface extends java.io.Serializable { }
+    Object m() {
+        return new SerialWarnAnonInterface() { };
+    }
+}
--- a/langtools/test/tools/javac/synthesize/src/Double.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/synthesize/src/Double.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2007, 2016, 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 java.lang;
 
 public class Double extends Number
--- a/langtools/test/tools/javac/synthesize/src/Float.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/synthesize/src/Float.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2007, 2016, 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 java.lang;
 
 public class Float extends Number
--- a/langtools/test/tools/javac/warnings/6594914/Auxiliary.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/warnings/6594914/Auxiliary.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,3 +1,5 @@
+/* /nodynamiccopyright/ */
+
 import java.io.StringBufferInputStream;
 
 public class Auxiliary {
--- a/langtools/test/tools/javac/warnings/6594914/ExplicitCompilation.out	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/warnings/6594914/ExplicitCompilation.out	Thu Apr 28 23:08:16 2016 -0700
@@ -1,2 +1,2 @@
-Auxiliary.java:1:15: compiler.warn.has.been.deprecated: java.io.StringBufferInputStream, java.io
+Auxiliary.java:3:15: compiler.warn.has.been.deprecated: java.io.StringBufferInputStream, java.io
 1 warning
--- a/langtools/test/tools/javac/warnings/6594914/ImplicitCompilation.out	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javac/warnings/6594914/ImplicitCompilation.out	Thu Apr 28 23:08:16 2016 -0700
@@ -1,2 +1,2 @@
-Auxiliary.java:1:15: compiler.warn.has.been.deprecated: java.io.StringBufferInputStream, java.io
+Auxiliary.java:3:15: compiler.warn.has.been.deprecated: java.io.StringBufferInputStream, java.io
 1 warning
--- a/langtools/test/tools/javadoc/6964914/TestStdDoclet.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javadoc/6964914/TestStdDoclet.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
  */
 
 import java.io.*;
+import java.util.*;
 
 /**
  * Dummy javadoc comment.
@@ -54,13 +55,21 @@
         // run javadoc in separate process to ensure doclet executed under
         // normal user conditions w.r.t. classloader
         String thisClassName = TestStdDoclet.class.getName();
-        Process p = new ProcessBuilder()
-            .command(javadoc.getPath(),
-                "-J-Xpatch:" + System.getProperty("jdk.launcher.patch.0", ""),
+        List<String> cmdArgs = new ArrayList<>();
+        cmdArgs.add(javadoc.getPath());
+        int i = 0;
+        String prop;
+        while ((prop = System.getProperty("jdk.launcher.patch." + (i++))) != null) {
+            cmdArgs.add("-J-Xpatch:" + prop);
+        }
+        cmdArgs.addAll(Arrays.asList(
                 "-classpath", ".", // insulates us from ambient classpath
                 "-Xdoclint:none",
                 "-package",
-                new File(testSrc, thisClassName + ".java").getPath())
+                new File(testSrc, thisClassName + ".java").getPath()
+        ));
+        Process p = new ProcessBuilder()
+            .command(cmdArgs)
             .redirectErrorStream(true)
             .start();
 
--- a/langtools/test/tools/javadoc/6964914/TestUserDoclet.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javadoc/6964914/TestUserDoclet.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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,6 +29,8 @@
  */
 
 import java.io.*;
+import java.util.*;
+
 import com.sun.javadoc.Doclet;
 import com.sun.javadoc.RootDoc;
 
@@ -55,12 +57,20 @@
         // run javadoc in separate process to ensure doclet executed under
         // normal user conditions w.r.t. classloader
         String thisClassName = TestUserDoclet.class.getName();
-        Process p = new ProcessBuilder()
-            .command(javadoc.getPath(),
-                "-J-Xpatch:" + System.getProperty("jdk.launcher.patch.0", ""),
+        List<String> cmdArgs = new ArrayList<>();
+        cmdArgs.add(javadoc.getPath());
+        int i = 0;
+        String prop;
+        while ((prop = System.getProperty("jdk.launcher.patch." + (i++))) != null) {
+            cmdArgs.add("-J-Xpatch:" + prop);
+        }
+        cmdArgs.addAll(Arrays.asList(
                 "-doclet", thisClassName,
                 "-docletpath", testClasses.getPath(),
-                new File(testSrc, thisClassName + ".java").getPath())
+                new File(testSrc, thisClassName + ".java").getPath()
+        ));
+        Process p = new ProcessBuilder()
+            .command(cmdArgs)
             .redirectErrorStream(true)
             .start();
 
--- a/langtools/test/tools/javadoc/sampleapi/lib/sampleapi/SampleApi.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javadoc/sampleapi/lib/sampleapi/SampleApi.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, 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
@@ -53,5 +53,8 @@
         public Fault(String msg) {
             super(msg);
         }
+        public Fault(String msg, Throwable th) {
+            super(msg, th);
+        }
     }
 }
--- a/langtools/test/tools/javadoc/sampleapi/lib/sampleapi/generator/DocCommentGenerator.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javadoc/sampleapi/lib/sampleapi/generator/DocCommentGenerator.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, 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
@@ -32,6 +32,8 @@
 import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.util.List;
+import java.util.HashMap;
+import java.util.Map;
 
 class DocCommentGenerator {
 
@@ -99,14 +101,25 @@
         LITERAL("@literal", "Use < and > brackets instead of &lt; and &gt; escapes."),
         CODE("@code", "(i) -> new Abc<Object>((i > 0) ? (i << 1) : 0)"),
         LINK("@link", ""),
-        VALUE("@value", "");
+        VALUE("@value", ""),
+        INDEX("@index", "", true);
 
         String tagName;
         String tagValue;
+        boolean counted;
+        Map<String, Integer> counters;
 
         InlineTag(String tagName, String tagValue) {
+            this(tagName, tagValue, false);
+        }
+
+        InlineTag(String tagName, String tagValue, boolean counted) {
             this.tagName = tagName;
             this.tagValue = tagValue;
+            this.counted = counted;
+            if (counted) {
+                counters = new HashMap<>();
+            }
         }
 
         public String toString() {
@@ -114,9 +127,14 @@
         }
 
         public String value(String value) {
+            String name = ((tagValue.length() != 0) ? " " + tagValue : "")
+                   + ((value.length() != 0) ? " " + value : "");
+            if (counted && !counters.containsKey(name)) {
+                counters.put(name, 0);
+            }
             return "{" + tagName
-                   + ((tagValue.length() != 0) ? " " + tagValue : "")
-                   + ((value.length() != 0) ? " " + value : "")
+                   + name
+                   + (counted ? "_" + counters.put(name, counters.get(name) + 1) : "")
                    + "}";
         }
     }
@@ -179,7 +197,8 @@
     //
 
     public String getPackageComment() {
-        return Text.LOREMIPSUM
+        return InlineTag.INDEX.value("PackageCommentLabel") + " "
+               + Text.LOREMIPSUM
                + "\n <p>" + Text.LIEUROPANLINGUES
                + "\n" + Text.CODE
                + "\n" + LinkTag.nextLink()
@@ -192,7 +211,9 @@
     static int serialValIdx = 0;
 
     public String getBaseComment(JCClassDecl baseDecl, boolean toplevel) {
-        String buildComment = Text.LIEUROPANLINGUES + "\n";
+        String buildComment = InlineTag.INDEX.value("BaseCommentLabel") + " ";
+
+        buildComment += Text.LIEUROPANLINGUES + "\n";
 
         buildComment += "<p>It is possible to see inlined code:\n"
                         + InlineTag.CODE
@@ -237,8 +258,9 @@
     }
 
     public String getConstComment() {
-        String buildComment = Text.NOWISTHETIME + " " + Text.BROWNFOX + "\n";
+        String buildComment = InlineTag.INDEX.value("ConstCommentLabel") + " ";
 
+        buildComment += Text.NOWISTHETIME + " " + Text.BROWNFOX + "\n";
         buildComment += LinkTag.nextLink() + "\n";
         buildComment += LinkTag.nextSee() + "\n";
         buildComment += Tag.SINCE + "\n";
@@ -249,8 +271,9 @@
     public String getFieldComment(JCClassDecl baseDecl,
                                   JCVariableDecl varDecl,
                                   boolean isFxStyle) {
-        String buildComment = Text.BROWNFOX + "<p>" + Text.NOWISTHETIME + "\n";
+        String buildComment = InlineTag.INDEX.value("FieldCommentLabel") + " ";
 
+        buildComment += Text.BROWNFOX + "<p>" + Text.NOWISTHETIME + "\n";
         Set<Modifier> mods = varDecl.getModifiers().getFlags();
         String varName = varDecl.getName().toString();
 
@@ -299,7 +322,9 @@
     public String getMethodComment(JCClassDecl baseDecl,
                                    JCMethodDecl methodDecl,
                                    boolean isFxStyle) {
-        String buildComment = Text.BROWNFOX + "\n<p>" + Text.THISPANGRAM + "\n";
+        String buildComment = InlineTag.INDEX.value("MethodCommentLabel") + " ";
+
+        buildComment += Text.BROWNFOX + "\n<p>" + Text.THISPANGRAM + "\n";
 
         buildComment += "<p>" + LinkTag.nextLink() + "\n";
 
--- a/langtools/test/tools/javadoc/sampleapi/lib/sampleapi/generator/PackageGenerator.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javadoc/sampleapi/lib/sampleapi/generator/PackageGenerator.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, 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
@@ -125,7 +125,7 @@
                 processTopLevel((Element)node);
             }
         } catch (ParserConfigurationException | SAXException | IOException e) {
-            throw new Fault("Error parsing dataset " + dsName);
+            throw new Fault("Error parsing dataset " + dsName, e);
         }
 
         fx = false;
--- a/langtools/test/tools/javap/4111861/A.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/javap/4111861/A.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,3 +1,26 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
 class A {
     public static final int i = 42;
     public static final boolean b = true;
--- a/langtools/test/tools/lib/toolbox/JavacTask.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/lib/toolbox/JavacTask.java	Thu Apr 28 23:08:16 2016 -0700
@@ -103,6 +103,16 @@
     }
 
     /**
+     * Sets the classpath.
+     * @param classpath the classpath
+     * @return this task object
+     */
+    public JavacTask classpath(List<Path> classpath) {
+        this.classpath = classpath;
+        return this;
+    }
+
+    /**
      * Sets the sourcepath.
      * @param sourcepath the sourcepath
      * @return this task object
@@ -126,6 +136,16 @@
     }
 
     /**
+     * Sets the sourcepath.
+     * @param sourcepath the sourcepath
+     * @return this task object
+     */
+    public JavacTask sourcepath(List<Path> sourcepath) {
+        this.sourcepath = sourcepath;
+        return this;
+    }
+
+    /**
      * Sets the output directory.
      * @param outdir the output directory
      * @return this task object
@@ -188,6 +208,18 @@
     }
 
     /**
+     * Sets the files to be compiled or analyzed.
+     * @param files the files
+     * @return this task object
+     */
+    public JavacTask files(List<Path> files) {
+        this.files = files.stream()
+                .map(Path::toString)
+                .collect(Collectors.toList());
+        return this;
+    }
+
+    /**
      * Sets the sources to be compiled or analyzed.
      * Each source string is converted into an in-memory object that
      * can be passed directly to the compiler.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/lib/toolbox/ModuleBuilder.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2015, 2016, 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 toolbox;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class ModuleBuilder {
+
+    private final ToolBox tb;
+    private final String name;
+    private String requires = "";
+    private String exports = "";
+    private String uses = "";
+    private String provides = "";
+    private String modulePath = "";
+    private List<String> content = new ArrayList<>();
+
+    public ModuleBuilder(ToolBox tb, String name) {
+        this.tb = tb;
+        this.name = name;
+    }
+
+    public ModuleBuilder requiresPublic(String requires, Path... modulePath) {
+        return requires("public " + requires, modulePath);
+    }
+
+    public ModuleBuilder requires(String requires, Path... modulePath) {
+        this.requires += "    requires " + requires + ";\n";
+        this.modulePath += Arrays.stream(modulePath)
+                .map(Path::toString)
+                .collect(Collectors.joining(File.pathSeparator));
+        return this;
+    }
+
+    public ModuleBuilder exportsTo(String pkg, String module) {
+        return exports(pkg + " to " + module);
+    }
+
+    public ModuleBuilder exports(String pkg) {
+        this.exports += "    exports " + pkg + ";\n";
+        return this;
+    }
+
+    public ModuleBuilder uses(String uses) {
+        this.uses += "    uses " + uses + ";\n";
+        return this;
+    }
+
+    public ModuleBuilder provides(String service, String implementation) {
+        this.provides += "    provides " + service + " with " + implementation + ";\n";
+        return this;
+    }
+
+    public ModuleBuilder classes(String... content) {
+        this.content.addAll(Arrays.asList(content));
+        return this;
+    }
+
+    public Path write(Path where) throws IOException {
+        Files.createDirectories(where);
+        List<String> sources = new ArrayList<>();
+        sources.add("module " + name + "{"
+                + requires
+                + exports
+                + uses
+                + provides
+                + "}");
+        sources.addAll(content);
+        Path moduleSrc = where.resolve(name + "/src");
+        tb.writeJavaFiles(moduleSrc, sources.toArray(new String[]{}));
+        return moduleSrc;
+    }
+
+    public void build(Path where) throws IOException {
+        Path moduleSrc = write(where);
+        new JavacTask(tb)
+                .outdir(where.resolve(name))
+                .options("-mp", modulePath)
+                .files(tb.findJavaFiles(moduleSrc))
+                .run()
+                .writeAll();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/lib/toolbox/TestRunner.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2016, 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 toolbox;
+
+import java.io.PrintStream;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.function.Function;
+
+/**
+ * Utility class to manage and execute sub-tests within a test.
+ *
+ * This class does the following:
+ * <ul>
+ * <li>  invokes those test methods annotated with @Test
+ * <li>  keeps track of successful and failed tests
+ * <li>  throws an Exception if any test fails.
+ * <li>  provides a test summary at the end of the run.
+ * </ul>
+
+ * Tests must extend this class, annotate the test methods
+ * with @Test and call one of the runTests method.
+ */
+public abstract class TestRunner {
+   /** Marker annotation for test cases. */
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface Test { }
+
+    int testCount = 0;
+    int errorCount = 0;
+
+    public String testName = null;
+
+    protected PrintStream out;
+
+    /**
+     * Constructs the Object.
+     * @param out the PrintStream to print output to.
+     */
+    public TestRunner(PrintStream out) {
+        this.out = out;
+    }
+
+    /**
+     * Invoke all methods annotated with @Test.
+     * @throws java.lang.Exception if any errors occur
+     */
+    protected void runTests() throws Exception {
+        runTests(f -> new Object[0]);
+    }
+
+    /**
+     * Invoke all methods annotated with @Test.
+     * @param f a lambda expression to specify arguments for the test method
+     * @throws java.lang.Exception if any errors occur
+     */
+    protected void runTests(Function<Method, Object[]> f) throws Exception {
+        for (Method m : getClass().getDeclaredMethods()) {
+            Annotation a = m.getAnnotation(Test.class);
+            if (a != null) {
+                testName = m.getName();
+                try {
+                    testCount++;
+                    out.println("test: " + testName);
+                    m.invoke(this, f.apply(m));
+                } catch (InvocationTargetException e) {
+                    errorCount++;
+                    Throwable cause = e.getCause();
+                    out.println("Exception: " + e.getCause());
+                    cause.printStackTrace(out);
+                }
+                out.println();
+            }
+        }
+
+        if (testCount == 0) {
+            throw new Error("no tests found");
+        }
+
+        StringBuilder summary = new StringBuilder();
+        if (testCount != 1) {
+            summary.append(testCount).append(" tests");
+        }
+        if (errorCount > 0) {
+            if (summary.length() > 0) {
+                summary.append(", ");
+            }
+            summary.append(errorCount).append(" errors");
+        }
+        out.println(summary);
+        if (errorCount > 0) {
+            throw new Exception(errorCount + " errors found");
+        }
+    }
+}
--- a/langtools/test/tools/lib/toolbox/ToolBox.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/lib/toolbox/ToolBox.java	Thu Apr 28 23:08:16 2016 -0700
@@ -41,6 +41,7 @@
 import java.nio.file.SimpleFileVisitor;
 import java.nio.file.StandardCopyOption;
 import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
@@ -49,6 +50,7 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.TreeSet;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
@@ -315,7 +317,7 @@
      * Reads the lines of a file.
      * The file is read using the default character encoding.
      * @param path the file to be read
-     * @return the lines of the file.
+     * @return the lines of the file
      * @throws IOException if an error occurred while reading the file
      */
     public List<String> readAllLines(String path) throws IOException {
@@ -326,7 +328,7 @@
      * Reads the lines of a file.
      * The file is read using the default character encoding.
      * @param path the file to be read
-     * @return the lines of the file.
+     * @return the lines of the file
      * @throws IOException if an error occurred while reading the file
      */
     public List<String> readAllLines(Path path) throws IOException {
@@ -348,7 +350,7 @@
      * Reads the lines of a file using the given encoding.
      * @param path the file to be read
      * @param encoding the encoding to be used to read the file
-     * @return the lines of the file.
+     * @return the lines of the file
      * @throws IOException if an error occurred while reading the file
      */
     public List<String> readAllLines(Path path, String encoding) throws IOException {
@@ -360,6 +362,30 @@
     }
 
     /**
+     * Find .java files in one or more directories.
+     * <p>Similar to the shell "find" command: {@code find paths -name \*.java}.
+     * @param paths the directories in which to search for .java files
+     * @return the .java files found
+     * @throws IOException if an error occurred while searching for files
+     */
+    public Path[] findJavaFiles(Path... paths) throws IOException {
+        Set<Path> files = new TreeSet<>();  // use TreeSet to force a consistent order
+        for (Path p : paths) {
+            Files.walkFileTree(p, new SimpleFileVisitor<Path>() {
+                @Override
+                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+                        throws IOException {
+                    if (file.getFileName().toString().endsWith(".java")) {
+                        files.add(file);
+                    }
+                    return FileVisitResult.CONTINUE;
+                }
+            });
+        }
+        return files.toArray(new Path[files.size()]);
+    }
+
+    /**
      * Writes a file containing the given content.
      * Any necessary directories for the file will be created.
      * @param path where to write the file
--- a/langtools/test/tools/sjavac/HiddenFiles.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/sjavac/HiddenFiles.java	Thu Apr 28 23:08:16 2016 -0700
@@ -36,6 +36,7 @@
  * @run main Wrapper HiddenFiles
  */
 
+import com.sun.tools.javac.main.Main.Result;
 import com.sun.tools.javac.util.Assert;
 import com.sun.tools.sjavac.server.Sjavac;
 
@@ -62,6 +63,6 @@
                          "-d", BIN.toString(),
                          "--state-dir=" + STATE_DIR);
 
-        Assert.check(rc == Sjavac.RC_FATAL, "Compilation succeeded unexpectedly.");
+        Assert.check(rc == Result.ERROR.exitCode, "Compilation succeeded unexpectedly.");
     }
 }
--- a/langtools/test/tools/sjavac/IdleShutdown.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/sjavac/IdleShutdown.java	Thu Apr 28 23:08:16 2016 -0700
@@ -29,9 +29,9 @@
  * @build Wrapper
  * @run main Wrapper IdleShutdown
  */
-import java.io.Writer;
 import java.util.concurrent.atomic.AtomicLong;
 
+import com.sun.tools.javac.main.Main.Result;
 import com.sun.tools.sjavac.server.IdleResetSjavac;
 import com.sun.tools.sjavac.server.Sjavac;
 import com.sun.tools.sjavac.server.Terminable;
@@ -103,13 +103,13 @@
         public void shutdown() {
         }
         @Override
-        public int compile(String[] args) {
+        public Result compile(String[] args) {
             // Attempt to trigger idle timeout during a call by sleeping
             try {
                 Thread.sleep(TIMEOUT_MS + 1000);
             } catch (InterruptedException e) {
             }
-            return 0;
+            return Result.OK;
         }
     }
 }
--- a/langtools/test/tools/sjavac/IncludeExcludePatterns.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/sjavac/IncludeExcludePatterns.java	Thu Apr 28 23:08:16 2016 -0700
@@ -33,6 +33,7 @@
  * @run main Wrapper IncludeExcludePatterns
  */
 
+import com.sun.tools.javac.main.Main.Result;
 import com.sun.tools.javac.util.Assert;
 import com.sun.tools.sjavac.server.Sjavac;
 
@@ -131,7 +132,7 @@
         int rc = compile((Object[]) args.split(" "));
 
         // Compilation should always pass in these tests
-        Assert.check(rc == Sjavac.RC_OK, "Compilation failed unexpectedly.");
+        Assert.check(rc == Result.OK.exitCode, "Compilation failed unexpectedly.");
 
         // The resulting .class files should correspond to the visible source files
         Set<Path> result = allFilesInDir(BIN);
--- a/langtools/test/tools/sjavac/PooledExecution.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/langtools/test/tools/sjavac/PooledExecution.java	Thu Apr 28 23:08:16 2016 -0700
@@ -30,12 +30,10 @@
  * @build Wrapper
  * @run main Wrapper PooledExecution
  */
-import java.io.PrintWriter;
-import java.io.Writer;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import com.sun.tools.sjavac.Log;
+import com.sun.tools.javac.main.Main.Result;
 import com.sun.tools.sjavac.comp.PooledSjavac;
 import com.sun.tools.sjavac.server.Sjavac;
 
@@ -111,7 +109,7 @@
             AtomicInteger activeRequests = new AtomicInteger(0);
 
             @Override
-            public int compile(String[] args) {
+            public Result compile(String[] args) {
                 leftToStart.countDown();
                 int numActiveRequests = activeRequests.incrementAndGet();
                 System.out.printf("Left to start: %2d / Currently active: %2d%n",
@@ -125,7 +123,7 @@
                 }
                 activeRequests.decrementAndGet();
                 System.out.println("Task completed");
-                return 0;
+                return Result.OK;
             }
 
             @Override
--- a/make/CompileJavaModules.gmk	Fri Apr 29 04:44:08 2016 +0200
+++ b/make/CompileJavaModules.gmk	Thu Apr 28 23:08:16 2016 -0700
@@ -98,7 +98,8 @@
 
 ################################################################################
 
-java.desktop_ADD_JAVAC_FLAGS := -Xdoclint:all/protected,-reference '-Xdoclint/package:java.*,javax.*'
+java.desktop_ADD_JAVAC_FLAGS := -Xdoclint:all/protected,-reference \
+    '-Xdoclint/package:java.*,javax.*'
 java.desktop_COPY := .gif .png .wav .txt .xml .css .pf
 java.desktop_CLEAN := iio-plugin.properties cursors.properties
 
--- a/make/CreateJmods.gmk	Fri Apr 29 04:44:08 2016 +0200
+++ b/make/CreateJmods.gmk	Thu Apr 28 23:08:16 2016 -0700
@@ -82,7 +82,7 @@
             --os-version $(REQUIRED_OS_VERSION) \
 	    --modulepath $(IMAGES_OUTPUTDIR)/jmods\
             --hash-dependencies '.*' \
-            --exclude '**_the.*' \
+            --exclude '**{_the.*,*.diz,*.debuginfo,*.dSYM/**,*.pdb,*.map}' \
 	    $(JMOD_FLAGS) $(SUPPORT_OUTPUTDIR)/jmods/$(notdir $@)
 	$(MV) $(SUPPORT_OUTPUTDIR)/jmods/$(notdir $@) $@
 
--- a/make/GensrcModuleInfo.gmk	Fri Apr 29 04:44:08 2016 +0200
+++ b/make/GensrcModuleInfo.gmk	Thu Apr 28 23:08:16 2016 -0700
@@ -78,21 +78,30 @@
   # let space represent new lines in the variable as $(shell) normalizes all
   # whitespace.
   $(foreach f, $(MOD_FILES), \
-    $(eval MOD_FILE_CONTENTS += $(shell $(GREP) -v ".\*" $f | $(TR) ' ' '/')))
+    $(eval MOD_FILE_CONTENTS += $(shell $(GREP) -v -e ".\*" -e "//" $f | $(TR) ' ' '/')))
+
+  # Separate the modifications into qualified exports and the rest
+  MODS_QUALIFIED_EXPORTS := $(call containing, /to/, $(MOD_FILE_CONTENTS))
+  MODS_REST := $(filter-out $(MODS_QUALIFIED_EXPORTS), $(MOD_FILE_CONTENTS))
 
   # Filter the contents for modules that are actually being built
   MODULES_FILTER := $(addprefix %/, $(addsuffix ;, $(ALL_MODULES)))
-  MODULES_FILTER += provides%
-  MODIFICATIONS := $(filter $(MODULES_FILTER), $(MOD_FILE_CONTENTS))
+  MODIFICATIONS := $(filter $(MODULES_FILTER), $(MODS_QUALIFIED_EXPORTS)) \
+      $(MODS_REST)
 
   # Convert the modification lines into arguments for the modification tool.
   # Filter out modifications for non existing to-modules.
   $(foreach line, $(MODIFICATIONS), \
     $(eval split_line := $(subst /,$(SPACE),$(line))) \
     $(eval command := $(word 1, $(split_line))) \
-    $(eval package := $(word 2, $(split_line))) \
+    $(eval package := $(patsubst %;,%,$(word 2, $(split_line)))) \
     $(eval to_module := $(patsubst %;,%,$(word 4, $(split_line)))) \
-    $(eval ARGS += -$(command) $(package)/$(to_module)))
+    $(if $(to_module), \
+      $(eval ARGS += -$(command) $(package)/$(to_module)) \
+    , \
+      $(eval ARGS += -$(command) $(package)) \
+    ) \
+  )
 
   ifneq ($(ARGS), )
     $(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/module-info.java: \
--- a/make/Images.gmk	Fri Apr 29 04:44:08 2016 +0200
+++ b/make/Images.gmk	Thu Apr 28 23:08:16 2016 -0700
@@ -423,6 +423,55 @@
 endif
 
 ################################################################################
+# Debug symbols
+# Since debug symbols are not included in the jmod files, they need to be copied
+# in manually after generating the images.
+
+ALL_JDK_MODULES := $(JDK_MODULES)
+ALL_JRE_MODULES := $(sort $(JRE_MODULES), $(foreach m, $(JRE_MODULES), \
+    $(call FindTransitiveDepsForModule, $m)))
+
+ifeq ($(OPENJDK_TARGET_OS), windows)
+  LIBS_TARGET_SUBDIR := bin
+else
+  LIBS_TARGET_SUBDIR := lib
+endif
+
+DEBUGINFO_SUFFIXES := .diz .debuginfo .pdb .map
+
+# Param 1 - dir to find debuginfo files in
+FindDebuginfoFiles = \
+    $(wildcard $(addprefix $1/*, $(DEBUGINFO_SUFFIXES)) \
+        $(addprefix $1/*/*, $(DEBUGINFO_SUFFIXES)) \
+        $(addprefix $1/*/*/*, $(DEBUGINFO_SUFFIXES)))
+
+# On Macosx, if debug symbols have not been zipped, find all files inside *.dSYM
+# dirs.
+ifeq ($(OPENJDK_TARGET_OS)-$(ZIP_EXTERNAL_DEBUG_SYMBOLS), macosx-false)
+  $(eval $(call FillCacheFind, \
+      $(SUPPORT_OUTPUTDIR)/modules_cmds $(SUPPORT_OUTPUTDIR)/modules_libs/))
+  FindDebuginfoFiles = \
+      $(if $(wildcard $1), $(call containing, .dSYM/, $(call CacheFind, $1)))
+endif
+
+# Param 1 - either JDK or JRE
+SetupCopyDebuginfo = \
+    $(foreach m, $(ALL_$1_MODULES), \
+      $(eval $(call SetupCopyFiles, COPY_$1_LIBS_DEBUGINFO_$m, \
+          SRC := $(SUPPORT_OUTPUTDIR)/modules_libs/$m, \
+          DEST := $($1_IMAGE_DIR)/$(LIBS_TARGET_SUBDIR), \
+          FILES := $(call FindDebuginfoFiles, \
+              $(SUPPORT_OUTPUTDIR)/modules_libs/$m), \
+      )) \
+      $(eval $1_TARGETS += $$(COPY_$1_LIBS_DEBUGINFO_$m)) \
+    )
+
+# No space before argument to avoid having to put $(strip ) everywhere in
+# implementation above.
+$(call SetupCopyDebuginfo,JDK)
+$(call SetupCopyDebuginfo,JRE)
+
+################################################################################
 
 # Include custom post hook here to make it possible to augment the target lists
 # before actual target prerequisites are declared.
--- a/make/Init.gmk	Fri Apr 29 04:44:08 2016 +0200
+++ b/make/Init.gmk	Thu Apr 28 23:08:16 2016 -0700
@@ -268,8 +268,13 @@
   ##############################################################################
 
   MAIN_TARGETS := $(SEQUENTIAL_TARGETS) $(PARALLEL_TARGETS) $(COMPARE_BUILD_MAKE)
+  # If building the default target, add what they are to the description.
+  DESCRIPTION_TARGETS := $(strip $(MAIN_TARGETS))
+  ifeq ($(DESCRIPTION_TARGETS), default)
+    DESCRIPTION_TARGETS += ($(DEFAULT_MAKE_TARGET))
+  endif
   TARGET_DESCRIPTION := target$(if $(word 2, $(MAIN_TARGETS)),s) \
-      '$(strip $(MAIN_TARGETS))' in configuration '$(CONF_NAME)'
+      '$(strip $(DESCRIPTION_TARGETS))' in configuration '$(CONF_NAME)'
 
   # MAKEOVERRIDES is automatically set and propagated by Make to sub-Make calls.
   # We need to clear it of the init-specific variables. The user-specified
--- a/make/InitSupport.gmk	Fri Apr 29 04:44:08 2016 +0200
+++ b/make/InitSupport.gmk	Thu Apr 28 23:08:16 2016 -0700
@@ -331,7 +331,7 @@
   BUILD_LOG := $(OUTPUT_ROOT)/build.log
   BUILD_TRACE_LOG := $(OUTPUT_ROOT)/build-trace-time.log
 
-  BUILD_LOG_PIPE := > >($(TEE) -a $(BUILD_LOG)) 2> >($(TEE) -a $(BUILD_LOG) >&2)
+  BUILD_LOG_PIPE := > >($(TEE) -a $(BUILD_LOG)) 2> >($(TEE) -a $(BUILD_LOG) >&2) && wait
 
   # Sanity check the spec file, so it matches this source code
   define CheckSpecSanity
--- a/make/Javadoc.gmk	Fri Apr 29 04:44:08 2016 +0200
+++ b/make/Javadoc.gmk	Thu Apr 28 23:08:16 2016 -0700
@@ -1580,7 +1580,7 @@
 JDKNET_PACKAGES_FILE = $(DOCSTMPDIR)/jdknet.packages
 
 # The modules required to be documented
-JDKNET_MODULES = java.base
+JDKNET_MODULES = jdk.net
 
 jdknetdocs: $(JDKNET_INDEX_HTML)
 
--- a/make/Jprt.gmk	Fri Apr 29 04:44:08 2016 +0200
+++ b/make/Jprt.gmk	Thu Apr 28 23:08:16 2016 -0700
@@ -108,7 +108,9 @@
 SRC_JRE_MACOSX_BUNDLE_DIR := $(JRE_MACOSX_BUNDLE_DIR)
 
 # Bundle up the images
-bundles: all
+JPRT_TARGET ?= default
+ifeq ($(JPRT_TARGET), default)
+  bundles: $(JPRT_TARGET)
 	@$(call TargetEnter)
 	$(MKDIR) -p $(BUILD_OUTPUT)/bundles
 	$(CD) $(SRC_JDK_IMAGE_DIR) && $(ZIP) -y -q -r \
@@ -128,9 +130,24 @@
 	      $(BUILD_OUTPUT)/bundles/$(SYMBOLS_IMAGE_SUBDIR).zip . ; \
 	fi
 	@$(call TargetExit)
+else
+  # Just fake the bundles
+  bundles: $(JPRT_TARGET)
+	@$(call TargetEnter)
+	$(MKDIR) -p $(BUILD_OUTPUT)/bundles
+	$(CD) $(TOPDIR) &&  $(ZIP) -y -q -r \
+	    $(BUILD_OUTPUT)/bundles/$(JDK_IMAGE_SUBDIR).zip README
+	$(CD) $(TOPDIR) &&  $(ZIP) -y -q -r \
+	    $(BUILD_OUTPUT)/bundles/$(JRE_IMAGE_SUBDIR).zip README
+	$(CD) $(TOPDIR) &&  $(ZIP) -y -q -r \
+	    $(BUILD_OUTPUT)/bundles/$(TEST_IMAGE_SUBDIR).zip README
+	$(CD) $(TOPDIR) &&  $(ZIP) -y -q -r \
+	    $(BUILD_OUTPUT)/bundles/modules.zip README
+	@$(call TargetExit)
+endif
 
 # Copy images to one unified location regardless of platform etc.
-final-images: all
+final-images: $(JPRT_TARGET)
 	@$(call TargetEnter)
 	$(RM) -r $(BUILD_OUTPUT)/final-images
 	$(MKDIR) -p $(BUILD_OUTPUT)/final-images/$(JDK_IMAGE_SUBDIR)
--- a/make/Main.gmk	Fri Apr 29 04:44:08 2016 +0200
+++ b/make/Main.gmk	Thu Apr 28 23:08:16 2016 -0700
@@ -229,10 +229,17 @@
 
 ifeq ($(BUILD_HOTSPOT),true)
   hotspot:
-	+($(CD) $(SRC_ROOT)/make && $(MAKE) $(MAKE_ARGS) -f HotspotWrapper.gmk)
+        ifeq ($(USE_NEW_HOTSPOT_BUILD), true)
+	  +($(CD) $(HOTSPOT_TOPDIR)/makefiles && $(MAKE) $(MAKE_ARGS) -f BuildHotspot.gmk)
+        else
+	  +($(CD) $(SRC_ROOT)/make && $(MAKE) $(MAKE_ARGS) -f HotspotWrapper.gmk)
+        endif
 endif
 
-ALL_TARGETS += hotspot
+hotspot-ide-project:
+	+($(CD) $(HOTSPOT_TOPDIR)/makefiles && $(MAKE) $(MAKE_ARGS) -f ide/CreateVSProject.gmk)
+
+ALL_TARGETS += hotspot hotspot-ide-project
 
 ################################################################################
 # Build demos and samples targets
@@ -333,10 +340,10 @@
 docs-jvmtidoc:
 	+($(CD) $(SRC_ROOT)/make && $(MAKE) $(MAKE_ARGS) -f Javadoc.gmk jvmtidocs)
 
-zip-docs: docs-javadoc docs-jvmtidoc
+zip-docs:
 	+($(CD) $(SRC_ROOT)/make && $(MAKE) $(MAKE_ARGS) -f Javadoc.gmk zip-docs)
 
-ALL_TARGETS += docs-javadoc docs-jvmtidoc
+ALL_TARGETS += docs-javadoc docs-jvmtidoc zip-docs
 
 ################################################################################
 # Cross compilation support
@@ -484,6 +491,8 @@
 
   $(JAVA_TARGETS): interim-langtools
 
+  hotspot-ide-project: hotspot exploded-image
+
   import-hotspot: hotspot
 
   generate-exported-symbols: java.base-libs jdk.jdwp.agent-libs
@@ -593,6 +602,8 @@
 
   docs-jvmtidoc: hotspot
 
+  zip-docs: docs-javadoc docs-jvmtidoc
+
   test: jimages test-image
 
   create-buildjdk-copy: jdk.jlink-java java.base-gendata
@@ -694,7 +705,7 @@
 endif
 
 # This target builds the documentation image
-docs-image: zip-docs
+docs-image: docs-javadoc docs-jvmtidoc
 
 # This target builds the test image
 test-image: prepare-test-image test-image-hotspot-jtreg-native \
@@ -718,7 +729,7 @@
 docs: docs-image
 all: all-images
 
-ALL_TARGETS += default jdk images docs all zip-docs
+ALL_TARGETS += default jdk images docs all
 
 ################################################################################
 ################################################################################
@@ -820,6 +831,10 @@
 
 ################################################################################
 
+
+# workaround issue when building open targets when closed jib-profiles.js is used
+installer: product-images test-image
+
 .PHONY: $(ALL_TARGETS)
 
 FRC: # Force target
--- a/make/common/MakeBase.gmk	Fri Apr 29 04:44:08 2016 +0200
+++ b/make/common/MakeBase.gmk	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, 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
@@ -706,10 +706,10 @@
 ExecuteWithLog = \
   $(call LogCmdlines, Exececuting: [$(strip $2)]) \
   $(call WriteFile, $2, $(strip $1).cmdline) \
-  ( $(strip $2) > >($(TEE) $(strip $1).log) 2> >($(TEE) $(strip $1).log >&2) || \
+  ( ( $(strip $2) > >($(TEE) $(strip $1).log) 2> >($(TEE) $(strip $1).log >&2) || \
       ( exitcode=$(DOLLAR)? && \
       $(CP) $(strip $1).log $(MAKESUPPORT_OUTPUTDIR)/failure-logs/$(subst /,_,$(patsubst $(BUILD_OUTPUT)/%,%,$(strip $1))).log && \
-      exit $(DOLLAR)exitcode ) )
+      exit $(DOLLAR)exitcode ) ) && wait )
 
 ################################################################################
 # Find lib dir for module
@@ -732,6 +732,16 @@
   "$(subst $(SPACE),$(PATH_SEP),$(strip $(subst $(DQUOTE),,$1)))"
 
 ################################################################################
+# Check if a specified hotspot variant is being built, or at least one of a
+# list of variants. Will return 'true' or 'false'.
+# $1 - the variant to test for
+check-jvm-variant = \
+  $(strip \
+    $(if $(filter-out $(VALID_JVM_VARIANTS), $1), \
+      $(error Internal error: Invalid variant tested: $1)) \
+    $(if $(filter $1, $(JVM_VARIANTS)), true, false))
+
+################################################################################
 
 # Hook to include the corresponding custom file, if present.
 $(eval $(call IncludeCustomExtension, , common/MakeBase.gmk))
--- a/make/common/Modules.gmk	Fri Apr 29 04:44:08 2016 +0200
+++ b/make/common/Modules.gmk	Thu Apr 28 23:08:16 2016 -0700
@@ -63,6 +63,7 @@
     java.xml.crypto \
     jdk.httpserver \
     jdk.management \
+    jdk.net \
     jdk.sctp \
     jdk.security.auth \
     jdk.security.jgss \
@@ -185,7 +186,8 @@
     $(call GetModuleNameFromModuleInfo, $(MODULE_INFOS))))
 
 FindImportedModules = \
-    $(if $(IMPORT_MODULES_CLASSES), $(notdir $(wildcard $(IMPORT_MODULES_CLASSES)/*)))
+    $(filter-out $(MODULES_FILTER), \
+    $(if $(IMPORT_MODULES_CLASSES), $(notdir $(wildcard $(IMPORT_MODULES_CLASSES)/*))))
 
 # Find all source dirs for a particular module
 # $1 - Module to find source dirs for
--- a/make/common/NativeCompilation.gmk	Fri Apr 29 04:44:08 2016 +0200
+++ b/make/common/NativeCompilation.gmk	Thu Apr 28 23:08:16 2016 -0700
@@ -197,14 +197,51 @@
     $1_$2_THIS_FILE = -DTHIS_FILE='"$$(<F)"'
   endif
 
+  ifeq ($$($1_$(notdir $2)_OPTIMIZATION), )
+    $1_$(notdir $2)_OPT_CFLAGS := $$($1_OPT_CFLAGS)
+    $1_$(notdir $2)_OPT_CXXFLAGS := $$($1_OPT_CXXFLAGS)
+  else
+    ifeq (NONE, $$($1_$(notdir $2)_OPTIMIZATION))
+      $1_$(notdir $2)_OPT_CFLAGS := $(C_O_FLAG_NONE)
+      $1_$(notdir $2)_OPT_CXXFLAGS := $(CXX_O_FLAG_NONE)
+    else ifeq (LOW, $$($1_$(notdir $2)_OPTIMIZATION))
+      $1_$(notdir $2)_OPT_CFLAGS := $(C_O_FLAG_NORM)
+      $1_$(notdir $2)_OPT_CXXFLAGS := $(CXX_O_FLAG_NORM)
+    else ifeq (HIGH, $$($1_$(notdir $2)_OPTIMIZATION))
+      $1_$(notdir $2)_OPT_CFLAGS := $(C_O_FLAG_HI)
+      $1_$(notdir $2)_OPT_CXXFLAGS := $(CXX_O_FLAG_HI)
+    else ifeq (HIGHEST, $$($1_$(notdir $2)_OPTIMIZATION))
+      $1_$(notdir $2)_OPT_CFLAGS := $(C_O_FLAG_HIGHEST)
+      $1_$(notdir $2)_OPT_CXXFLAGS := $(CXX_O_FLAG_HIGHEST)
+    else ifeq (HIGHEST_JVM, $$($1_$(notdir $2)_OPTIMIZATION))
+      $1_$(notdir $2)_OPT_CFLAGS := $(C_O_FLAG_HIGHEST_JVM)
+      $1_$(notdir $2)_OPT_CXXFLAGS := $(CXX_O_FLAG_HIGHEST_JVM)
+    else ifeq (SIZE, $$($1_$(notdir $2)_OPTIMIZATION))
+      $1_$(notdir $2)_OPT_CFLAGS := $(C_O_FLAG_SIZE)
+      $1_$(notdir $2)_OPT_CXXFLAGS := $(CXX_O_FLAG_SIZE)
+    else
+      $$(error Unknown value for OPTIMIZATION: $$($1_$(notdir $2)_OPTIMIZATION))
+    endif
+  endif
+
+  ifneq ($$($1_PRECOMPILED_HEADER), )
+    ifeq ($$(filter $$(notdir $2), $$($1_PRECOMPILED_HEADER_EXCLUDE)), )
+      $1_$2_USE_PCH_FLAGS := $$($1_USE_PCH_FLAGS)
+    endif
+  endif
+
   ifneq (,$$(filter %.c,$2))
     # Compile as a C file
-    $1_$2_FLAGS=$(CFLAGS_CCACHE) $4 $$($1_$(notdir $2)_CFLAGS) $$($1_$2_THIS_FILE) -c
+    $1_$2_FLAGS=$(CFLAGS_CCACHE) $$($1_$2_USE_PCH_FLAGS) $4 \
+        $$($1_$(notdir $2)_OPT_CFLAGS) \
+        $$($1_$(notdir $2)_CFLAGS) $$($1_$2_THIS_FILE) -c
     $1_$2_COMP=$5
     $1_$2_DEP_FLAG:=$(C_FLAG_DEPS)
   else ifneq (,$$(filter %.m,$2))
     # Compile as an Objective-C file
-    $1_$2_FLAGS=-x objective-c $(CFLAGS_CCACHE) $4 $$($1_$(notdir $2)_CFLAGS) $$($1_$2_THIS_FILE) -c
+    $1_$2_FLAGS=-x objective-c $(CFLAGS_CCACHE) $$($1_$2_USE_PCH_FLAGS) $4 \
+        $$($1_$(notdir $2)_OPT_CFLAGS) \
+        $$($1_$(notdir $2)_CFLAGS) $$($1_$2_THIS_FILE) -c
     $1_$2_COMP=$5
     $1_$2_DEP_FLAG:=$(C_FLAG_DEPS)
   else ifneq (,$$(filter %.s %.S,$2))
@@ -214,7 +251,9 @@
     $1_$2_DEP_FLAG:=
   else ifneq (,$$(filter %.cpp,$2)$$(filter %.cc,$2)$$(filter %.mm,$2))
     # Compile as a C++ or Objective-C++ file
-    $1_$2_FLAGS=$(CFLAGS_CCACHE) $6 $$($1_$(notdir $2)_CXXFLAGS) $$($1_$2_THIS_FILE) -c
+    $1_$2_FLAGS=$(CFLAGS_CCACHE) $$($1_$2_USE_PCH_FLAGS) $6 \
+        $$($1_$(notdir $2)_OPT_CXXFLAGS) \
+        $$($1_$(notdir $2)_CXXFLAGS) $$($1_$2_THIS_FILE) -c
     $1_$2_COMP=$7
     $1_$2_DEP_FLAG:=$(CXX_FLAG_DEPS)
   else
@@ -245,8 +284,10 @@
       endif
     endif
 
-    ifneq ($$($1_$(notdir $2)_CFLAGS)$$($1_$(notdir $2)_CXXFLAGS), )
-      $1_$2_VARDEPS := $$($1_$(notdir $2)_CFLAGS) $$($1_$(notdir $2)_CXXFLAGS)
+    ifneq ($$(strip $$($1_$(notdir $2)_CFLAGS) $$($1_$(notdir $2)_CXXFLAGS) \
+        $$($1_$(notdir $2)_OPTIMIZATION)), )
+      $1_$2_VARDEPS := $$($1_$(notdir $2)_CFLAGS) $$($1_$(notdir $2)_CXXFLAGS) \
+          $$($1_$(notdir $2)_OPT_CFLAGS) $$($1_$(notdir $2)_OPT_CXXFLAGS)
       $1_$2_VARDEPS_FILE := $$(call DependOnVariable, $1_$2_VARDEPS, \
           $$(patsubst %$(OBJ_SUFFIX),%.vardeps,$$($1_$2_OBJ)))
     endif
@@ -323,7 +364,7 @@
 #       mapfile for the output symbols file
 #   CC the compiler to use, default is $(CC)
 #   LD the linker to use, default is $(LD)
-#   OPTIMIZATION sets optimization level to NONE, LOW, HIGH, HIGHEST
+#   OPTIMIZATION sets optimization level to NONE, LOW, HIGH, HIGHEST, HIGHEST_JVM, SIZE
 #   DISABLED_WARNINGS_<toolchain> Disable the given warnings for the specified toolchain
 #   DISABLED_WARNINGS_C_<toolchain> Disable the given warnings for the specified toolchain
 #       when compiling C code
@@ -331,7 +372,11 @@
 #       toolchain when compiling C++ code
 #   STRIP_SYMBOLS Set to true to strip the final binary if the toolchain allows for it
 #   DEBUG_SYMBOLS Set to false to disable generation of debug symbols
+#   CFLAGS_DEBUG_SYMBOLS Overrides the default cflags for enabling debug symbols
+#   CXXFLAGS_DEBUG_SYMBOLS Overrides the default cxxflags for enabling debug symbols
 #   STRIPFLAGS Optionally change the flags given to the strip command
+#   PRECOMPILED_HEADER Header file to use as precompiled header
+#   PRECOMPILED_HEADER_EXCLUDE List of source files that should not use PCH
 SetupNativeCompilation = $(NamedParamsMacroTemplate)
 define SetupNativeCompilationBody
 
@@ -556,8 +601,10 @@
   endif
 
   ifeq ($(COMPILE_WITH_DEBUG_SYMBOLS), true)
-    $1_EXTRA_CFLAGS += $(CFLAGS_DEBUG_SYMBOLS)
-    $1_EXTRA_CXXFLAGS += $(CXXFLAGS_DEBUG_SYMBOLS)
+    $$(call SetIfEmpty, $1_CFLAGS_DEBUG_SYMBOLS, $(CFLAGS_DEBUG_SYMBOLS))
+    $$(call SetIfEmpty, $1_CXXFLAGS_DEBUG_SYMBOLS, $(CXXFLAGS_DEBUG_SYMBOLS))
+    $1_EXTRA_CFLAGS += $$($1_CFLAGS_DEBUG_SYMBOLS)
+    $1_EXTRA_CXXFLAGS += $$($1_CXXFLAGS_DEBUG_SYMBOLS)
   endif
 
   ifneq (,$$($1_REORDER))
@@ -597,17 +644,23 @@
   endif
 
   ifeq (NONE, $$($1_OPTIMIZATION))
-    $1_EXTRA_CFLAGS += $(C_O_FLAG_NONE)
-    $1_EXTRA_CXXFLAGS += $(CXX_O_FLAG_NONE)
+    $1_OPT_CFLAGS := $(C_O_FLAG_NONE)
+    $1_OPT_CXXFLAGS := $(CXX_O_FLAG_NONE)
   else ifeq (LOW, $$($1_OPTIMIZATION))
-    $1_EXTRA_CFLAGS += $(C_O_FLAG_NORM)
-    $1_EXTRA_CXXFLAGS += $(CXX_O_FLAG_NORM)
+    $1_OPT_CFLAGS := $(C_O_FLAG_NORM)
+    $1_OPT_CXXFLAGS := $(CXX_O_FLAG_NORM)
   else ifeq (HIGH, $$($1_OPTIMIZATION))
-    $1_EXTRA_CFLAGS += $(C_O_FLAG_HI)
-    $1_EXTRA_CXXFLAGS += $(CXX_O_FLAG_HI)
+    $1_OPT_CFLAGS := $(C_O_FLAG_HI)
+    $1_OPT_CXXFLAGS := $(CXX_O_FLAG_HI)
   else ifeq (HIGHEST, $$($1_OPTIMIZATION))
-    $1_EXTRA_CFLAGS += $(C_O_FLAG_HIGHEST)
-    $1_EXTRA_CXXFLAGS += $(CXX_O_FLAG_HIGHEST)
+    $1_OPT_CFLAGS := $(C_O_FLAG_HIGHEST)
+    $1_OPT_CXXFLAGS := $(CXX_O_FLAG_HIGHEST)
+  else ifeq (HIGHEST_JVM, $$($1_OPTIMIZATION))
+    $1_OPT_CFLAGS := $(C_O_FLAG_HIGHEST_JVM)
+    $1_OPT_CXXFLAGS := $(CXX_O_FLAG_HIGHEST_JVM)
+  else ifeq (SIZE, $$($1_OPTIMIZATION))
+    $1_OPT_CFLAGS := $(C_O_FLAG_SIZE)
+    $1_OPT_CXXFLAGS := $(CXX_O_FLAG_SIZE)
   else ifneq (, $$($1_OPTIMIZATION))
     $$(error Unknown value for OPTIMIZATION: $$($1_OPTIMIZATION))
   endif
@@ -618,11 +671,65 @@
   # lines for all object files in this setup. This includes at least all the
   # variables used in the call to add_native_source below.
   $1_COMPILE_VARDEPS := $$($1_CFLAGS) $$($1_EXTRA_CFLAGS) $$($1_SYSROOT_CFLAGS) \
-      $$($1_CXXFLAGS) $$($1_EXTRA_CXXFLAGS) \
+      $$($1_CXXFLAGS) $$($1_EXTRA_CXXFLAGS) $$($1_OPT_CFLAGS) $$($1_OPT_CXXFLAGS) \
       $$($1_CC) $$($1_CXX) $$($1_AS) $$($1_ASFLAGS)
   $1_COMPILE_VARDEPS_FILE := $$(call DependOnVariable, $1_COMPILE_VARDEPS, \
       $$($1_OBJECT_DIR)/$$($1_NOSUFFIX).comp.vardeps)
 
+  ifneq ($$($1_PRECOMPILED_HEADER), )
+    ifeq ($(USE_PRECOMPILED_HEADER), 1)
+      ifeq ($(TOOLCHAIN_TYPE), microsoft)
+        $1_PCH_FILE := $$($1_OBJECT_DIR)/$1.pch
+        $1_GENERATED_PCH_SRC := $$($1_OBJECT_DIR)/$1_pch.cpp
+        $1_GENERATED_PCH_OBJ := $$($1_OBJECT_DIR)/$1_pch.obj
+
+        $$(eval $$(call add_native_source,$1,$$($1_GENERATED_PCH_SRC), \
+            $$($1_OBJECT_DIR),,, \
+            $$($1_CXXFLAGS) $$($1_EXTRA_CXXFLAGS) $$($1_SYSROOT_CFLAGS) \
+                -Fp$$($1_PCH_FILE) -Yc$$(notdir $$($1_PRECOMPILED_HEADER)), \
+            $$($1_CXX),,no_this_file))
+
+        $1_USE_PCH_FLAGS := \
+            -Fp$$($1_PCH_FILE) -Yu$$(notdir $$($1_PRECOMPILED_HEADER))
+
+        $$($1_ALL_OBJS): $$($1_GENERATED_PCH_OBJ)
+
+        # Explicitly add the pch obj file first to ease comparing to old
+        # hotspot build.
+        $1_ALL_OBJS := $$($1_GENERATED_PCH_OBJ) $$($1_ALL_OBJS)
+
+        $$($1_GENERATED_PCH_SRC):
+		$(ECHO) "#include \"$$(notdir $$($1_PRECOMPILED_HEADER))\"" > $$@
+
+      else ifneq ($(findstring $(TOOLCHAIN_TYPE), gcc clang), )
+        ifeq ($(TOOLCHAIN_TYPE), gcc)
+          $1_PCH_FILE := $$($1_OBJECT_DIR)/precompiled/$$(notdir $$($1_PRECOMPILED_HEADER)).gch
+          $1_USE_PCH_FLAGS := -I$$($1_OBJECT_DIR)/precompiled
+        else ifeq ($(TOOLCHAIN_TYPE), clang)
+          $1_PCH_FILE := $$($1_OBJECT_DIR)/precompiled/$$(notdir $$($1_PRECOMPILED_HEADER)).pch
+          $1_USE_PCH_FLAGS := -include-pch $$($1_PCH_FILE)
+        endif
+        $1_PCH_DEP := $$($1_PCH_FILE).d
+        $1_PCH_DEP_TARGETS := $$($1_PCH_FILE).d.targets
+
+        -include $$($1_PCH_DEP)
+        -include $$($1_PCH_DEP_TARGETS)
+
+        $$($1_PCH_FILE): $$($1_PRECOMPILED_HEADER) $$($1_COMPILE_VARDEPS_FILE)
+		$$(call LogInfo, Generating precompiled header)
+		$$(call MakeDir, $$(@D))
+		$$(call ExecuteWithLog, $$@, \
+		    $$($1_CC) $$($1_CFLAGS) $$($1_EXTRA_CFLAGS) $$($1_SYSROOT_CFLAGS) \
+		    $$($1_OPT_CFLAGS) \
+		    -x c++-header -c $(C_FLAG_DEPS) $$($1_PCH_DEP) $$< -o $$@)
+		$(SED) $(DEPENDENCY_TARGET_SED_PATTERN) $$($1_PCH_DEP) > $$($1_PCH_DEP_TARGETS)
+
+        $$($1_ALL_OBJS): $$($1_PCH_FILE)
+
+      endif
+    endif
+  endif
+
   # Now call add_native_source for each source file we are going to compile.
   $$(foreach p,$$($1_SRCS), \
       $$(eval $$(call add_native_source,$1,$$p,$$($1_OBJECT_DIR), \
--- a/make/jprt.properties	Fri Apr 29 04:44:08 2016 +0200
+++ b/make/jprt.properties	Thu Apr 28 23:08:16 2016 -0700
@@ -129,9 +129,15 @@
 jprt.build.flavor.optimizedOpen.target=jprt_bundle
 jprt.build.flavor.slowdebug.target=jprt_bundle
 
-# Use these configure args to define debug level
+# Use these configure args to define debug level or provide specific
+# configuration details not covered by Jib profiles.
 jprt.slowdebug.build.configure.args=
 jprt.fastdebug.build.configure.args=--disable-precompiled-headers
+# Don't disable precompiled headers on windows. It's simply too slow.
+jprt.windows_i586.fastdebug.build.configure.args=
+jprt.windows_x64.fastdebug.build.configure.args=
+jprt.windows_i586.fastdebugOpen.build.configure.args=
+jprt.windows_x64.fastdebugOpen.build.configure.args=
 jprt.product.build.configure.args=
 jprt.optimized.build.configure.args=--with-debug-level=optimized
 jprt.slowdebugOpen.build.configure.args=${jprt.slowdebug.build.configure.args}
--- a/nashorn/.hgtags	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/.hgtags	Thu Apr 28 23:08:16 2016 -0700
@@ -348,3 +348,5 @@
 c261f8440c5578b34596e6b0419a81aec431a884 jdk-9+112
 a5d1990fd32d908da8154d79116fce8013ba4d40 jdk-9+113
 ba21793a0e4816283cc0ecdab5142a4959363529 jdk-9+114
+295ac208a4443d433214d0c1f32d2ea45a3a32d2 jdk-9+115
+208388a5622dcca8227d6ad6c268f2c88087d283 jdk-9+116
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java	Thu Apr 28 23:08:16 2016 -0700
@@ -4310,7 +4310,7 @@
      * @param ident identifier for block or function where applicable
      */
     private void printSymbols(final Block block, final FunctionNode function, final String ident) {
-        if (compiler.getScriptEnvironment()._print_symbols || function.getFlag(FunctionNode.IS_PRINT_SYMBOLS)) {
+        if (compiler.getScriptEnvironment()._print_symbols || function.getDebugFlag(FunctionNode.DEBUG_PRINT_SYMBOLS)) {
             final PrintWriter out = compiler.getScriptEnvironment().getErr();
             out.println("[BLOCK in '" + ident + "']");
             if (!block.printSymbols(out)) {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CompilationPhase.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CompilationPhase.java	Thu Apr 28 23:08:16 2016 -0700
@@ -278,12 +278,12 @@
             final PrintWriter       err  = senv.getErr();
 
             //TODO separate phase for the debug printouts for abstraction and clarity
-            if (senv._print_lower_ast || fn.getFlag(FunctionNode.IS_PRINT_LOWER_AST)) {
+            if (senv._print_lower_ast || fn.getDebugFlag(FunctionNode.DEBUG_PRINT_LOWER_AST)) {
                 err.println("Lower AST for: " + quote(newFunctionNode.getName()));
                 err.println(new ASTWriter(newFunctionNode));
             }
 
-            if (senv._print_lower_parse || fn.getFlag(FunctionNode.IS_PRINT_LOWER_PARSE)) {
+            if (senv._print_lower_parse || fn.getDebugFlag(FunctionNode.DEBUG_PRINT_LOWER_PARSE)) {
                 err.println("Lower AST for: " + quote(newFunctionNode.getName()));
                 err.println(new PrintVisitor(newFunctionNode));
             }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/SplitIntoFunctions.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/SplitIntoFunctions.java	Thu Apr 28 23:08:16 2016 -0700
@@ -175,7 +175,9 @@
                 // we still use IS_SPLIT as the criteria in CompilationPhase.SERIALIZE_SPLIT_PHASE.
                 FunctionNode.IS_ANONYMOUS | FunctionNode.USES_ANCESTOR_SCOPE | FunctionNode.IS_SPLIT,
                 body,
-                null
+                null,
+                originalFn.getModule(),
+                originalFn.getDebugFlags()
         )
         .setCompileUnit(lc, splitNode.getCompileUnit());
 
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/WeighNodes.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/WeighNodes.java	Thu Apr 28 23:08:16 2016 -0700
@@ -435,7 +435,7 @@
     }
 
     @Override
-    public Node leaveBIND(final BinaryNode binaryNode) {
+    public Node leaveARROW(final BinaryNode binaryNode) {
         return binaryNodeWeight(binaryNode);
     }
 
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/AccessNode.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/AccessNode.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, 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,12 +48,13 @@
      * @param property  property
      */
     public AccessNode(final long token, final int finish, final Expression base, final String property) {
-        super(token, finish, base, false);
+        super(token, finish, base, false, false);
         this.property = property;
     }
 
-    private AccessNode(final AccessNode accessNode, final Expression base, final String property, final boolean isFunction, final Type type, final int id) {
-        super(accessNode, base, isFunction, type, id);
+    private AccessNode(final AccessNode accessNode, final Expression base, final String property, final boolean isFunction,
+                       final Type type, final int id, final boolean isSuper) {
+        super(accessNode, base, isFunction, type, id, isSuper);
         this.property = property;
     }
 
@@ -105,7 +106,7 @@
         if (this.base == base) {
             return this;
         }
-        return new AccessNode(this, base, property, isFunction(), type, programPoint);
+        return new AccessNode(this, base, property, isFunction(), type, programPoint, isSuper());
     }
 
     @Override
@@ -113,7 +114,7 @@
         if (this.type == type) {
             return this;
         }
-        return new AccessNode(this, base, property, isFunction(), type, programPoint);
+        return new AccessNode(this, base, property, isFunction(), type, programPoint, isSuper());
     }
 
     @Override
@@ -121,7 +122,7 @@
         if (this.programPoint == programPoint) {
             return this;
         }
-        return new AccessNode(this, base, property, isFunction(), type, programPoint);
+        return new AccessNode(this, base, property, isFunction(), type, programPoint, isSuper());
     }
 
     @Override
@@ -129,6 +130,14 @@
         if (isFunction()) {
             return this;
         }
-        return new AccessNode(this, base, property, true, type, programPoint);
+        return new AccessNode(this, base, property, true, type, programPoint, isSuper());
+    }
+
+    @Override
+    public AccessNode setIsSuper() {
+        if (isSuper()) {
+            return this;
+        }
+        return new AccessNode(this, base, property, isFunction(), type, programPoint, true);
     }
 }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/BaseNode.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/BaseNode.java	Thu Apr 28 23:08:16 2016 -0700
@@ -52,6 +52,9 @@
     /** Program point id */
     protected final int programPoint;
 
+    /** Super property access. */
+    private final boolean isSuper;
+
     /**
      * Constructor
      *
@@ -59,13 +62,15 @@
      * @param finish finish
      * @param base   base node
      * @param isFunction is this a function
+     * @param isSuper is this a super property access
      */
-    public BaseNode(final long token, final int finish, final Expression base, final boolean isFunction) {
+    public BaseNode(final long token, final int finish, final Expression base, final boolean isFunction, final boolean isSuper) {
         super(token, base.getStart(), finish);
         this.base           = base;
         this.isFunction     = isFunction;
         this.type = null;
         this.programPoint   = INVALID_PROGRAM_POINT;
+        this.isSuper        = isSuper;
     }
 
     /**
@@ -75,13 +80,15 @@
      * @param isFunction is this a function
      * @param callSiteType  the callsite type for this base node, either optimistic or conservative
      * @param programPoint  program point id
+     * @param isSuper is this a super property access
      */
-    protected BaseNode(final BaseNode baseNode, final Expression base, final boolean isFunction, final Type callSiteType, final int programPoint) {
+    protected BaseNode(final BaseNode baseNode, final Expression base, final boolean isFunction, final Type callSiteType, final int programPoint, final boolean isSuper) {
         super(baseNode);
         this.base           = base;
         this.isFunction     = isFunction;
         this.type = callSiteType;
         this.programPoint   = programPoint;
+        this.isSuper        = isSuper;
     }
 
     /**
@@ -136,4 +143,17 @@
      */
     public abstract BaseNode setIsFunction();
 
+    /**
+     * @return {@code true} if a SuperProperty access.
+     */
+    public boolean isSuper() {
+        return isSuper;
+    }
+
+    /**
+     * Mark this node as being a SuperProperty access.
+     *
+     * @return  a base node identical to this one in all aspects except with its super flag set.
+     */
+    public abstract BaseNode setIsSuper();
 }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Block.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Block.java	Thu Apr 28 23:08:16 2016 -0700
@@ -65,24 +65,39 @@
     private final LocalVariableConversion conversion;
 
     /** Flag indicating that this block needs scope */
-    public static final int NEEDS_SCOPE = 1 << 0;
+    public static final int NEEDS_SCOPE        = 1 << 0;
 
     /**
      * Is this block tagged as terminal based on its contents
      * (usually the last statement)
      */
-    public static final int IS_TERMINAL = 1 << 2;
+    public static final int IS_TERMINAL        = 1 << 2;
 
     /**
      * Is this block the eager global scope - i.e. the original program. This isn't true for the
      * outermost level of recompiles
      */
-    public static final int IS_GLOBAL_SCOPE = 1 << 3;
+    public static final int IS_GLOBAL_SCOPE    = 1 << 3;
 
     /**
      * Is this block a synthetic one introduced by Parser?
      */
-    public static final int IS_SYNTHETIC = 1 << 4;
+    public static final int IS_SYNTHETIC       = 1 << 4;
+
+    /**
+     * Is this the function body block? May not be the first, if parameter list contains expressions.
+     */
+    public static final int IS_BODY            = 1 << 5;
+
+    /**
+     * Is this the parameter initialization block? If present, must be the first block, immediately wrapping the function body block.
+     */
+    public static final int IS_PARAMETER_BLOCK = 1 << 6;
+
+    /**
+     * Marks the variable declaration block for case clauses of a switch statement.
+     */
+    public static final int IS_SWITCH_BLOCK    = 1 << 7;
 
     /**
      * Constructor
@@ -489,4 +504,31 @@
     public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
         return Acceptor.accept(this, visitor);
     }
+
+    /**
+     * Checks if this is a function body.
+     *
+     * @return true if the function body flag is set
+     */
+    public boolean isFunctionBody() {
+        return getFlag(IS_BODY);
+    }
+
+    /**
+     * Checks if this is a parameter block.
+     *
+     * @return true if the parameter block flag is set
+     */
+    public boolean isParameterBlock() {
+        return getFlag(IS_PARAMETER_BLOCK);
+    }
+
+    /**
+     * Checks whether this is a switch block.
+     *
+     * @return true if this is a switch block
+     */
+    public boolean isSwitchBlock() {
+        return getFlag(IS_SWITCH_BLOCK);
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/ClassNode.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2015, 2016, 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 jdk.nashorn.internal.ir;
+
+import java.util.Collections;
+import java.util.List;
+
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+
+/**
+ * IR representation for class definitions.
+ */
+public class ClassNode extends Expression {
+    private static final long serialVersionUID = 1L;
+
+    private final IdentNode ident;
+    private final Expression classHeritage;
+    private final PropertyNode constructor;
+    private final List<PropertyNode> classElements;
+    private final int line;
+
+    /**
+     * Constructor.
+     *
+     * @param line line number
+     * @param token token
+     * @param finish finish
+     * @param ident ident
+     * @param classHeritage class heritage
+     * @param constructor constructor
+     * @param classElements class elements
+     */
+    public ClassNode(final int line, final long token, final int finish, final IdentNode ident, final Expression classHeritage, final PropertyNode constructor,
+                     final List<PropertyNode> classElements) {
+        super(token, finish);
+        this.line = line;
+        this.ident = ident;
+        this.classHeritage = classHeritage;
+        this.constructor = constructor;
+        this.classElements = classElements;
+    }
+
+    /**
+     * Class identifier. Optional.
+     *
+     * @return the class identifier
+     */
+    public IdentNode getIdent() {
+        return ident;
+    }
+
+    /**
+     * The expression of the {@code extends} clause. Optional.
+     *
+     * @return the class heritage
+     */
+    public Expression getClassHeritage() {
+        return classHeritage;
+    }
+
+    /**
+     * Get the constructor method definition.
+     *
+     * @return the constructor
+     */
+    public PropertyNode getConstructor() {
+        return constructor;
+    }
+
+    /**
+     * Get method definitions except the constructor.
+     *
+     * @return the class elements
+     */
+    public List<PropertyNode> getClassElements() {
+        return Collections.unmodifiableList(classElements);
+    }
+
+    /**
+     * Returns the line number.
+     *
+     * @return the line number
+     */
+    public int getLineNumber() {
+        return line;
+    }
+
+    @Override
+    public Type getType() {
+        return Type.OBJECT;
+    }
+
+    @Override
+    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
+        if (visitor.enterClassNode(this)) {
+            return visitor.leaveClassNode(this);
+        }
+
+        return this;
+    }
+
+    @Override
+    public void toString(final StringBuilder sb, final boolean printType) {
+        sb.append("class");
+        if (ident != null) {
+            sb.append(' ');
+            ident.toString(sb, printType);
+        }
+        if (classHeritage != null) {
+            sb.append(" extends");
+            classHeritage.toString(sb, printType);
+        }
+        sb.append(" {");
+        if (constructor != null) {
+            constructor.toString(sb, printType);
+        }
+        for (final PropertyNode classElement : classElements) {
+            sb.append(" ");
+            classElement.toString(sb, printType);
+        }
+        sb.append("}");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/ExpressionList.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2015, 2016, 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 jdk.nashorn.internal.ir;
+
+import java.util.Collections;
+import java.util.List;
+
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+
+/**
+ * IR for CoverParenthesizedExpressionAndArrowParameterList, used only during parsing.
+ */
+public final class ExpressionList extends Expression {
+    private static final long serialVersionUID = 1L;
+
+    private final List<Expression> expressions;
+
+    /**
+     * Constructor.
+     *
+     * @param token token
+     * @param finish finish
+     * @param expressions expression
+     */
+    public ExpressionList(final long token, final int finish, final List<Expression> expressions) {
+        super(token, finish);
+        this.expressions = expressions;
+    }
+
+    /**
+     * Get the list of expressions.
+     *
+     * @return the list of expressions
+     */
+    public List<Expression> getExpressions() {
+        return Collections.unmodifiableList(expressions);
+    }
+
+    @Override
+    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Type getType() {
+        return null;
+    }
+
+    @Override
+    public void toString(StringBuilder sb, boolean printType) {
+        sb.append("(");
+        boolean first = true;
+        for (Expression expression : expressions) {
+            if (first) {
+                first = false;
+            } else {
+                sb.append(", ");
+            }
+            expression.toString(sb, printType);
+        }
+        sb.append(")");
+    }
+}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/ForNode.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/ForNode.java	Thu Apr 28 23:08:16 2016 -0700
@@ -90,7 +90,6 @@
         this.init = init;
         this.modify = modify;
         this.iterator = null;
-
     }
 
     private ForNode(final ForNode forNode, final Expression init, final JoinPredecessorExpression test,
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/FunctionNode.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/FunctionNode.java	Thu Apr 28 23:08:16 2016 -0700
@@ -69,7 +69,13 @@
         /** a getter, @see {@link UserAccessorProperty} */
         GETTER,
         /** a setter, @see {@link UserAccessorProperty} */
-        SETTER
+        SETTER,
+        /** an arrow function */
+        ARROW,
+        /** a generator function */
+        GENERATOR,
+        /** a module function */
+        MODULE
     }
 
     /** Source of entity. */
@@ -122,6 +128,12 @@
     /** Root class for function */
     private final Class<?> rootClass;
 
+    /** The ES6 module */
+    private final Module module;
+
+    /** The debug flags */
+    private final int debugFlags;
+
     /** Is anonymous function flag. */
     public static final int IS_ANONYMOUS                = 1 << 0;
 
@@ -172,49 +184,21 @@
     /**
      * Is this function the top-level program?
      */
-    public static final int IS_PROGRAM = 1 << 13;
+    public static final int IS_PROGRAM                  = 1 << 13;
 
     /**
      * Flag indicating whether this function uses the local variable symbol for itself. Only named function expressions
      * can have this flag set if they reference themselves (e.g. "(function f() { return f })". Declared functions will
      * use the symbol in their parent scope instead when they reference themselves by name.
      */
-    public static final int USES_SELF_SYMBOL = 1 << 14;
+    public static final int USES_SELF_SYMBOL            = 1 << 14;
 
     /** Does this function use the "this" keyword? */
-    public static final int USES_THIS = 1 << 15;
+    public static final int USES_THIS                   = 1 << 15;
 
     /** Is this declared in a dynamic context */
-    public static final int IN_DYNAMIC_CONTEXT = 1 << 16;
-
-    /**
-     * The following flags are derived from directive comments within this function.
-     * Note that even IS_STRICT is one such flag but that requires special handling.
-     */
+    public static final int IN_DYNAMIC_CONTEXT          = 1 << 16;
 
-    /** parser, print parse tree */
-    public static final int IS_PRINT_PARSE       = 1 << 17;
-    /** parser, print lower parse tree */
-    public static final int IS_PRINT_LOWER_PARSE = 1 << 18;
-    /** parser, print AST */
-    public static final int IS_PRINT_AST         = 1 << 19;
-    /** parser, print lower AST */
-    public static final int IS_PRINT_LOWER_AST   = 1 << 20;
-    /** parser, print symbols */
-    public static final int IS_PRINT_SYMBOLS     = 1 << 21;
-
-    // callsite tracing, profiling within this function
-    /** profile callsites in this function? */
-    public static final int IS_PROFILE         = 1 << 22;
-
-    /** trace callsite enterexit in this function? */
-    public static final int IS_TRACE_ENTEREXIT = 1 << 23;
-
-    /** trace callsite misses in this function? */
-    public static final int IS_TRACE_MISSES    = 1 << 24;
-
-    /** trace callsite values in this function? */
-    public static final int IS_TRACE_VALUES    = 1 << 25;
 
     /**
      * Whether this function needs the callee {@link ScriptFunction} instance passed to its code as a
@@ -222,18 +206,41 @@
      * Rather, it is always calculated (see {@link #needsCallee()}). {@link RecompilableScriptFunctionData}
      * will, however, cache the value of this flag.
      */
-    public static final int NEEDS_CALLEE       = 1 << 26;
+    public static final int NEEDS_CALLEE                = 1 << 17;
 
     /**
      * Is the function node cached?
      */
-    public static final int IS_CACHED = 1 << 27;
+    public static final int IS_CACHED                   = 1 << 18;
+
+    /**
+     * Does this function contain a super call? (cf. ES6 14.3.5 Static Semantics: HasDirectSuper)
+     */
+    public static final int ES6_HAS_DIRECT_SUPER        = 1 << 19;
+
+    /**
+     * Does this function use the super binding?
+     */
+    public static final int ES6_USES_SUPER              = 1 << 20;
 
-    /** extension callsite flags mask */
-    public static final int EXTENSION_CALLSITE_FLAGS = IS_PRINT_PARSE |
-        IS_PRINT_LOWER_PARSE | IS_PRINT_AST | IS_PRINT_LOWER_AST |
-        IS_PRINT_SYMBOLS | IS_PROFILE | IS_TRACE_ENTEREXIT |
-        IS_TRACE_MISSES | IS_TRACE_VALUES;
+    /**
+     * Is this function a (class or object) method?
+     */
+    public static final int ES6_IS_METHOD               = 1 << 21;
+
+    /**
+     * Is this the constructor method?
+     */
+    public static final int ES6_IS_CLASS_CONSTRUCTOR    = 1 << 22;
+
+    /** Is this the constructor of a subclass (i.e., a class with an extends declaration)? */
+    public static final int ES6_IS_SUBCLASS_CONSTRUCTOR = 1 << 23;
+
+    /** is this a strong mode function? */
+    public static final int ES6_IS_STRONG               = 1 << 24;
+
+    /** Does this function use new.target? */
+    public static final int ES6_USES_NEW_TARGET         = 1 << 25;
 
     /** Does this function or any nested functions contain an eval? */
     private static final int HAS_DEEP_EVAL = HAS_EVAL | HAS_NESTED_EVAL;
@@ -247,8 +254,44 @@
     /** Does this function need the parent scope? It needs it if either it or its descendants use variables from it, or have a deep eval, or it's the program. */
     public static final int NEEDS_PARENT_SCOPE = USES_ANCESTOR_SCOPE | HAS_DEEP_EVAL | IS_PROGRAM;
 
+
+    /**
+     * The following flags are derived from directive comments within this function.
+     * Note that even IS_STRICT is one such flag but that requires special handling.
+     */
+
+    /** parser, print parse tree */
+    public static final int DEBUG_PRINT_PARSE       = 1 << 0;
+    /** parser, print lower parse tree */
+    public static final int DEBUG_PRINT_LOWER_PARSE = 1 << 1;
+    /** parser, print AST */
+    public static final int DEBUG_PRINT_AST         = 1 << 2;
+    /** parser, print lower AST */
+    public static final int DEBUG_PRINT_LOWER_AST   = 1 << 3;
+    /** parser, print symbols */
+    public static final int DEBUG_PRINT_SYMBOLS     = 1 << 4;
+
+    // callsite tracing, profiling within this function
+    /** profile callsites in this function? */
+    public static final int DEBUG_PROFILE           = 1 << 5;
+
+    /** trace callsite enterexit in this function? */
+    public static final int DEBUG_TRACE_ENTEREXIT   = 1 << 6;
+
+    /** trace callsite misses in this function? */
+    public static final int DEBUG_TRACE_MISSES      = 1 << 7;
+
+    /** trace callsite values in this function? */
+    public static final int DEBUG_TRACE_VALUES      = 1 << 8;
+
+    /** extension callsite flags mask */
+    public static final int DEBUG_CALLSITE_FLAGS = DEBUG_PRINT_PARSE |
+            DEBUG_PRINT_LOWER_PARSE | DEBUG_PRINT_AST | DEBUG_PRINT_LOWER_AST |
+            DEBUG_PRINT_SYMBOLS | DEBUG_PROFILE | DEBUG_TRACE_ENTEREXIT |
+            DEBUG_TRACE_MISSES | DEBUG_TRACE_VALUES;
+
     /** What is the return type of this function? */
-    private Type returnType = Type.UNKNOWN;
+    public Type returnType = Type.UNKNOWN;
 
     /**
      * Constructor
@@ -267,6 +310,8 @@
      * @param flags      initial flags
      * @param body       body of the function
      * @param endParserState The parser state at the end of the parsing.
+     * @param module     the module
+     * @param debugFlags the debug flags
      */
     public FunctionNode(
         final Source source,
@@ -282,7 +327,9 @@
         final FunctionNode.Kind kind,
         final int flags,
         final Block body,
-        final Object endParserState) {
+        final Object endParserState,
+        final Module module,
+        final int debugFlags) {
         super(token, finish);
 
         this.source           = source;
@@ -299,7 +346,9 @@
         this.body             = body;
         this.thisProperties   = 0;
         this.rootClass        = null;
-        this.endParserState    = endParserState;
+        this.endParserState   = endParserState;
+        this.module           = module;
+        this.debugFlags       = debugFlags;
     }
 
     private FunctionNode(
@@ -335,6 +384,8 @@
         this.ident           = functionNode.ident;
         this.kind            = functionNode.kind;
         this.firstToken      = functionNode.firstToken;
+        this.module          = functionNode.module;
+        this.debugFlags      = functionNode.debugFlags;
     }
 
     @Override
@@ -366,23 +417,23 @@
         }
 
         // quick check for extension callsite flags turned on by directives.
-        if ((flags & EXTENSION_CALLSITE_FLAGS) == 0) {
+        if ((debugFlags & DEBUG_CALLSITE_FLAGS) == 0) {
             return callsiteFlags;
         }
 
-        if (getFlag(IS_PROFILE)) {
+        if (getDebugFlag(DEBUG_PROFILE)) {
             callsiteFlags |= CALLSITE_PROFILE;
         }
 
-        if (getFlag(IS_TRACE_MISSES)) {
+        if (getDebugFlag(DEBUG_TRACE_MISSES)) {
             callsiteFlags |= CALLSITE_TRACE | CALLSITE_TRACE_MISSES;
         }
 
-        if (getFlag(IS_TRACE_VALUES)) {
+        if (getDebugFlag(DEBUG_TRACE_VALUES)) {
             callsiteFlags |= CALLSITE_TRACE | CALLSITE_TRACE_ENTEREXIT | CALLSITE_TRACE_VALUES;
         }
 
-        if (getFlag(IS_TRACE_ENTEREXIT)) {
+        if (getDebugFlag(DEBUG_TRACE_ENTEREXIT)) {
             callsiteFlags |= CALLSITE_TRACE | CALLSITE_TRACE_ENTEREXIT;
         }
 
@@ -466,23 +517,23 @@
     public static int getDirectiveFlag(final String directive) {
         switch (directive) {
             case "nashorn callsite trace enterexit":
-                return IS_TRACE_ENTEREXIT;
+                return DEBUG_TRACE_ENTEREXIT;
             case "nashorn callsite trace misses":
-                return IS_TRACE_MISSES;
+                return DEBUG_TRACE_MISSES;
             case "nashorn callsite trace objects":
-                return IS_TRACE_VALUES;
+                return DEBUG_TRACE_VALUES;
             case "nashorn callsite profile":
-                return IS_PROFILE;
+                return DEBUG_PROFILE;
             case "nashorn print parse":
-                return IS_PRINT_PARSE;
+                return DEBUG_PRINT_PARSE;
             case "nashorn print lower parse":
-                return IS_PRINT_LOWER_PARSE;
+                return DEBUG_PRINT_LOWER_PARSE;
             case "nashorn print ast":
-                return IS_PRINT_AST;
+                return DEBUG_PRINT_AST;
             case "nashorn print lower ast":
-                return IS_PRINT_LOWER_AST;
+                return DEBUG_PRINT_LOWER_AST;
             case "nashorn print symbols":
-                return IS_PRINT_SYMBOLS;
+                return DEBUG_PRINT_SYMBOLS;
             default:
                 // unknown/unsupported directive
                 return 0;
@@ -579,6 +630,25 @@
     }
 
     /**
+     * Returns the debug flags for this function.
+     *
+     * @return the debug flags
+     */
+    public int getDebugFlags() {
+        return debugFlags;
+    }
+
+    /**
+     * Checks whether a debug flag is set for this function.
+     *
+     * @param debugFlag the debug flag
+     * @return true if the flag is set
+     */
+    public boolean getDebugFlag(final int debugFlag) {
+        return (debugFlags & debugFlag) != 0;
+    }
+
+    /**
      * Returns true if the function is the top-level program.
      * @return True if this function node represents the top-level program.
      */
@@ -1065,6 +1135,86 @@
         return setFlag(lc, IS_CACHED);
     }
 
+    /**
+     * Checks if the function is generated in strong mode.
+     *
+     * @return true if strong mode enabled for function
+     */
+    public boolean isStrong() {
+        return getFlag(ES6_IS_STRONG);
+    }
+
+    /**
+     * Checks if this is an ES6 method.
+     *
+     * @return true if the ES6 method flag is set
+     */
+    public boolean isMethod() {
+        return getFlag(ES6_IS_METHOD);
+    }
+
+    /**
+     * Checks if this function uses the ES6 super binding.
+     *
+     * @return true if the ES6 super flag is set
+     */
+    public boolean usesSuper() {
+        return getFlag(ES6_USES_SUPER);
+    }
+
+    /**
+     * Checks if this function directly uses the super binding.
+     *
+     * @return true if the ES6 has-direct-super flag is set
+     */
+    public boolean hasDirectSuper() {
+        return getFlag(ES6_HAS_DIRECT_SUPER);
+    }
+
+    /**
+     * Checks if this is an ES6 class constructor.
+     *
+     * @return true if the ES6 class constructor flag is set
+     */
+    public boolean isClassConstructor() {
+        return getFlag(ES6_IS_CLASS_CONSTRUCTOR);
+    }
+
+    /**
+     * Checks if this is an ES6 subclass constructor.
+     *
+     * @return true if the ES6 subclass constructor flag is set
+     */
+    public boolean isSubclassConstructor() {
+        return getFlag(ES6_IS_SUBCLASS_CONSTRUCTOR);
+    }
+
+    /**
+     * Checks if this function uses the ES6 new-targert.
+     *
+     * @return true if the ES6 new-target flag is set
+     */
+    public boolean usesNewTarget() {
+        return getFlag(ES6_USES_NEW_TARGET);
+    }
+
+    /**
+     * Checks if this is an ES6 module.
+     *
+     * @return true if this is an ES6 module
+     */
+    public boolean isModule() {
+        return kind == Kind.MODULE;
+    }
+
+    /**
+     * Returns the functions's ES6 module.
+     *
+     * @return the module, or null if this function is not part of one
+     */
+    public Module getModule() {
+        return module;
+    }
 
     /**
      * Get the compile unit used to compile this function
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/IdentNode.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/IdentNode.java	Thu Apr 28 23:08:16 2016 -0700
@@ -49,6 +49,11 @@
     private static final int FUTURESTRICT_NAME = 1 << 3;
     private static final int IS_DECLARED_HERE  = 1 << 4;
     private static final int IS_DEAD           = 1 << 5;
+    private static final int DIRECT_SUPER      = 1 << 6;
+    private static final int REST_PARAMETER    = 1 << 7;
+    private static final int PROTO_PROPERTY    = 1 << 8;
+    private static final int DEFAULT_PARAMETER = 1 << 9;
+    private static final int DESTRUCTURED_PARAMETER = 1 << 10;
 
     /** Identifier. */
     private final String name;
@@ -382,4 +387,94 @@
     public LocalVariableConversion getLocalVariableConversion() {
         return conversion;
     }
+
+    /**
+     * Checks if this is a direct super identifier
+     *
+     * @return true if the direct super flag is set
+     */
+    public boolean isDirectSuper() {
+        return (flags & DIRECT_SUPER) != 0;
+    }
+
+    /**
+     * Return a new identifier with the direct super flag set.
+     *
+     * @return the new identifier
+     */
+    public IdentNode setIsDirectSuper() {
+        return new IdentNode(this, name, type, flags | DIRECT_SUPER, programPoint, conversion);
+    }
+
+    /**
+     * Checks if this is a rest parameter
+     *
+     * @return true if the rest parameter flag is set
+     */
+    public boolean isRestParameter() {
+        return (flags & REST_PARAMETER) != 0;
+    }
+
+    /**
+     * Return a new identifier with the rest parameter flag set.
+     *
+     * @return the new identifier
+     */
+    public IdentNode setIsRestParameter() {
+        return new IdentNode(this, name, type, flags | REST_PARAMETER, programPoint, conversion);
+    }
+
+    /**
+     * Checks if this is a proto property name.
+     *
+     * @return true if this is the proto property name
+     */
+    public boolean isProtoPropertyName() {
+        return (flags & PROTO_PROPERTY) != 0;
+    }
+
+    /**
+     * Return a new identifier with the proto property name flag set.
+     *
+     * @return the new identifier
+     */
+    public IdentNode setIsProtoPropertyName() {
+        return new IdentNode(this, name, type, flags | PROTO_PROPERTY, programPoint, conversion);
+    }
+
+    /**
+     * Checks whether this is a default parameter.
+     *
+     * @return true if this is a default parameter
+     */
+    public boolean isDefaultParameter() {
+        return (flags & DEFAULT_PARAMETER) != 0;
+    }
+
+    /**
+     * Return a new identifier with the default parameter flag set.
+     *
+     * @return the new identifier
+     */
+    public IdentNode setIsDefaultParameter() {
+        return new IdentNode(this, name, type, flags | DEFAULT_PARAMETER, programPoint, conversion);
+    }
+
+    /**
+     * Checks whether this is a destructured parameter.
+     *
+     * @return true if this is a destructured parameter
+     */
+    public boolean isDestructuredParameter() {
+        return (flags & DESTRUCTURED_PARAMETER) != 0;
+    }
+
+    /**
+     * Return a new identifier with the destructured parameter flag set.
+     *
+     * @return the new identifier
+     */
+    public IdentNode setIsDestructuredParameter() {
+        return new IdentNode(this, name, type, flags | DESTRUCTURED_PARAMETER, programPoint, conversion);
+    }
 }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/IndexNode.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/IndexNode.java	Thu Apr 28 23:08:16 2016 -0700
@@ -47,12 +47,13 @@
      * @param index   index for access
      */
     public IndexNode(final long token, final int finish, final Expression base, final Expression index) {
-        super(token, finish, base, false);
+        super(token, finish, base, false, false);
         this.index = index;
     }
 
-    private IndexNode(final IndexNode indexNode, final Expression base, final Expression index, final boolean isFunction, final Type type, final int programPoint) {
-        super(indexNode, base, isFunction, type, programPoint);
+    private IndexNode(final IndexNode indexNode, final Expression base, final Expression index, final boolean isFunction,
+                      final Type type, final int programPoint, final boolean isSuper) {
+        super(indexNode, base, isFunction, type, programPoint, isSuper);
         this.index = index;
     }
 
@@ -101,7 +102,7 @@
         if (this.base == base) {
             return this;
         }
-        return new IndexNode(this, base, index, isFunction(), type, programPoint);
+        return new IndexNode(this, base, index, isFunction(), type, programPoint, isSuper());
     }
 
     /**
@@ -113,7 +114,7 @@
         if(this.index == index) {
             return this;
         }
-        return new IndexNode(this, base, index, isFunction(), type, programPoint);
+        return new IndexNode(this, base, index, isFunction(), type, programPoint, isSuper());
     }
 
     @Override
@@ -121,7 +122,7 @@
         if (this.type == type) {
             return this;
         }
-        return new IndexNode(this, base, index, isFunction(), type, programPoint);
+        return new IndexNode(this, base, index, isFunction(), type, programPoint, isSuper());
     }
 
     @Override
@@ -129,7 +130,7 @@
         if (isFunction()) {
             return this;
         }
-        return new IndexNode(this, base, index, true, type, programPoint);
+        return new IndexNode(this, base, index, true, type, programPoint, isSuper());
     }
 
     @Override
@@ -137,6 +138,14 @@
         if (this.programPoint == programPoint) {
             return this;
         }
-        return new IndexNode(this, base, index, isFunction(), type, programPoint);
+        return new IndexNode(this, base, index, isFunction(), type, programPoint, isSuper());
+    }
+
+    @Override
+    public IndexNode setIsSuper() {
+        if (isSuper()) {
+            return this;
+        }
+        return new IndexNode(this, base, index, isFunction(), type, programPoint, true);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Module.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 2015, 2016, 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 jdk.nashorn.internal.ir;
+
+import java.util.List;
+
+/**
+ * ES6 Module information.
+ */
+public final class Module {
+
+    /** The synthetic binding name assigned to export default declarations with unnamed expressions. */
+    public static final String DEFAULT_EXPORT_BINDING_NAME = "*default*";
+
+    /** The {@code export default} name. */
+    public static final String DEFAULT_NAME = "default";
+
+    /** The {@code export *} name. */
+    public static final String STAR_NAME = "*";
+
+    /**
+     * A module ExportEntry record.
+     *
+     * @link http://www.ecma-international.org/ecma-262/6.0/#sec-source-text-module-records
+     */
+    public static final class ExportEntry {
+        private final String exportName;
+        private final String moduleRequest;
+        private final String importName;
+        private final String localName;
+
+        private ExportEntry(final String exportName, final String moduleRequest, final String importName, final String localName) {
+            this.exportName = exportName;
+            this.moduleRequest = moduleRequest;
+            this.importName = importName;
+            this.localName = localName;
+        }
+
+        /**
+         * Creates a {@code export *} export entry.
+         *
+         * @param moduleRequest the module request
+         * @return the export entry
+         */
+        public static ExportEntry exportStarFrom(final String moduleRequest) {
+            return new ExportEntry(null, moduleRequest, STAR_NAME, null);
+        }
+
+        /**
+         * Creates a {@code export default} export entry.
+         *
+         * @return the export entry
+         */
+        public static ExportEntry exportDefault() {
+            return exportDefault(DEFAULT_EXPORT_BINDING_NAME);
+        }
+
+        /**
+         * Creates a {@code export default} export entry with a local name.
+         *
+         * @param localName the local name
+         * @return the export entry
+         */
+        public static ExportEntry exportDefault(final String localName) {
+            return new ExportEntry(DEFAULT_NAME, null, null, localName);
+        }
+
+        /**
+         * Creates a export entry with a local name and export name.
+         *
+         * @param exportName the export name
+         * @param localName the local name
+         * @return the export entry
+         */
+        public static ExportEntry exportSpecifier(final String exportName, final String localName) {
+            return new ExportEntry(exportName, null, null, localName);
+        }
+
+        /**
+         * Creates a export entry with an export name.
+         *
+         * @param exportName the export name
+         * @return the export entry
+         */
+        public static ExportEntry exportSpecifier(final String exportName) {
+            return exportSpecifier(exportName, exportName);
+        }
+
+        /**
+         * Create a copy of this entry with the specified {@code module request} string.
+         *
+         * @param moduleRequest the module request
+         * @return the new export entry
+         */
+        public ExportEntry withFrom(@SuppressWarnings("hiding") final String moduleRequest) {
+            return new ExportEntry(exportName, moduleRequest, localName, null);
+        }
+
+        /**
+         * Returns the entry's export name.
+         *
+         * @return the export name
+         */
+        public String getExportName() {
+            return exportName;
+        }
+
+        /**
+         * Returns the entry's module request.
+         *
+         * @return the module request
+         */
+        public String getModuleRequest() {
+            return moduleRequest;
+        }
+
+        /**
+         * Returns the entry's import name.
+         *
+         * @return the import name
+         */
+        public String getImportName() {
+            return importName;
+        }
+
+        /**
+         * Returns the entry's local name.
+         *
+         * @return the local name
+         */
+        public String getLocalName() {
+            return localName;
+        }
+
+        @Override
+        public String toString() {
+            return "ExportEntry [exportName=" + exportName + ", moduleRequest=" + moduleRequest + ", importName=" + importName + ", localName=" + localName + "]";
+        }
+    }
+
+    /**
+     * An ImportEntry record.
+     *
+     * @link http://www.ecma-international.org/ecma-262/6.0/#sec-source-text-module-records
+     */
+    public static final class ImportEntry {
+        private final String moduleRequest;
+        private final String importName;
+        private final String localName;
+
+        private ImportEntry(final String moduleRequest, final String importName, final String localName) {
+            this.moduleRequest = moduleRequest;
+            this.importName = importName;
+            this.localName = localName;
+        }
+
+        /**
+         * Creates an import entry with default name.
+         *
+         * @param localName the local name
+         * @return the import entry
+         */
+        public static ImportEntry importDefault(final String localName) {
+            return new ImportEntry(null, DEFAULT_NAME, localName);
+        }
+
+        /**
+         * Creates an import entry with {@code *} import name.
+         *
+         * @param localName the local name
+         * @return the import entry
+         */
+        public static ImportEntry importStarAsNameSpaceFrom(final String localName) {
+            return new ImportEntry(null, STAR_NAME, localName);
+        }
+
+        /**
+         * Creates an import entry with the given import and local names.
+         *
+         * @param importName the import name
+         * @param localName the local name
+         * @return the import entry
+         */
+        public static ImportEntry importSpecifier(final String importName, final String localName) {
+            return new ImportEntry(null, importName, localName);
+        }
+
+        /**
+         * Creates a new import entry with the given import name.
+         *
+         * @param importName the import name
+         * @return the import entry
+         */
+        public static ImportEntry importSpecifier(final String importName) {
+            return importSpecifier(importName, importName);
+        }
+
+        /**
+         * Returns a copy of this import entry with the given module request.
+         *
+         * @param moduleRequest the module request
+         * @return the new import entry
+         */
+        public ImportEntry withFrom(@SuppressWarnings("hiding") final String moduleRequest) {
+            return new ImportEntry(moduleRequest, importName, localName);
+        }
+
+        /**
+         * Returns the entry's module request.
+         *
+         * @return the module request
+         */
+        public String getModuleRequest() {
+            return moduleRequest;
+        }
+
+        /**
+         * Returns the entry's import name.
+         *
+         * @return the import name
+         */
+        public String getImportName() {
+            return importName;
+        }
+
+        /**
+         * Returns the entry's local name.
+         *
+         * @return the local name
+         */
+        public String getLocalName() {
+            return localName;
+        }
+
+        @Override
+        public String toString() {
+            return "ImportEntry [moduleRequest=" + moduleRequest + ", importName=" + importName + ", localName=" + localName + "]";
+        }
+    }
+
+    private final List<String> requestedModules;
+    private final List<ImportEntry> importEntries;
+    private final List<ExportEntry> localExportEntries;
+    private final List<ExportEntry> indirectExportEntries;
+    private final List<ExportEntry> starExportEntries;
+
+    /**
+     * Creates a module with the specified requested modules and import and export entries.
+     *
+     * @param requestedModules the requested modules
+     * @param importEntries the import entries
+     * @param localExportEntries local export entries
+     * @param indirectExportEntries indirect export entries
+     * @param starExportEntries star export entries
+     */
+    public Module(final List<String> requestedModules, final List<ImportEntry> importEntries, final List<ExportEntry> localExportEntries,
+                  final List<ExportEntry> indirectExportEntries, final List<ExportEntry> starExportEntries) {
+        this.requestedModules = requestedModules;
+        this.importEntries = importEntries;
+        this.localExportEntries = localExportEntries;
+        this.indirectExportEntries = indirectExportEntries;
+        this.starExportEntries = starExportEntries;
+    }
+
+    /**
+     * Returns the list of requested modules.
+     *
+     * @return the requested modules
+     */
+    public List<String> getRequestedModules() {
+        return requestedModules;
+    }
+
+    /**
+     * Returns the list of import entries.
+     *
+     * @return the import entries
+     */
+    public List<ImportEntry> getImportEntries() {
+        return importEntries;
+    }
+
+    /**
+     * Returns the list of local export entries.
+     *
+     * @return the local export entries
+     */
+    public List<ExportEntry> getLocalExportEntries() {
+        return localExportEntries;
+    }
+
+    /**
+     * Returns the list of indirect export entries.
+     *
+     * @return the indirect export entries
+     */
+    public List<ExportEntry> getIndirectExportEntries() {
+        return indirectExportEntries;
+    }
+
+    /**
+     * Returns the list of star export entries.
+     *
+     * @return the star export entries
+     */
+    public List<ExportEntry> getStarExportEntries() {
+        return starExportEntries;
+    }
+
+    @Override
+    public String toString() {
+        return "Module [requestedModules=" + requestedModules + ", importEntries=" + importEntries + ", localExportEntries=" + localExportEntries + ", indirectExportEntries=" +
+                indirectExportEntries + ", starExportEntries=" + starExportEntries + "]";
+    }
+}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/PropertyNode.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/PropertyNode.java	Thu Apr 28 23:08:16 2016 -0700
@@ -36,7 +36,7 @@
     private static final long serialVersionUID = 1L;
 
     /** Property key. */
-    private final PropertyKey key;
+    private final Expression key;
 
     /** Property value. */
     private final Expression value;
@@ -47,6 +47,12 @@
     /** Property getter. */
     private final FunctionNode setter;
 
+    /** static property flag */
+    private final boolean isStatic;
+
+    /** Computed property flag */
+    private final boolean computed;
+
     /**
      * Constructor
      *
@@ -56,21 +62,27 @@
      * @param value   the value of this property
      * @param getter  getter function body
      * @param setter  setter function body
+     * @param isStatic is this a static property?
+     * @param computed is this a computed property?
      */
-    public PropertyNode(final long token, final int finish, final PropertyKey key, final Expression value, final FunctionNode getter, final FunctionNode setter) {
+    public PropertyNode(final long token, final int finish, final Expression key, final Expression value, final FunctionNode getter, final FunctionNode setter, final boolean isStatic, final boolean computed) {
         super(token, finish);
         this.key    = key;
         this.value  = value;
         this.getter = getter;
         this.setter = setter;
+        this.isStatic = isStatic;
+        this.computed = computed;
     }
 
-    private PropertyNode(final PropertyNode propertyNode, final PropertyKey key, final Expression value, final FunctionNode getter, final FunctionNode setter) {
+    private PropertyNode(final PropertyNode propertyNode, final Expression key, final Expression value, final FunctionNode getter, final FunctionNode setter, final boolean isStatic, final boolean computed) {
         super(propertyNode);
         this.key    = key;
         this.value  = value;
         this.getter = getter;
         this.setter = setter;
+        this.isStatic = isStatic;
+        this.computed = computed;
     }
 
     /**
@@ -78,14 +90,14 @@
      * @return key name
      */
     public String getKeyName() {
-        return key.getPropertyName();
+        return key instanceof PropertyKey ? ((PropertyKey) key).getPropertyName() : null;
     }
 
     @Override
     public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
         if (visitor.enterPropertyNode(this)) {
             return visitor.leavePropertyNode(
-                setKey((PropertyKey)((Node)key).accept(visitor)).
+                setKey((Expression) key.accept(visitor)).
                 setValue(value == null ? null : (Expression)value.accept(visitor)).
                 setGetter(getter == null ? null : (FunctionNode)getter.accept(visitor)).
                 setSetter(setter == null ? null : (FunctionNode)setter.accept(visitor)));
@@ -134,7 +146,7 @@
         if (this.getter == getter) {
             return this;
         }
-        return new PropertyNode(this, key, value, getter, setter);
+        return new PropertyNode(this, key, value, getter, setter, isStatic, computed);
     }
 
     /**
@@ -142,14 +154,14 @@
      * @return the key
      */
     public Expression getKey() {
-        return (Expression)key;
+        return key;
     }
 
-    private PropertyNode setKey(final PropertyKey key) {
+    private PropertyNode setKey(final Expression key) {
         if (this.key == key) {
             return this;
         }
-        return new PropertyNode(this, key, value, getter, setter);
+        return new PropertyNode(this, key, value, getter, setter, isStatic, computed);
     }
 
     /**
@@ -169,7 +181,7 @@
         if (this.setter == setter) {
             return this;
         }
-        return new PropertyNode(this, key, value, getter, setter);
+        return new PropertyNode(this, key, value, getter, setter, isStatic, computed);
     }
 
     /**
@@ -189,6 +201,24 @@
         if (this.value == value) {
             return this;
         }
-        return new PropertyNode(this, key, value, getter, setter);
-   }
+        return new PropertyNode(this, key, value, getter, setter, isStatic, computed);
+    }
+
+    /**
+     * Returns true if this is a static property.
+     *
+     * @return true if static flag is set
+     */
+    public boolean isStatic() {
+        return isStatic;
+    }
+
+    /**
+     * Returns true if this is a computed property.
+     *
+     * @return true if the computed flag is set
+     */
+    public boolean isComputed() {
+        return computed;
+    }
 }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java	Thu Apr 28 23:08:16 2016 -0700
@@ -133,8 +133,8 @@
             return enterASSIGN_SHR(binaryNode);
         case ASSIGN_SUB:
             return enterASSIGN_SUB(binaryNode);
-        case BIND:
-            return enterBIND(binaryNode);
+        case ARROW:
+            return enterARROW(binaryNode);
         case BIT_AND:
             return enterBIT_AND(binaryNode);
         case BIT_OR:
@@ -217,8 +217,8 @@
             return leaveASSIGN_SHR(binaryNode);
         case ASSIGN_SUB:
             return leaveASSIGN_SUB(binaryNode);
-        case BIND:
-            return leaveBIND(binaryNode);
+        case ARROW:
+            return leaveARROW(binaryNode);
         case BIT_AND:
             return leaveBIT_AND(binaryNode);
         case BIT_OR:
@@ -735,22 +735,22 @@
     }
 
     /**
-     * Binary enter - callback for entering a bind operator
+     * Binary enter - callback for entering a arrow operator
      *
      * @param  binaryNode the node
      * @return true if traversal should continue and node children be traversed, false otherwise
      */
-    public boolean enterBIND(final BinaryNode binaryNode) {
+    public boolean enterARROW(final BinaryNode binaryNode) {
         return enterDefault(binaryNode);
     }
 
     /**
-     * Binary leave - callback for leaving a bind operator
+     * Binary leave - callback for leaving a arrow operator
      *
      * @param  binaryNode the node
      * @return processed node, which will replace the original one, or the original node
      */
-    public Node leaveBIND(final BinaryNode binaryNode) {
+    public Node leaveARROW(final BinaryNode binaryNode) {
         return leaveDefault(binaryNode);
     }
 
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/visitor/NodeVisitor.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/visitor/NodeVisitor.java	Thu Apr 28 23:08:16 2016 -0700
@@ -33,6 +33,7 @@
 import jdk.nashorn.internal.ir.CallNode;
 import jdk.nashorn.internal.ir.CaseNode;
 import jdk.nashorn.internal.ir.CatchNode;
+import jdk.nashorn.internal.ir.ClassNode;
 import jdk.nashorn.internal.ir.ContinueNode;
 import jdk.nashorn.internal.ir.DebuggerNode;
 import jdk.nashorn.internal.ir.EmptyNode;
@@ -897,5 +898,23 @@
         return leaveDefault(withNode);
     }
 
+    /**
+     * Callback for entering a ClassNode
+     *
+     * @param  classNode  the node
+     * @return true if traversal should continue and node children be traversed, false otherwise
+     */
+    public boolean enterClassNode(final ClassNode classNode) {
+        return enterDefault(classNode);
+    }
 
+    /**
+     * Callback for leaving a ClassNode
+     *
+     * @param  classNode  the node
+     * @return processed node, which will replace the original one, or the original node
+     */
+    public Node leaveClassNode(final ClassNode classNode) {
+        return leaveDefault(classNode);
+    }
 }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java	Thu Apr 28 23:08:16 2016 -0700
@@ -28,35 +28,55 @@
 import static jdk.nashorn.internal.codegen.CompilerConstants.ANON_FUNCTION_PREFIX;
 import static jdk.nashorn.internal.codegen.CompilerConstants.EVAL;
 import static jdk.nashorn.internal.codegen.CompilerConstants.PROGRAM;
+import static jdk.nashorn.internal.parser.TokenType.ARROW;
 import static jdk.nashorn.internal.parser.TokenType.ASSIGN;
 import static jdk.nashorn.internal.parser.TokenType.CASE;
 import static jdk.nashorn.internal.parser.TokenType.CATCH;
+import static jdk.nashorn.internal.parser.TokenType.CLASS;
 import static jdk.nashorn.internal.parser.TokenType.COLON;
 import static jdk.nashorn.internal.parser.TokenType.COMMARIGHT;
+import static jdk.nashorn.internal.parser.TokenType.COMMENT;
 import static jdk.nashorn.internal.parser.TokenType.CONST;
 import static jdk.nashorn.internal.parser.TokenType.DECPOSTFIX;
 import static jdk.nashorn.internal.parser.TokenType.DECPREFIX;
+import static jdk.nashorn.internal.parser.TokenType.ELLIPSIS;
 import static jdk.nashorn.internal.parser.TokenType.ELSE;
 import static jdk.nashorn.internal.parser.TokenType.EOF;
 import static jdk.nashorn.internal.parser.TokenType.EOL;
+import static jdk.nashorn.internal.parser.TokenType.EQ_STRICT;
+import static jdk.nashorn.internal.parser.TokenType.ESCSTRING;
+import static jdk.nashorn.internal.parser.TokenType.EXPORT;
+import static jdk.nashorn.internal.parser.TokenType.EXTENDS;
 import static jdk.nashorn.internal.parser.TokenType.FINALLY;
 import static jdk.nashorn.internal.parser.TokenType.FUNCTION;
 import static jdk.nashorn.internal.parser.TokenType.IDENT;
 import static jdk.nashorn.internal.parser.TokenType.IF;
+import static jdk.nashorn.internal.parser.TokenType.IMPORT;
 import static jdk.nashorn.internal.parser.TokenType.INCPOSTFIX;
 import static jdk.nashorn.internal.parser.TokenType.LBRACE;
+import static jdk.nashorn.internal.parser.TokenType.LBRACKET;
 import static jdk.nashorn.internal.parser.TokenType.LET;
 import static jdk.nashorn.internal.parser.TokenType.LPAREN;
+import static jdk.nashorn.internal.parser.TokenType.MUL;
+import static jdk.nashorn.internal.parser.TokenType.PERIOD;
 import static jdk.nashorn.internal.parser.TokenType.RBRACE;
 import static jdk.nashorn.internal.parser.TokenType.RBRACKET;
 import static jdk.nashorn.internal.parser.TokenType.RPAREN;
 import static jdk.nashorn.internal.parser.TokenType.SEMICOLON;
+import static jdk.nashorn.internal.parser.TokenType.SPREAD_ARRAY;
+import static jdk.nashorn.internal.parser.TokenType.STATIC;
+import static jdk.nashorn.internal.parser.TokenType.STRING;
+import static jdk.nashorn.internal.parser.TokenType.SUPER;
 import static jdk.nashorn.internal.parser.TokenType.TEMPLATE;
 import static jdk.nashorn.internal.parser.TokenType.TEMPLATE_HEAD;
 import static jdk.nashorn.internal.parser.TokenType.TEMPLATE_MIDDLE;
 import static jdk.nashorn.internal.parser.TokenType.TEMPLATE_TAIL;
 import static jdk.nashorn.internal.parser.TokenType.TERNARY;
+import static jdk.nashorn.internal.parser.TokenType.VAR;
+import static jdk.nashorn.internal.parser.TokenType.VOID;
 import static jdk.nashorn.internal.parser.TokenType.WHILE;
+import static jdk.nashorn.internal.parser.TokenType.YIELD;
+import static jdk.nashorn.internal.parser.TokenType.YIELD_STAR;
 
 import java.io.Serializable;
 import java.util.ArrayDeque;
@@ -68,6 +88,8 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
+import java.util.function.Consumer;
 import jdk.nashorn.internal.codegen.CompilerConstants;
 import jdk.nashorn.internal.codegen.Namespace;
 import jdk.nashorn.internal.ir.AccessNode;
@@ -79,11 +101,13 @@
 import jdk.nashorn.internal.ir.CallNode;
 import jdk.nashorn.internal.ir.CaseNode;
 import jdk.nashorn.internal.ir.CatchNode;
+import jdk.nashorn.internal.ir.ClassNode;
 import jdk.nashorn.internal.ir.ContinueNode;
 import jdk.nashorn.internal.ir.DebuggerNode;
 import jdk.nashorn.internal.ir.EmptyNode;
 import jdk.nashorn.internal.ir.ErrorNode;
 import jdk.nashorn.internal.ir.Expression;
+import jdk.nashorn.internal.ir.ExpressionList;
 import jdk.nashorn.internal.ir.ExpressionStatement;
 import jdk.nashorn.internal.ir.ForNode;
 import jdk.nashorn.internal.ir.FunctionNode;
@@ -92,7 +116,9 @@
 import jdk.nashorn.internal.ir.IndexNode;
 import jdk.nashorn.internal.ir.JoinPredecessorExpression;
 import jdk.nashorn.internal.ir.LabelNode;
+import jdk.nashorn.internal.ir.LexicalContext;
 import jdk.nashorn.internal.ir.LiteralNode;
+import jdk.nashorn.internal.ir.Module;
 import jdk.nashorn.internal.ir.Node;
 import jdk.nashorn.internal.ir.ObjectNode;
 import jdk.nashorn.internal.ir.PropertyKey;
@@ -110,6 +136,7 @@
 import jdk.nashorn.internal.ir.WithNode;
 import jdk.nashorn.internal.ir.debug.ASTWriter;
 import jdk.nashorn.internal.ir.debug.PrintVisitor;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.ErrorManager;
 import jdk.nashorn.internal.runtime.JSErrorType;
@@ -254,6 +281,14 @@
     }
 
     /**
+     * Set up first token. Skips opening EOL.
+     */
+    private void scanFirstToken() {
+        k = -1;
+        next();
+    }
+
+    /**
      * Execute parse and return the resulting function node.
      * Errors will be thrown and the error manager will contain information
      * if parsing should fail
@@ -280,9 +315,7 @@
             lexer.line = lexer.pendingLine = lineOffset + 1;
             line = lineOffset;
 
-            // Set up first token (skips opening EOL.)
-            k = -1;
-            next();
+            scanFirstToken();
             // Begin parse.
             return program(scriptName, allowPropertyFunction);
         } catch (final Exception e) {
@@ -301,6 +334,44 @@
     }
 
     /**
+     * Parse and return the resulting module.
+     * Errors will be thrown and the error manager will contain information
+     * if parsing should fail
+     *
+     * @param moduleName name for the module, given to the parsed FunctionNode
+     * @param startPos start position in source
+     * @param len length of parse
+     *
+     * @return function node resulting from successful parse
+     */
+    public FunctionNode parseModule(final String moduleName, final int startPos, final int len) {
+        try {
+            stream = new TokenStream();
+            lexer  = new Lexer(source, startPos, len, stream, scripting && !env._no_syntax_extensions, env._es6, reparsedFunction != null);
+            lexer.line = lexer.pendingLine = lineOffset + 1;
+            line = lineOffset;
+
+            scanFirstToken();
+            // Begin parse.
+            return module(moduleName);
+        } catch (final Exception e) {
+            handleParseException(e);
+
+            return null;
+        }
+    }
+
+    /**
+     * Entry point for parsing a module.
+     *
+     * @param moduleName the module name
+     * @return the parsed module
+     */
+    public FunctionNode parseModule(final String moduleName) {
+        return parseModule(moduleName, 0, source.getLength());
+    }
+
+    /**
      * Parse and return the list of function parameter list. A comma
      * separated list of function parameter identifiers is expected to be parsed.
      * Errors will be thrown and the error manager will contain information
@@ -314,11 +385,9 @@
             stream = new TokenStream();
             lexer  = new Lexer(source, stream, scripting && !env._no_syntax_extensions, env._es6);
 
-            // Set up first token (skips opening EOL.)
-            k = -1;
-            next();
-
-            return formalParameterList(TokenType.EOF);
+            scanFirstToken();
+
+            return formalParameterList(TokenType.EOF, false);
         } catch (final Exception e) {
             handleParseException(e);
             return null;
@@ -339,9 +408,7 @@
             lexer  = new Lexer(source, stream, scripting && !env._no_syntax_extensions, env._es6);
             final int functionLine = line;
 
-            // Set up first token (skips opening EOL.)
-            k = -1;
-            next();
+            scanFirstToken();
 
             // Make a fake token for the function.
             final long functionToken = Token.toDesc(FUNCTION, 0, source.getLength());
@@ -432,7 +499,7 @@
         }
 
         // Skip to a recovery point.
-loop:
+        loop:
         while (true) {
             switch (type) {
             case EOF:
@@ -474,7 +541,7 @@
         sb.append(ident.getName());
 
         final String name = namespace.uniqueName(sb.toString());
-        assert parentFunction != null || name.equals(PROGRAM.symbolName()) || name.startsWith(RecompilableScriptFunctionData.RECOMPILATION_PREFIX) : "name = " + name;
+        assert parentFunction != null || name.equals(PROGRAM.symbolName()) : "name = " + name;
 
         int flags = 0;
         if (isStrictMode) {
@@ -489,7 +556,8 @@
         return functionNode;
     }
 
-    private FunctionNode createFunctionNode(final ParserContextFunctionNode function, final long startToken, final IdentNode ident, final List<IdentNode> parameters, final FunctionNode.Kind kind, final int functionLine, final Block body){
+    private FunctionNode createFunctionNode(final ParserContextFunctionNode function, final long startToken, final IdentNode ident, final List<IdentNode> parameters, final FunctionNode.Kind kind, final int functionLine, final Block body) {
+        // assert body.isFunctionBody() || body.getFlag(Block.IS_PARAMETER_BLOCK) && ((BlockStatement) body.getLastStatement()).getBlock().isFunctionBody();
         // Start new block.
         final FunctionNode functionNode =
             new FunctionNode(
@@ -506,7 +574,9 @@
                 kind,
                 function.getFlags(),
                 body,
-                function.getEndParserState());
+                function.getEndParserState(),
+                function.getModule(),
+                function.getDebugFlags());
 
         printAST(functionNode);
 
@@ -544,23 +614,39 @@
             expect(RBRACE);
         }
 
-        final int flags = newBlock.getFlags() | (needsBraces? 0 : Block.IS_SYNTHETIC);
+        final int flags = newBlock.getFlags() | (needsBraces ? 0 : Block.IS_SYNTHETIC);
         return new Block(blockToken, finish, flags, newBlock.getStatements());
     }
 
+    /**
+     * Get the statements in a case clause.
+     */
+    private List<Statement> caseStatementList() {
+        final ParserContextBlockNode newBlock = newBlock();
+        try {
+            statementList();
+        } finally {
+            restoreBlock(newBlock);
+        }
+        return newBlock.getStatements();
+    }
 
     /**
      * Get all the statements generated by a single statement.
      * @return Statements.
      */
     private Block getStatement() {
+        return getStatement(false);
+    }
+
+    private Block getStatement(boolean labelledStatement) {
         if (type == LBRACE) {
             return getBlock(true);
         }
         // Set up new block. Captures first token.
         final ParserContextBlockNode newBlock = newBlock();
         try {
-            statement(false, false, true);
+            statement(false, false, true, labelledStatement);
         } finally {
             restoreBlock(newBlock);
         }
@@ -576,6 +662,9 @@
 
         if (EVAL.symbolName().equals(name)) {
             markEval(lc);
+        } else if (SUPER.getName().equals(name)) {
+            assert ident.isDirectSuper();
+            markSuperCall(lc);
         }
     }
 
@@ -585,7 +674,8 @@
      */
     private void detectSpecialProperty(final IdentNode ident) {
         if (isArguments(ident)) {
-            lc.getCurrentFunction().setFlag(FunctionNode.USES_ARGUMENTS);
+            // skip over arrow functions, e.g. function f() { return (() => arguments.length)(); }
+            getCurrentNonArrowFunction().setFlag(FunctionNode.USES_ARGUMENTS);
         }
     }
 
@@ -593,11 +683,15 @@
         return env._es6;
     }
 
+    private boolean isES6() {
+        return env._es6;
+    }
+
     private static boolean isArguments(final String name) {
         return ARGUMENTS_NAME.equals(name);
     }
 
-    private static boolean isArguments(final IdentNode ident) {
+    static boolean isArguments(final IdentNode ident) {
         return isArguments(ident.getName());
     }
 
@@ -634,20 +728,20 @@
         case ASSIGN_SHL:
         case ASSIGN_SHR:
         case ASSIGN_SUB:
-            if (!(lhs instanceof AccessNode ||
-                  lhs instanceof IndexNode ||
-                  lhs instanceof IdentNode)) {
-                return referenceError(lhs, rhs, env._early_lvalue_error);
-            }
-
             if (lhs instanceof IdentNode) {
                 if (!checkIdentLValue((IdentNode)lhs)) {
                     return referenceError(lhs, rhs, false);
                 }
-                verifyStrictIdent((IdentNode)lhs, "assignment");
+                verifyIdent((IdentNode)lhs, "assignment");
+                break;
+            } else if (lhs instanceof AccessNode || lhs instanceof IndexNode) {
+                break;
+            } else if (opType == ASSIGN && isDestructuringLhs(lhs)) {
+                verifyDestructuringAssignmentPattern(lhs, "assignment");
+                break;
+            } else {
+                return referenceError(lhs, rhs, env._early_lvalue_error);
             }
-            break;
-
         default:
             break;
         }
@@ -659,6 +753,114 @@
         return new BinaryNode(op, lhs, rhs);
     }
 
+    private boolean isDestructuringLhs(Expression lhs) {
+        if (lhs instanceof ObjectNode || lhs instanceof LiteralNode.ArrayLiteralNode) {
+            return isES6();
+        }
+        return false;
+    }
+
+    private void verifyDestructuringAssignmentPattern(Expression pattern, String contextString) {
+        assert pattern instanceof ObjectNode || pattern instanceof LiteralNode.ArrayLiteralNode;
+        pattern.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
+            @Override
+            public boolean enterLiteralNode(LiteralNode<?> literalNode) {
+                if (literalNode.isArray()) {
+                    boolean restElement = false;
+                    for (Expression element : literalNode.getElementExpressions()) {
+                        if (element != null) {
+                            if (restElement) {
+                                throw error(String.format("Unexpected element after rest element"), element.getToken());
+                            }
+                            if (element.isTokenType(SPREAD_ARRAY)) {
+                                restElement = true;
+                                Expression lvalue = ((UnaryNode) element).getExpression();
+                                if (!checkValidLValue(lvalue, contextString)) {
+                                    throw error(AbstractParser.message("invalid.lvalue"), lvalue.getToken());
+                                }
+                            }
+                            element.accept(this);
+                        }
+                    }
+                    return false;
+                } else {
+                    return enterDefault(literalNode);
+                }
+            }
+
+            @Override
+            public boolean enterObjectNode(ObjectNode objectNode) {
+                return true;
+            }
+
+            @Override
+            public boolean enterPropertyNode(PropertyNode propertyNode) {
+                if (propertyNode.getValue() != null) {
+                    propertyNode.getValue().accept(this);
+                    return false;
+                } else {
+                    return enterDefault(propertyNode);
+                }
+            }
+
+            @Override
+            public boolean enterIdentNode(IdentNode identNode) {
+                verifyIdent(identNode, contextString);
+                if (!checkIdentLValue(identNode)) {
+                    referenceError(identNode, null, true);
+                    return false;
+                }
+                return false;
+            }
+
+            @Override
+            public boolean enterAccessNode(AccessNode accessNode) {
+                return false;
+            }
+
+            @Override
+            public boolean enterIndexNode(IndexNode indexNode) {
+                return false;
+            }
+
+            @Override
+            public boolean enterBinaryNode(BinaryNode binaryNode) {
+                if (binaryNode.isTokenType(ASSIGN)) {
+                    binaryNode.lhs().accept(this);
+                    // Initializer(rhs) can be any AssignmentExpression
+                    return false;
+                } else {
+                    return enterDefault(binaryNode);
+                }
+            }
+
+            @Override
+            public boolean enterUnaryNode(UnaryNode unaryNode) {
+                if (unaryNode.isTokenType(SPREAD_ARRAY)) {
+                    // rest element
+                    return true;
+                } else {
+                    return enterDefault(unaryNode);
+                }
+            }
+
+            @Override
+            protected boolean enterDefault(Node node) {
+                throw error(String.format("unexpected node in AssignmentPattern: %s", node));
+            }
+        });
+    }
+
+    private static Expression newBinaryExpression(final long op, final Expression lhs, final Expression rhs) {
+        final TokenType opType = Token.descType(op);
+
+        // Build up node.
+        if (BinaryNode.isLogical(opType)) {
+            return new BinaryNode(op, new JoinPredecessorExpression(lhs), new JoinPredecessorExpression(rhs));
+        }
+        return new BinaryNode(op, lhs, rhs);
+    }
+
 
     /**
      * Reduce increment/decrement to simpler operations.
@@ -717,7 +919,7 @@
 
         restoreBlock(body);
         body.setFlag(Block.NEEDS_SCOPE);
-        final Block programBody = new Block(functionToken, finish, body.getFlags() | Block.IS_SYNTHETIC, body.getStatements());
+        final Block programBody = new Block(functionToken, finish, body.getFlags() | Block.IS_SYNTHETIC | Block.IS_BODY, body.getStatements());
         lc.pop(script);
         script.setLastToken(token);
 
@@ -776,7 +978,7 @@
 
                 try {
                     // Get the next element.
-                    statement(true, allowPropertyFunction, false);
+                    statement(true, allowPropertyFunction, false, false);
                     allowPropertyFunction = false;
 
                     // check for directive prologues
@@ -816,16 +1018,16 @@
 
                                     // verify that function name as well as parameter names
                                     // satisfy strict mode restrictions.
-                                    verifyStrictIdent(function.getIdent(), "function name");
+                                    verifyIdent(function.getIdent(), "function name");
                                     for (final IdentNode param : function.getParameters()) {
-                                        verifyStrictIdent(param, "function parameter");
+                                        verifyIdent(param, "function parameter");
                                     }
                                 }
                             } else if (Context.DEBUG) {
-                                final int flag = FunctionNode.getDirectiveFlag(directive);
-                                if (flag != 0) {
+                                final int debugFlag = FunctionNode.getDirectiveFlag(directive);
+                                if (debugFlag != 0) {
                                     final ParserContextFunctionNode function = lc.getCurrentFunction();
-                                    function.setFlag(flag);
+                                    function.setDebugFlag(debugFlag);
                                 }
                             }
                         }
@@ -849,29 +1051,53 @@
     }
 
     /**
+     * Parse any of the basic statement types.
+     *
      * Statement :
-     *      Block
+     *      BlockStatement
      *      VariableStatement
      *      EmptyStatement
      *      ExpressionStatement
      *      IfStatement
-     *      IterationStatement
+     *      BreakableStatement
      *      ContinueStatement
      *      BreakStatement
      *      ReturnStatement
      *      WithStatement
      *      LabelledStatement
-     *      SwitchStatement
      *      ThrowStatement
      *      TryStatement
      *      DebuggerStatement
      *
-     * see 12
+     * BreakableStatement :
+     *      IterationStatement
+     *      SwitchStatement
+     *
+     * BlockStatement :
+     *      Block
+     *
+     * Block :
+     *      { StatementList opt }
      *
-     * Parse any of the basic statement types.
+     * StatementList :
+     *      StatementListItem
+     *      StatementList StatementListItem
+     *
+     * StatementItem :
+     *      Statement
+     *      Declaration
+     *
+     * Declaration :
+     *     HoistableDeclaration
+     *     ClassDeclaration
+     *     LexicalDeclaration
+     *
+     * HoistableDeclaration :
+     *     FunctionDeclaration
+     *     GeneratorDeclaration
      */
     private void statement() {
-        statement(false, false, false);
+        statement(false, false, false, false);
     }
 
     /**
@@ -879,14 +1105,7 @@
      * @param allowPropertyFunction allow property "get" and "set" functions?
      * @param singleStatement are we in a single statement context?
      */
-    private void statement(final boolean topLevel, final boolean allowPropertyFunction, final boolean singleStatement) {
-        if (type == FUNCTION) {
-            // As per spec (ECMA section 12), function declarations as arbitrary statement
-            // is not "portable". Implementation can issue a warning or disallow the same.
-            functionExpression(true, topLevel);
-            return;
-        }
-
+    private void statement(final boolean topLevel, final boolean allowPropertyFunction, final boolean singleStatement, final boolean labelledStatement) {
         switch (type) {
         case LBRACE:
             block();
@@ -918,9 +1137,6 @@
         case RETURN:
             returnStatement();
             break;
-        case YIELD:
-            yieldStatement();
-            break;
         case WITH:
             withStatement();
             break;
@@ -941,13 +1157,32 @@
         case EOF:
             expect(SEMICOLON);
             break;
+        case FUNCTION:
+            // As per spec (ECMA section 12), function declarations as arbitrary statement
+            // is not "portable". Implementation can issue a warning or disallow the same.
+            if (singleStatement) {
+                // ES6 B.3.2 Labelled Function Declarations
+                // It is a Syntax Error if any strict mode source code matches this rule:
+                // LabelledItem : FunctionDeclaration.
+                if (!labelledStatement || isStrictMode) {
+                    throw error(AbstractParser.message("expected.stmt", "function declaration"), token);
+                }
+            }
+            functionExpression(true, topLevel || labelledStatement);
+            return;
         default:
-            if (useBlockScope() && (type == LET || type == CONST)) {
+            if (useBlockScope() && (type == LET && lookaheadIsLetDeclaration(false) || type == CONST)) {
                 if (singleStatement) {
                     throw error(AbstractParser.message("expected.stmt", type.getName() + " declaration"), token);
                 }
                 variableStatement(type);
                 break;
+            } else if (type == CLASS && isES6()) {
+                if (singleStatement) {
+                    throw error(AbstractParser.message("expected.stmt", "class declaration"), token);
+                }
+                classDeclaration(false);
+                break;
             }
             if (env._const_as_var && type == CONST) {
                 variableStatement(TokenType.VAR);
@@ -963,11 +1198,11 @@
                     final String ident = (String)getValue();
                     final long propertyToken = token;
                     final int propertyLine = line;
-                    if("get".equals(ident)) {
+                    if ("get".equals(ident)) {
                         next();
                         addPropertyFunctionStatement(propertyGetterFunction(propertyToken, propertyLine));
                         return;
-                    } else if("set".equals(ident)) {
+                    } else if ("set".equals(ident)) {
                         next();
                         addPropertyFunctionStatement(propertySetterFunction(propertyToken, propertyLine));
                         return;
@@ -986,6 +1221,267 @@
     }
 
     /**
+     * ClassDeclaration[Yield, Default] :
+     *   class BindingIdentifier[?Yield] ClassTail[?Yield]
+     *   [+Default] class ClassTail[?Yield]
+     */
+    private ClassNode classDeclaration(boolean isDefault) {
+        int classLineNumber = line;
+
+        ClassNode classExpression = classExpression(!isDefault);
+
+        if (!isDefault) {
+            VarNode classVar = new VarNode(classLineNumber, classExpression.getToken(), classExpression.getIdent().getFinish(), classExpression.getIdent(), classExpression, VarNode.IS_CONST);
+            appendStatement(classVar);
+        }
+        return classExpression;
+    }
+
+    /**
+     * ClassExpression[Yield] :
+     *   class BindingIdentifier[?Yield]opt ClassTail[?Yield]
+     */
+    private ClassNode classExpression(boolean isStatement) {
+        assert type == CLASS;
+        int classLineNumber = line;
+        long classToken = token;
+        next();
+
+        IdentNode className = null;
+        if (isStatement || type == IDENT) {
+            className = getIdent();
+        }
+
+        return classTail(classLineNumber, classToken, className);
+    }
+
+    private static final class ClassElementKey {
+        private final boolean isStatic;
+        private final String propertyName;
+
+        private ClassElementKey(boolean isStatic, String propertyName) {
+            this.isStatic = isStatic;
+            this.propertyName = propertyName;
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + (isStatic ? 1231 : 1237);
+            result = prime * result + ((propertyName == null) ? 0 : propertyName.hashCode());
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof ClassElementKey) {
+                ClassElementKey other = (ClassElementKey) obj;
+                return this.isStatic == other.isStatic && Objects.equals(this.propertyName, other.propertyName);
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Parse ClassTail and ClassBody.
+     *
+     * ClassTail[Yield] :
+     *   ClassHeritage[?Yield]opt { ClassBody[?Yield]opt }
+     * ClassHeritage[Yield] :
+     *   extends LeftHandSideExpression[?Yield]
+     *
+     * ClassBody[Yield] :
+     *   ClassElementList[?Yield]
+     * ClassElementList[Yield] :
+     *   ClassElement[?Yield]
+     *   ClassElementList[?Yield] ClassElement[?Yield]
+     * ClassElement[Yield] :
+     *   MethodDefinition[?Yield]
+     *   static MethodDefinition[?Yield]
+     *   ;
+     */
+    private ClassNode classTail(final int classLineNumber, final long classToken, final IdentNode className) {
+        final boolean oldStrictMode = isStrictMode;
+        isStrictMode = true;
+        try {
+            Expression classHeritage = null;
+            if (type == EXTENDS) {
+                next();
+                classHeritage = leftHandSideExpression();
+            }
+
+            expect(LBRACE);
+
+            PropertyNode constructor = null;
+            final ArrayList<PropertyNode> classElements = new ArrayList<>();
+            final Map<ClassElementKey, Integer> keyToIndexMap = new HashMap<>();
+            for (;;) {
+                if (type == SEMICOLON) {
+                    next();
+                    continue;
+                }
+                if (type == RBRACE) {
+                    break;
+                }
+                final long classElementToken = token;
+                boolean isStatic = false;
+                if (type == STATIC) {
+                    isStatic = true;
+                    next();
+                }
+                boolean generator = false;
+                if (isES6() && type == MUL) {
+                    generator = true;
+                    next();
+                }
+                final PropertyNode classElement = methodDefinition(isStatic, classHeritage != null, generator);
+                if (classElement.isComputed()) {
+                    classElements.add(classElement);
+                } else if (!classElement.isStatic() && classElement.getKeyName().equals("constructor")) {
+                    if (constructor == null) {
+                        constructor = classElement;
+                    } else {
+                        throw error(AbstractParser.message("multiple.constructors"), classElementToken);
+                    }
+                } else {
+                    // Check for duplicate method definitions and combine accessor methods.
+                    // In ES6, a duplicate is never an error regardless of strict mode (in consequence of computed property names).
+
+                    final ClassElementKey key = new ClassElementKey(classElement.isStatic(), classElement.getKeyName());
+                    final Integer existing = keyToIndexMap.get(key);
+
+                    if (existing == null) {
+                        keyToIndexMap.put(key, classElements.size());
+                        classElements.add(classElement);
+                    } else {
+                        final PropertyNode existingProperty = classElements.get(existing);
+
+                        final Expression   value  = classElement.getValue();
+                        final FunctionNode getter = classElement.getGetter();
+                        final FunctionNode setter = classElement.getSetter();
+
+                        if (value != null || existingProperty.getValue() != null) {
+                            keyToIndexMap.put(key, classElements.size());
+                            classElements.add(classElement);
+                        } else if (getter != null) {
+                            assert existingProperty.getGetter() != null || existingProperty.getSetter() != null;
+                            classElements.set(existing, existingProperty.setGetter(getter));
+                        } else if (setter != null) {
+                            assert existingProperty.getGetter() != null || existingProperty.getSetter() != null;
+                            classElements.set(existing, existingProperty.setSetter(setter));
+                        }
+                    }
+                }
+            }
+
+            final long lastToken = token;
+            expect(RBRACE);
+
+            if (constructor == null) {
+                constructor = createDefaultClassConstructor(classLineNumber, classToken, lastToken, className, classHeritage != null);
+            }
+
+            classElements.trimToSize();
+            return new ClassNode(classLineNumber, classToken, finish, className, classHeritage, constructor, classElements);
+        } finally {
+            isStrictMode = oldStrictMode;
+        }
+    }
+
+    private PropertyNode createDefaultClassConstructor(int classLineNumber, long classToken, long lastToken, IdentNode className, boolean subclass) {
+        final int ctorFinish = finish;
+        final List<Statement> statements;
+        final List<IdentNode> parameters;
+        final long identToken = Token.recast(classToken, TokenType.IDENT);
+        if (subclass) {
+            final IdentNode superIdent = createIdentNode(identToken, ctorFinish, SUPER.getName()).setIsDirectSuper();
+            final IdentNode argsIdent = createIdentNode(identToken, ctorFinish, "args").setIsRestParameter();
+            final Expression spreadArgs = new UnaryNode(Token.recast(classToken, TokenType.SPREAD_ARGUMENT), argsIdent);
+            final CallNode superCall = new CallNode(classLineNumber, classToken, ctorFinish, superIdent, Collections.singletonList(spreadArgs), false);
+            statements = Collections.singletonList(new ExpressionStatement(classLineNumber, classToken, ctorFinish, superCall));
+            parameters = Collections.singletonList(argsIdent);
+        } else {
+            statements = Collections.emptyList();
+            parameters = Collections.emptyList();
+        }
+
+        final Block body = new Block(classToken, ctorFinish, Block.IS_BODY, statements);
+        final IdentNode ctorName = className != null ? className : createIdentNode(identToken, ctorFinish, "constructor");
+        final ParserContextFunctionNode function = createParserContextFunctionNode(ctorName, classToken, FunctionNode.Kind.NORMAL, classLineNumber, parameters);
+        function.setLastToken(lastToken);
+
+        function.setFlag(FunctionNode.ES6_IS_METHOD);
+        function.setFlag(FunctionNode.ES6_IS_CLASS_CONSTRUCTOR);
+        if (subclass) {
+            function.setFlag(FunctionNode.ES6_IS_SUBCLASS_CONSTRUCTOR);
+            function.setFlag(FunctionNode.ES6_HAS_DIRECT_SUPER);
+        }
+        if (className == null) {
+            function.setFlag(FunctionNode.IS_ANONYMOUS);
+        }
+
+        final PropertyNode constructor = new PropertyNode(classToken, ctorFinish, ctorName, createFunctionNode(
+                        function,
+                        classToken,
+                        ctorName,
+                        parameters,
+                        FunctionNode.Kind.NORMAL,
+                        classLineNumber,
+                        body
+                        ), null, null, false, false);
+        return constructor;
+    }
+
+    private PropertyNode methodDefinition(final boolean isStatic, final boolean subclass, final boolean generator) {
+        final long methodToken = token;
+        final int methodLine = line;
+        final boolean computed = type == LBRACKET;
+        final boolean isIdent = type == IDENT;
+        final Expression propertyName = propertyName();
+        int flags = FunctionNode.ES6_IS_METHOD;
+        if (!computed) {
+            final String name = ((PropertyKey)propertyName).getPropertyName();
+            if (!generator && isIdent && type != LPAREN && name.equals("get")) {
+                final PropertyFunction methodDefinition = propertyGetterFunction(methodToken, methodLine, flags);
+                verifyAllowedMethodName(methodDefinition.key, isStatic, methodDefinition.computed, generator, true);
+                return new PropertyNode(methodToken, finish, methodDefinition.key, null, methodDefinition.functionNode, null, isStatic, methodDefinition.computed);
+            } else if (!generator && isIdent && type != LPAREN && name.equals("set")) {
+                final PropertyFunction methodDefinition = propertySetterFunction(methodToken, methodLine, flags);
+                verifyAllowedMethodName(methodDefinition.key, isStatic, methodDefinition.computed, generator, true);
+                return new PropertyNode(methodToken, finish, methodDefinition.key, null, null, methodDefinition.functionNode, isStatic, methodDefinition.computed);
+            } else {
+                if (!isStatic && !generator && name.equals("constructor")) {
+                    flags |= FunctionNode.ES6_IS_CLASS_CONSTRUCTOR;
+                    if (subclass) {
+                        flags |= FunctionNode.ES6_IS_SUBCLASS_CONSTRUCTOR;
+                    }
+                }
+                verifyAllowedMethodName(propertyName, isStatic, computed, generator, false);
+            }
+        }
+        final PropertyFunction methodDefinition = propertyMethodFunction(propertyName, methodToken, methodLine, generator, flags, computed);
+        return new PropertyNode(methodToken, finish, methodDefinition.key, methodDefinition.functionNode, null, null, isStatic, computed);
+    }
+
+    /**
+     * ES6 14.5.1 Static Semantics: Early Errors.
+     */
+    private void verifyAllowedMethodName(final Expression key, final boolean isStatic, final boolean computed, final boolean generator, final boolean accessor) {
+        if (!computed) {
+            if (!isStatic && generator && ((PropertyKey) key).getPropertyName().equals("constructor")) {
+                throw error(AbstractParser.message("generator.constructor"), key.getToken());
+            }
+            if (!isStatic && accessor && ((PropertyKey) key).getPropertyName().equals("constructor")) {
+                throw error(AbstractParser.message("accessor.constructor"), key.getToken());
+            }
+            if (isStatic && ((PropertyKey) key).getPropertyName().equals("prototype")) {
+                throw error(AbstractParser.message("static.prototype.method"), key.getToken());
+            }
+        }
+    }
+
+    /**
      * block :
      *      { StatementList? }
      *
@@ -1008,7 +1504,7 @@
      */
     private void statementList() {
         // Accumulate statements until end of list. */
-loop:
+        loop:
         while (type != EOF) {
             switch (type) {
             case EOF:
@@ -1026,6 +1522,22 @@
     }
 
     /**
+     * Make sure that the identifier name used is allowed.
+     *
+     * @param ident         Identifier that is verified
+     * @param contextString String used in error message to give context to the user
+     */
+    private void verifyIdent(final IdentNode ident, final String contextString) {
+        verifyStrictIdent(ident, contextString);
+        if (isES6()) {
+            final TokenType tokenType = TokenLookup.lookupKeyword(ident.getName().toCharArray(), 0, ident.getName().length());
+            if (tokenType != IDENT && tokenType.getKind() != TokenKind.FUTURESTRICT) {
+                throw error(expectMessage(IDENT));
+            }
+        }
+    }
+
+    /**
      * Make sure that in strict mode, the identifier name used is allowed.
      *
      * @param ident         Identifier that is verified
@@ -1066,15 +1578,16 @@
      * Parse a VAR statement.
      * @param isStatement True if a statement (not used in a FOR.)
      */
-    private List<VarNode> variableStatement(final TokenType varType) {
-        return variableStatement(varType, true, -1);
+    private void variableStatement(final TokenType varType) {
+        variableDeclarationList(varType, true, -1);
     }
 
-    private List<VarNode> variableStatement(final TokenType varType, final boolean isStatement, final int sourceOrder) {
+    private List<Expression> variableDeclarationList(final TokenType varType, final boolean isStatement, final int sourceOrder) {
         // VAR tested in caller.
+        assert varType == VAR || varType == LET || varType == CONST;
         next();
 
-        final List<VarNode> vars = new ArrayList<>();
+        final List<Expression> bindings = new ArrayList<>();
         int varFlags = 0;
         if (varType == LET) {
             varFlags |= VarNode.IS_LET;
@@ -1082,13 +1595,29 @@
             varFlags |= VarNode.IS_CONST;
         }
 
+        Expression missingAssignment = null;
         while (true) {
             // Get starting token.
             final int  varLine  = line;
             final long varToken = token;
             // Get name of var.
-            final IdentNode name = getIdent();
-            verifyStrictIdent(name, "variable name");
+            if (type == YIELD && inGeneratorFunction()) {
+                expect(IDENT);
+            }
+
+            final String contextString = "variable name";
+            Expression binding = bindingIdentifierOrPattern(contextString);
+            final boolean isDestructuring = !(binding instanceof IdentNode);
+            if (isDestructuring) {
+                final int finalVarFlags = varFlags;
+                verifyDestructuringBindingPattern(binding, new Consumer<IdentNode>() {
+                    public void accept(final IdentNode identNode) {
+                        verifyIdent(identNode, contextString);
+                        final VarNode var = new VarNode(varLine, varToken, sourceOrder, identNode.getFinish(), identNode.setIsDeclaredHere(), null, finalVarFlags);
+                        appendStatement(var);
+                    }
+                });
+            }
 
             // Assume no init.
             Expression init = null;
@@ -1098,22 +1627,53 @@
                 next();
 
                 // Get initializer expression. Suppress IN if not statement.
-                defaultNames.push(name);
+                if (!isDestructuring) {
+                    defaultNames.push(binding);
+                }
                 try {
                     init = assignmentExpression(!isStatement);
                 } finally {
-                    defaultNames.pop();
+                    if (!isDestructuring) {
+                        defaultNames.pop();
+                    }
                 }
-            } else if (varType == CONST && isStatement) {
-                throw error(AbstractParser.message("missing.const.assignment", name.getName()));
+            } else if (isStatement) {
+                if (isDestructuring) {
+                    throw error(AbstractParser.message("missing.destructuring.assignment"), token);
+                } else if (varType == CONST) {
+                    throw error(AbstractParser.message("missing.const.assignment", ((IdentNode)binding).getName()));
+                }
+                // else, if we are in a for loop, delay checking until we know the kind of loop
             }
 
-            // Only set declaration flag on lexically scoped let/const as it adds runtime overhead.
-            final IdentNode actualName = varType == LET || varType == CONST ? name.setIsDeclaredHere() : name;
-            // Allocate var node.
-            final VarNode var = new VarNode(varLine, varToken, sourceOrder, finish, actualName, init, varFlags);
-            vars.add(var);
-            appendStatement(var);
+            if (!isDestructuring) {
+                assert init != null || varType != CONST || !isStatement;
+                final IdentNode ident = (IdentNode)binding;
+                if (!isStatement && ident.getName().equals("let")) {
+                    throw error(AbstractParser.message("let.binding.for")); //ES6 13.7.5.1
+                }
+                // Only set declaration flag on lexically scoped let/const as it adds runtime overhead.
+                final IdentNode name = varType == LET || varType == CONST ? ident.setIsDeclaredHere() : ident;
+                binding = name;
+                final VarNode var = new VarNode(varLine, varToken, sourceOrder, finish, name, init, varFlags);
+                appendStatement(var);
+                if (init == null && varType == CONST) {
+                    if (missingAssignment == null) {
+                        missingAssignment = binding;
+                    }
+                }
+            } else {
+                assert init != null || !isStatement;
+                binding = init == null ? binding : verifyAssignment(Token.recast(varToken, ASSIGN), binding, init);
+                if (isStatement) {
+                    appendStatement(new ExpressionStatement(varLine, binding.getToken(), finish, binding));
+                } else if (init == null) {
+                    if (missingAssignment == null) {
+                        missingAssignment = binding;
+                    }
+                }
+            }
+            bindings.add(binding);
 
             if (type != COMMARIGHT) {
                 break;
@@ -1124,9 +1684,128 @@
         // If is a statement then handle end of line.
         if (isStatement) {
             endOfLine();
+        } else {
+            if (type == SEMICOLON) {
+                // late check for missing assignment, now we know it's a for (init; test; modify) loop
+                if (missingAssignment != null) {
+                    if (missingAssignment instanceof IdentNode) {
+                        throw error(AbstractParser.message("missing.const.assignment", ((IdentNode)missingAssignment).getName()));
+                    } else {
+                        throw error(AbstractParser.message("missing.destructuring.assignment"), missingAssignment.getToken());
+                    }
+                }
+            }
         }
 
-        return vars;
+        return bindings;
+    }
+
+    private boolean isBindingIdentifier() {
+        return type == IDENT || isNonStrictModeIdent();
+    }
+
+    private IdentNode bindingIdentifier(final String contextString) {
+        final IdentNode name = getIdent();
+        verifyIdent(name, contextString);
+        return name;
+    }
+
+    private Expression bindingPattern() {
+        if (type == LBRACKET) {
+            return arrayLiteral();
+        } else if (type == LBRACE) {
+            return objectLiteral();
+        } else {
+            throw error(AbstractParser.message("expected.binding"));
+        }
+    }
+
+    private Expression bindingIdentifierOrPattern(final String contextString) {
+        if (isBindingIdentifier() || !isES6()) {
+            return bindingIdentifier(contextString);
+        } else {
+            return bindingPattern();
+        }
+    }
+
+    /**
+     * Verify destructuring variable declaration binding pattern and extract bound variable declarations.
+     */
+    private void verifyDestructuringBindingPattern(final Expression pattern, final Consumer<IdentNode> identifierCallback) {
+        assert pattern instanceof ObjectNode || pattern instanceof LiteralNode.ArrayLiteralNode;
+        pattern.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
+            @Override
+            public boolean enterLiteralNode(final LiteralNode<?> literalNode) {
+                if (literalNode.isArray()) {
+                    boolean restElement = false;
+                    for (final Expression element : literalNode.getElementExpressions()) {
+                        if (restElement) {
+                            throw error(String.format("Unexpected element after rest element"), element.getToken());
+                        }
+                        if (element != null) {
+                            if (element.isTokenType(SPREAD_ARRAY)) {
+                                restElement = true;
+                                if (!(((UnaryNode) element).getExpression() instanceof IdentNode)) {
+                                    throw error(String.format("Expected a valid binding identifier"), element.getToken());
+
+                                }
+                            }
+                            element.accept(this);
+                        }
+                    }
+                    return false;
+                } else {
+                    return enterDefault(literalNode);
+                }
+            }
+
+            @Override
+            public boolean enterObjectNode(final ObjectNode objectNode) {
+                return true;
+            }
+
+            @Override
+            public boolean enterPropertyNode(final PropertyNode propertyNode) {
+                if (propertyNode.getValue() != null) {
+                    propertyNode.getValue().accept(this);
+                    return false;
+                } else {
+                    return enterDefault(propertyNode);
+                }
+            }
+
+            @Override
+            public boolean enterIdentNode(final IdentNode identNode) {
+                identifierCallback.accept(identNode);
+                return false;
+            }
+
+            @Override
+            public boolean enterBinaryNode(final BinaryNode binaryNode) {
+                if (binaryNode.isTokenType(ASSIGN)) {
+                    binaryNode.lhs().accept(this);
+                    // Initializer(rhs) can be any AssignmentExpression
+                    return false;
+                } else {
+                    return enterDefault(binaryNode);
+                }
+            }
+
+            @Override
+            public boolean enterUnaryNode(final UnaryNode unaryNode) {
+                if (unaryNode.isTokenType(SPREAD_ARRAY)) {
+                    // rest element
+                    return true;
+                } else {
+                    return enterDefault(unaryNode);
+                }
+            }
+
+            @Override
+            protected boolean enterDefault(final Node node) {
+                throw error(String.format("unexpected node in BindingPattern: %s", node));
+            }
+        });
     }
 
     /**
@@ -1230,7 +1909,7 @@
         final ParserContextLoopNode forNode = new ParserContextLoopNode();
         lc.push(forNode);
         Block body = null;
-        List<VarNode> vars = null;
+        List<Expression> vars = null;
         Expression init = null;
         JoinPredecessorExpression test = null;
         JoinPredecessorExpression modify = null;
@@ -1254,20 +1933,20 @@
             switch (type) {
             case VAR:
                 // Var declaration captured in for outer block.
-                vars = variableStatement(type, false, forStart);
+                vars = variableDeclarationList(type, false, forStart);
                 break;
             case SEMICOLON:
                 break;
             default:
-                if (useBlockScope() && (type == LET || type == CONST)) {
+                if (useBlockScope() && (type == LET && lookaheadIsLetDeclaration(true) || type == CONST)) {
                     flags |= ForNode.PER_ITERATION_SCOPE;
                     // LET/CONST declaration captured in container block created above.
-                    vars = variableStatement(type, false, forStart);
+                    vars = variableDeclarationList(type, false, forStart);
                     break;
                 }
                 if (env._const_as_var && type == CONST) {
                     // Var declaration captured in for outer block.
-                    vars = variableStatement(TokenType.VAR, false, forStart);
+                    vars = variableDeclarationList(TokenType.VAR, false, forStart);
                     break;
                 }
 
@@ -1309,7 +1988,11 @@
                 if (vars != null) {
                     // for (var i in obj)
                     if (vars.size() == 1) {
-                        init = new IdentNode(vars.get(0).getName());
+                        init = new IdentNode((IdentNode)vars.get(0));
+                        if (init.isTokenType(ASSIGN)) {
+                            throw error(AbstractParser.message("for.in.loop.initializer"), init.getToken());
+                        }
+                        assert init instanceof IdentNode || isDestructuringLhs(init);
                     } else {
                         // for (var i, j in obj) is invalid
                         throw error(AbstractParser.message("many.vars.in.for.in.loop", isForOf ? "of" : "in"), vars.get(1).getToken());
@@ -1351,10 +2034,9 @@
         } finally {
             lc.pop(forNode);
 
-            if (vars != null) {
-                for (final VarNode var : vars) {
-                    appendStatement(var);
-                }
+            for (final Statement var : forNode.getStatements()) {
+                assert var instanceof VarNode;
+                appendStatement(var);
             }
             if (body != null) {
                 appendStatement(new ForNode(forLine, forToken, body.getFinish(), body, (forNode.getFlags() | flags), init, test, modify));
@@ -1371,6 +2053,49 @@
         }
     }
 
+    private boolean checkValidLValue(final Expression init, final String contextString) {
+        if (init instanceof IdentNode) {
+            if (!checkIdentLValue((IdentNode)init)) {
+                return false;
+            }
+            verifyIdent((IdentNode)init, contextString);
+            return true;
+        } else if (init instanceof AccessNode || init instanceof IndexNode) {
+            return true;
+        } else if (isDestructuringLhs(init)) {
+            verifyDestructuringAssignmentPattern(init, contextString);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private boolean lookaheadIsLetDeclaration(final boolean ofContextualKeyword) {
+        assert type == LET;
+        for (int i = 1;; i++) {
+            TokenType t = T(k + i);
+            switch (t) {
+            case EOL:
+            case COMMENT:
+                continue;
+            case IDENT:
+                if (ofContextualKeyword && isES6() && "of".equals(getValue(getToken(k + i)))) {
+                    return false;
+                }
+                // fall through
+            case LBRACKET:
+            case LBRACE:
+                return true;
+            default:
+                // accept future strict tokens in non-strict mode (including LET)
+                if (!isStrictMode && t.getKind() == TokenKind.FUTURESTRICT) {
+                    return true;
+                }
+                return false;
+            }
+        }
+    }
+
     /**
      * ...IterationStatement :
      *           ...
@@ -1559,7 +2284,7 @@
      */
     private void returnStatement() {
         // check for return outside function
-        if (lc.getCurrentFunction().getKind() == FunctionNode.Kind.SCRIPT) {
+        if (lc.getCurrentFunction().getKind() == FunctionNode.Kind.SCRIPT || lc.getCurrentFunction().getKind() == FunctionNode.Kind.MODULE) {
             throw error(AbstractParser.message("invalid.return"));
         }
 
@@ -1591,39 +2316,61 @@
     }
 
     /**
-     * YieldStatement :
-     *      yield Expression? ; // [no LineTerminator here]
-     *
-     * JavaScript 1.8
+     * Parse YieldExpression.
      *
-     * Parse YIELD statement.
+     * YieldExpression[In] :
+     *   yield
+     *   yield [no LineTerminator here] AssignmentExpression[?In, Yield]
+     *   yield [no LineTerminator here] * AssignmentExpression[?In, Yield]
      */
-    private void yieldStatement() {
+    private Expression yieldExpression(final boolean noIn) {
+        assert inGeneratorFunction();
         // Capture YIELD token.
-        final int  yieldLine  = line;
-        final long yieldToken = token;
+        long yieldToken = token;
         // YIELD tested in caller.
+        assert type == YIELD;
         nextOrEOL();
 
         Expression expression = null;
 
-        // SEMICOLON or expression.
+        boolean yieldAsterisk = false;
+        if (type == MUL) {
+            yieldAsterisk = true;
+            yieldToken = Token.recast(yieldToken, YIELD_STAR);
+            next();
+        }
+
         switch (type) {
         case RBRACE:
         case SEMICOLON:
         case EOL:
         case EOF:
-            break;
+        case COMMARIGHT:
+        case RPAREN:
+        case RBRACKET:
+        case COLON:
+            if (!yieldAsterisk) {
+                // treat (yield) as (yield void 0)
+                expression = newUndefinedLiteral(yieldToken, finish);
+                if (type == EOL) {
+                    next();
+                }
+                break;
+            } else {
+                // AssignmentExpression required, fall through
+            }
 
         default:
-            expression = expression();
+            expression = assignmentExpression(noIn);
             break;
         }
 
-        endOfLine();
-
         // Construct and add YIELD node.
-        appendStatement(new ReturnNode(yieldLine, yieldToken, finish, expression));
+        return new UnaryNode(yieldToken, expression);
+    }
+
+    private static UnaryNode newUndefinedLiteral(final long token, final int finish) {
+        return new UnaryNode(Token.recast(token, VOID), LiteralNode.newInstance(token, finish, 0));
     }
 
     /**
@@ -1679,11 +2426,15 @@
     private void switchStatement() {
         final int  switchLine  = line;
         final long switchToken = token;
+
+        // Block to capture variables declared inside the switch statement.
+        final ParserContextBlockNode switchBlock = newBlock();
+
         // SWITCH tested in caller.
         next();
 
         // Create and add switch statement.
-        final ParserContextSwitchNode switchNode= new ParserContextSwitchNode();
+        final ParserContextSwitchNode switchNode = new ParserContextSwitchNode();
         lc.push(switchNode);
 
         CaseNode defaultCase = null;
@@ -1727,7 +2478,7 @@
                 expect(COLON);
 
                 // Get CASE body.
-                final Block statements = getBlock(false);
+                final Block statements = getBlock(false); // TODO: List<Statement> statements = caseStatementList();
                 final CaseNode caseNode = new CaseNode(caseToken, finish, caseExpression, statements);
 
                 if (caseExpression == null) {
@@ -1740,9 +2491,11 @@
             next();
         } finally {
             lc.pop(switchNode);
+            restoreBlock(switchBlock);
         }
 
-        appendStatement(new SwitchNode(switchLine, switchToken, finish, expression, cases, defaultCase));
+        final SwitchNode switchStatement = new SwitchNode(switchLine, switchToken, finish, expression, cases, defaultCase);
+        appendStatement(new BlockStatement(switchLine, new Block(switchToken, finish, switchBlock.getFlags() | Block.IS_SYNTHETIC | Block.IS_SWITCH_BLOCK, switchStatement)));
     }
 
     /**
@@ -1769,7 +2522,7 @@
         Block body = null;
         try {
             lc.push(labelNode);
-            body = getStatement();
+            body = getStatement(true);
         } finally {
             assert lc.peek() instanceof ParserContextLabelNode;
             lc.pop(labelNode);
@@ -1935,13 +2688,19 @@
     /**
      * PrimaryExpression :
      *      this
-     *      Identifier
+     *      IdentifierReference
      *      Literal
      *      ArrayLiteral
      *      ObjectLiteral
      *      RegularExpressionLiteral
      *      TemplateLiteral
+     *      CoverParenthesizedExpressionAndArrowParameterList
+     *
+     * CoverParenthesizedExpressionAndArrowParameterList :
      *      ( Expression )
+     *      ( )
+     *      ( ... BindingIdentifier )
+     *      ( Expression , ... BindingIdentifier )
      *
      * Parse primary expression.
      * @return Expression node.
@@ -1956,7 +2715,7 @@
         case THIS:
             final String name = type.getName();
             next();
-            lc.getCurrentFunction().setFlag(FunctionNode.USES_THIS);
+            markThis(lc);
             return new IdentNode(primaryToken, finish, name);
         case IDENT:
             final IdentNode ident = getIdent();
@@ -1997,6 +2756,22 @@
         case LPAREN:
             next();
 
+            if (isES6()) {
+                if (type == RPAREN) {
+                    // ()
+                    nextOrEOL();
+                    expectDontAdvance(ARROW);
+                    return new ExpressionList(primaryToken, finish, Collections.emptyList());
+                } else if (type == ELLIPSIS) {
+                    // (...rest)
+                    final IdentNode restParam = formalParameterList(false).get(0);
+                    expectDontAdvance(RPAREN);
+                    nextOrEOL();
+                    expectDontAdvance(ARROW);
+                    return new ExpressionList(primaryToken, finish, Collections.singletonList(restParam));
+                }
+            }
+
             final Expression expression = expression();
 
             expect(RPAREN);
@@ -2073,8 +2848,9 @@
         final List<Expression> elements = new ArrayList<>();
         // Track elisions.
         boolean elision = true;
-loop:
+        loop:
         while (true) {
+            long spreadToken = 0;
             switch (type) {
             case RBRACKET:
                 next();
@@ -2093,14 +2869,24 @@
 
                 break;
 
+            case ELLIPSIS:
+                if (isES6()) {
+                    spreadToken = token;
+                    next();
+                }
+                // fall through
+
             default:
                 if (!elision) {
                     throw error(AbstractParser.message("expected.comma", type.getNameOrType()));
                 }
+
                 // Add expression element.
-                final Expression expression = assignmentExpression(false);
-
+                Expression expression = assignmentExpression(false);
                 if (expression != null) {
+                    if (spreadToken != 0) {
+                        expression = new UnaryNode(Token.recast(spreadToken, SPREAD_ARRAY), expression);
+                    }
                     elements.add(expression);
                 } else {
                     expect(RBRACKET);
@@ -2141,7 +2927,7 @@
 
         // Create a block for the object literal.
         boolean commaSeen = true;
-loop:
+        loop:
         while (true) {
             switch (type) {
                 case RBRACE:
@@ -2164,6 +2950,12 @@
                     commaSeen = false;
                     // Get and add the next property.
                     final PropertyNode property = propertyAssignment();
+
+                    if (property.isComputed()) {
+                        elements.add(property);
+                        break;
+                    }
+
                     final String key = property.getKeyName();
                     final Integer existing = map.get(key);
 
@@ -2185,36 +2977,23 @@
                     final FunctionNode prevGetter = existingProperty.getGetter();
                     final FunctionNode prevSetter = existingProperty.getSetter();
 
-                    // ECMA 11.1.5 strict mode restrictions
-                    if (isStrictMode && value != null && prevValue != null) {
-                        throw error(AbstractParser.message("property.redefinition", key), property.getToken());
-                    }
-
-                    final boolean isPrevAccessor = prevGetter != null || prevSetter != null;
-                    final boolean isAccessor     = getter != null     || setter != null;
-
-                    // data property redefined as accessor property
-                    if (prevValue != null && isAccessor) {
-                        throw error(AbstractParser.message("property.redefinition", key), property.getToken());
-                    }
-
-                    // accessor property redefined as data
-                    if (isPrevAccessor && value != null) {
-                        throw error(AbstractParser.message("property.redefinition", key), property.getToken());
-                    }
-
-                    if (isAccessor && isPrevAccessor) {
-                        if (getter != null && prevGetter != null ||
-                                setter != null && prevSetter != null) {
-                            throw error(AbstractParser.message("property.redefinition", key), property.getToken());
+                    if (!isES6()) {
+                        checkPropertyRedefinition(property, value, getter, setter, prevValue, prevGetter, prevSetter);
+                    } else {
+                        if (property.getKey() instanceof IdentNode && ((IdentNode)property.getKey()).isProtoPropertyName() &&
+                                        existingProperty.getKey() instanceof IdentNode && ((IdentNode)existingProperty.getKey()).isProtoPropertyName()) {
+                            throw error(AbstractParser.message("multiple.proto.key"), property.getToken());
                         }
                     }
 
-                    if (value != null) {
+                    if (value != null || prevValue != null) {
+                        map.put(key, elements.size());
                         elements.add(property);
                     } else if (getter != null) {
+                        assert prevGetter != null || prevSetter != null;
                         elements.set(existing, existingProperty.setGetter(getter));
                     } else if (setter != null) {
+                        assert prevGetter != null || prevSetter != null;
                         elements.set(existing, existingProperty.setSetter(setter));
                     }
                     break;
@@ -2224,18 +3003,43 @@
         return new ObjectNode(objectToken, finish, elements);
     }
 
+    private void checkPropertyRedefinition(final PropertyNode property, final Expression value, final FunctionNode getter, final FunctionNode setter, final Expression prevValue, final FunctionNode prevGetter, final FunctionNode prevSetter) {
+        // ECMA 11.1.5 strict mode restrictions
+        if (isStrictMode && value != null && prevValue != null) {
+            throw error(AbstractParser.message("property.redefinition", property.getKeyName()), property.getToken());
+        }
+
+        final boolean isPrevAccessor = prevGetter != null || prevSetter != null;
+        final boolean isAccessor     = getter != null     || setter != null;
+
+        // data property redefined as accessor property
+        if (prevValue != null && isAccessor) {
+            throw error(AbstractParser.message("property.redefinition", property.getKeyName()), property.getToken());
+        }
+
+        // accessor property redefined as data
+        if (isPrevAccessor && value != null) {
+            throw error(AbstractParser.message("property.redefinition", property.getKeyName()), property.getToken());
+        }
+
+        if (isAccessor && isPrevAccessor) {
+            if (getter != null && prevGetter != null ||
+                    setter != null && prevSetter != null) {
+                throw error(AbstractParser.message("property.redefinition", property.getKeyName()), property.getToken());
+            }
+        }
+    }
+
     /**
-     * PropertyName :
+     * LiteralPropertyName :
      *      IdentifierName
      *      StringLiteral
      *      NumericLiteral
      *
-     * See 11.1.5
-     *
      * @return PropertyName node
      */
     @SuppressWarnings("fallthrough")
-    private PropertyKey propertyName() {
+    private PropertyKey literalPropertyName() {
         switch (type) {
         case IDENT:
             return getIdent().setIsPropertyName();
@@ -2257,6 +3061,34 @@
     }
 
     /**
+     * ComputedPropertyName :
+     *      AssignmentExpression
+     *
+     * @return PropertyName node
+     */
+    private Expression computedPropertyName() {
+        expect(LBRACKET);
+        Expression expression = assignmentExpression(false);
+        expect(RBRACKET);
+        return expression;
+    }
+
+    /**
+     * PropertyName :
+     *      LiteralPropertyName
+     *      ComputedPropertyName
+     *
+     * @return PropertyName node
+     */
+    private Expression propertyName() {
+        if (type == LBRACKET && isES6()) {
+            return computedPropertyName();
+        } else {
+            return (Expression)literalPropertyName();
+        }
+    }
+
+    /**
      * PropertyAssignment :
      *      PropertyName : AssignmentExpression
      *      get PropertyName ( ) { FunctionBody }
@@ -2280,51 +3112,95 @@
         final long propertyToken = token;
         final int  functionLine  = line;
 
-        PropertyKey propertyName;
-
+        final Expression propertyName;
+        final boolean isIdentifier;
+
+        boolean generator = false;
+        if (type == MUL && isES6()) {
+            generator = true;
+            next();
+        }
+
+        final boolean computed = type == LBRACKET;
         if (type == IDENT) {
             // Get IDENT.
             final String ident = (String)expectValue(IDENT);
 
-            if (type != COLON) {
+            if (type != COLON && (type != LPAREN || !isES6())) {
                 final long getSetToken = propertyToken;
 
                 switch (ident) {
                 case "get":
                     final PropertyFunction getter = propertyGetterFunction(getSetToken, functionLine);
-                    return new PropertyNode(propertyToken, finish, getter.ident, null, getter.functionNode, null);
+                    return new PropertyNode(propertyToken, finish, getter.key, null, getter.functionNode, null, false, getter.computed);
 
                 case "set":
                     final PropertyFunction setter = propertySetterFunction(getSetToken, functionLine);
-                    return new PropertyNode(propertyToken, finish, setter.ident, null, null, setter.functionNode);
+                    return new PropertyNode(propertyToken, finish, setter.key, null, null, setter.functionNode, false, setter.computed);
                 default:
                     break;
                 }
             }
 
-            propertyName = createIdentNode(propertyToken, finish, ident).setIsPropertyName();
+            isIdentifier = true;
+            IdentNode identNode = createIdentNode(propertyToken, finish, ident).setIsPropertyName();
+            if (type == COLON && ident.equals("__proto__")) {
+                identNode = identNode.setIsProtoPropertyName();
+            }
+            propertyName = identNode;
         } else {
+            isIdentifier = isNonStrictModeIdent();
             propertyName = propertyName();
         }
 
-        expect(COLON);
-
-        defaultNames.push(propertyName);
-        try {
-            return new PropertyNode(propertyToken, finish, propertyName, assignmentExpression(false), null, null);
-        } finally {
-            defaultNames.pop();
+        Expression propertyValue;
+
+        if (generator) {
+            expectDontAdvance(LPAREN);
         }
+
+        if (type == LPAREN && isES6()) {
+            propertyValue = propertyMethodFunction(propertyName, propertyToken, functionLine, generator, FunctionNode.ES6_IS_METHOD, computed).functionNode;
+        } else if (isIdentifier && (type == COMMARIGHT || type == RBRACE || type == ASSIGN) && isES6()) {
+            propertyValue = createIdentNode(propertyToken, finish, ((IdentNode) propertyName).getPropertyName());
+            if (type == ASSIGN && isES6()) {
+                // TODO if not destructuring, this is a SyntaxError
+                final long assignToken = token;
+                next();
+                final Expression rhs = assignmentExpression(false);
+                propertyValue = verifyAssignment(assignToken, propertyValue, rhs);
+            }
+        } else {
+            expect(COLON);
+
+            defaultNames.push(propertyName);
+            try {
+                propertyValue = assignmentExpression(false);
+            } finally {
+                defaultNames.pop();
+            }
+        }
+
+        return new PropertyNode(propertyToken, finish, propertyName, propertyValue, null, null, false, computed);
     }
 
     private PropertyFunction propertyGetterFunction(final long getSetToken, final int functionLine) {
-        final PropertyKey getIdent = propertyName();
-        final String getterName = getIdent.getPropertyName();
-        final IdentNode getNameNode = createIdentNode(((Node)getIdent).getToken(), finish, NameCodec.encode("get " + getterName));
+        return propertyGetterFunction(getSetToken, functionLine, FunctionNode.ES6_IS_METHOD);
+    }
+
+    private PropertyFunction propertyGetterFunction(final long getSetToken, final int functionLine, final int flags) {
+        final boolean computed = type == LBRACKET;
+        final Expression propertyName = propertyName();
+        final String getterName = propertyName instanceof PropertyKey ? ((PropertyKey) propertyName).getPropertyName() : getDefaultValidFunctionName(functionLine, false);
+        final IdentNode getNameNode = createIdentNode((propertyName).getToken(), finish, NameCodec.encode("get " + getterName));
         expect(LPAREN);
         expect(RPAREN);
 
         final ParserContextFunctionNode functionNode = createParserContextFunctionNode(getNameNode, getSetToken, FunctionNode.Kind.GETTER, functionLine, Collections.<IdentNode>emptyList());
+        functionNode.setFlag(flags);
+        if (computed) {
+            functionNode.setFlag(FunctionNode.IS_ANONYMOUS);
+        }
         lc.push(functionNode);
 
         Block functionBody;
@@ -2345,20 +3221,25 @@
                 functionLine,
                 functionBody);
 
-        return new PropertyFunction(getIdent, function);
+        return new PropertyFunction(propertyName, function, computed);
     }
 
     private PropertyFunction propertySetterFunction(final long getSetToken, final int functionLine) {
-        final PropertyKey setIdent = propertyName();
-        final String setterName = setIdent.getPropertyName();
-        final IdentNode setNameNode = createIdentNode(((Node)setIdent).getToken(), finish, NameCodec.encode("set " + setterName));
+        return propertySetterFunction(getSetToken, functionLine, FunctionNode.ES6_IS_METHOD);
+    }
+
+    private PropertyFunction propertySetterFunction(final long getSetToken, final int functionLine, final int flags) {
+        final boolean computed = type == LBRACKET;
+        final Expression propertyName = propertyName();
+        final String setterName = propertyName instanceof PropertyKey ? ((PropertyKey) propertyName).getPropertyName() : getDefaultValidFunctionName(functionLine, false);
+        final IdentNode setNameNode = createIdentNode((propertyName).getToken(), finish, NameCodec.encode("set " + setterName));
         expect(LPAREN);
         // be sloppy and allow missing setter parameter even though
         // spec does not permit it!
         final IdentNode argIdent;
-        if (type == IDENT || isNonStrictModeIdent()) {
+        if (isBindingIdentifier()) {
             argIdent = getIdent();
-            verifyStrictIdent(argIdent, "setter argument");
+            verifyIdent(argIdent, "setter argument");
         } else {
             argIdent = null;
         }
@@ -2370,6 +3251,10 @@
 
 
         final ParserContextFunctionNode functionNode = createParserContextFunctionNode(setNameNode, getSetToken, FunctionNode.Kind.SETTER, functionLine, parameters);
+        functionNode.setFlag(flags);
+        if (computed) {
+            functionNode.setFlag(FunctionNode.IS_ANONYMOUS);
+        }
         lc.push(functionNode);
 
         Block functionBody;
@@ -2389,33 +3274,81 @@
                 functionLine,
                 functionBody);
 
-        return new PropertyFunction(setIdent, function);
+        return new PropertyFunction(propertyName, function, computed);
+    }
+
+    private PropertyFunction propertyMethodFunction(Expression key, final long methodToken, final int methodLine, final boolean generator, final int flags, boolean computed) {
+        final String methodName = key instanceof PropertyKey ? ((PropertyKey) key).getPropertyName() : getDefaultValidFunctionName(methodLine, false);
+        final IdentNode methodNameNode = createIdentNode(((Node)key).getToken(), finish, methodName);
+
+        FunctionNode.Kind functionKind = generator ? FunctionNode.Kind.GENERATOR : FunctionNode.Kind.NORMAL;
+        final ParserContextFunctionNode functionNode = createParserContextFunctionNode(methodNameNode, methodToken, functionKind, methodLine, null);
+        functionNode.setFlag(flags);
+        if (computed) {
+            functionNode.setFlag(FunctionNode.IS_ANONYMOUS);
+        }
+        lc.push(functionNode);
+
+        try {
+            final ParserContextBlockNode parameterBlock = newBlock();
+            final List<IdentNode> parameters;
+            try {
+                expect(LPAREN);
+                parameters = formalParameterList(generator);
+                functionNode.setParameters(parameters);
+                expect(RPAREN);
+            } finally {
+                restoreBlock(parameterBlock);
+            }
+
+            Block functionBody = functionBody(functionNode);
+
+            functionBody = maybeWrapBodyInParameterBlock(functionBody, parameterBlock);
+
+            final FunctionNode  function = createFunctionNode(
+                            functionNode,
+                            methodToken,
+                            methodNameNode,
+                            parameters,
+                            functionKind,
+                            methodLine,
+                            functionBody);
+            return new PropertyFunction(key, function, computed);
+        } finally {
+            lc.pop(functionNode);
+        }
     }
 
     private static class PropertyFunction {
-        final PropertyKey ident;
+        final Expression key;
         final FunctionNode functionNode;
-
-        PropertyFunction(final PropertyKey ident, final FunctionNode function) {
-            this.ident = ident;
+        final boolean computed;
+
+        PropertyFunction(final Expression key, final FunctionNode function, final boolean computed) {
+            this.key = key;
             this.functionNode = function;
+            this.computed = computed;
         }
     }
 
     /**
-     * Parse left hand side expression.
-     *
      * LeftHandSideExpression :
      *      NewExpression
      *      CallExpression
      *
      * CallExpression :
      *      MemberExpression Arguments
+     *      SuperCall
      *      CallExpression Arguments
      *      CallExpression [ Expression ]
      *      CallExpression . IdentifierName
-     *      CallExpression TemplateLiteral
+     *
+     * SuperCall :
+     *      super Arguments
      *
+     * See 11.2
+     *
+     * Parse left hand side expression.
      * @return Expression node.
      */
     private Expression leftHandSideExpression() {
@@ -2435,7 +3368,7 @@
             lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
         }
 
-loop:
+        loop:
         while (true) {
             // Capture token.
             callLine  = line;
@@ -2479,6 +3412,7 @@
                 // tagged template literal
                 final List<Expression> arguments = templateLiteralArgumentList();
 
+                // Create call node.
                 lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
 
                 break;
@@ -2506,6 +3440,20 @@
         // NEW is tested in caller.
         next();
 
+        if (type == PERIOD && isES6()) {
+            next();
+            if (type == IDENT && "target".equals(getValue())) {
+                if (lc.getCurrentFunction().isProgram()) {
+                    throw error(AbstractParser.message("new.target.in.function"), token);
+                }
+                next();
+                markNewTarget(lc);
+                return new IdentNode(newToken, finish, "new.target");
+            } else {
+                throw error(AbstractParser.message("expected.target"), token);
+            }
+        }
+
         // Get function base.
         final int  callLine    = line;
         final Expression constructor = memberExpression();
@@ -2541,21 +3489,33 @@
     }
 
     /**
-     * Parse member expression.
-     *
      * MemberExpression :
      *      PrimaryExpression
-     *      FunctionExpression
+     *        FunctionExpression
+     *        ClassExpression
+     *        GeneratorExpression
      *      MemberExpression [ Expression ]
      *      MemberExpression . IdentifierName
      *      MemberExpression TemplateLiteral
+     *      SuperProperty
+     *      MetaProperty
      *      new MemberExpression Arguments
      *
+     * SuperProperty :
+     *      super [ Expression ]
+     *      super . IdentifierName
+     *
+     * MetaProperty :
+     *      NewTarget
+     *
+     * Parse member expression.
      * @return Expression node.
      */
+    @SuppressWarnings("fallthrough")
     private Expression memberExpression() {
         // Prepare to build operation.
         Expression lhs;
+        boolean isSuper = false;
 
         switch (type) {
         case NEW:
@@ -2568,13 +3528,53 @@
             lhs = functionExpression(false, false);
             break;
 
+        case CLASS:
+            if (isES6()) {
+                lhs = classExpression(false);
+                break;
+            } else {
+                // fall through
+            }
+
+        case SUPER:
+            if (isES6()) {
+                final ParserContextFunctionNode currentFunction = getCurrentNonArrowFunction();
+                if (currentFunction.isMethod()) {
+                    long identToken = Token.recast(token, IDENT);
+                    next();
+                    lhs = createIdentNode(identToken, finish, SUPER.getName());
+
+                    switch (type) {
+                        case LBRACKET:
+                        case PERIOD:
+                            getCurrentNonArrowFunction().setFlag(FunctionNode.ES6_USES_SUPER);
+                            isSuper = true;
+                            break;
+                        case LPAREN:
+                            if (currentFunction.isSubclassConstructor()) {
+                                lhs = ((IdentNode)lhs).setIsDirectSuper();
+                                break;
+                            } else {
+                                // fall through to throw error
+                            }
+                        default:
+                            throw error(AbstractParser.message("invalid.super"), identToken);
+                    }
+                    break;
+                } else {
+                    // fall through
+                }
+            } else {
+                // fall through
+            }
+
         default:
             // Get primary expression.
             lhs = primaryExpression();
             break;
         }
 
-loop:
+        loop:
         while (true) {
             // Capture token.
             final long callToken = token;
@@ -2591,6 +3591,11 @@
                 // Create indexing node.
                 lhs = new IndexNode(callToken, finish, lhs, index);
 
+                if (isSuper) {
+                    isSuper = false;
+                    lhs = ((BaseNode) lhs).setIsSuper();
+                }
+
                 break;
             }
             case PERIOD: {
@@ -2605,6 +3610,11 @@
                 // Create property access node.
                 lhs = new AccessNode(callToken, finish, lhs, property.getName());
 
+                if (isSuper) {
+                    isSuper = false;
+                    lhs = ((BaseNode) lhs).setIsSuper();
+                }
+
                 break;
             }
             case TEMPLATE:
@@ -2632,7 +3642,9 @@
      *
      * ArgumentList :
      *      AssignmentExpression
+     *      ... AssignmentExpression
      *      ArgumentList , AssignmentExpression
+     *      ArgumentList , ... AssignmentExpression
      *
      * See 11.2
      *
@@ -2656,8 +3668,18 @@
                 first = false;
             }
 
+            long spreadToken = 0;
+            if (type == ELLIPSIS && isES6()) {
+                spreadToken = token;
+                next();
+            }
+
             // Get argument expression.
-            nodeList.add(assignmentExpression(false));
+            Expression expression = assignmentExpression(false);
+            if (spreadToken != 0) {
+                expression = new UnaryNode(Token.recast(spreadToken, TokenType.SPREAD_ARGUMENT), expression);
+            }
+            nodeList.add(expression);
         }
 
         expect(RPAREN);
@@ -2697,11 +3719,24 @@
         final long functionToken = token;
         final int  functionLine  = line;
         // FUNCTION is tested in caller.
+        assert type == FUNCTION;
         next();
 
+        boolean generator = false;
+        if (type == MUL && isES6()) {
+            generator = true;
+            next();
+        }
+
         IdentNode name = null;
 
-        if (type == IDENT || isNonStrictModeIdent()) {
+        if (isBindingIdentifier()) {
+            if (type == YIELD && ((!isStatement && generator) || (isStatement && inGeneratorFunction()))) {
+                // 12.1.1 Early SyntaxError if:
+                // GeneratorExpression with BindingIdentifier yield
+                // HoistableDeclaration with BindingIdentifier yield in generator function body
+                expect(IDENT);
+            }
             name = getIdent();
             verifyStrictIdent(name, "function name");
         } else if (isStatement) {
@@ -2723,25 +3758,36 @@
             isAnonymous = true;
         }
 
-        expect(LPAREN);
-        final List<IdentNode> parameters = formalParameterList();
-        expect(RPAREN);
-
-        final ParserContextFunctionNode functionNode = createParserContextFunctionNode(name, functionToken, FunctionNode.Kind.NORMAL, functionLine, parameters);
+        FunctionNode.Kind functionKind = generator ? FunctionNode.Kind.GENERATOR : FunctionNode.Kind.NORMAL;
+        List<IdentNode> parameters = Collections.emptyList();
+        final ParserContextFunctionNode functionNode = createParserContextFunctionNode(name, functionToken, functionKind, functionLine, parameters);
         lc.push(functionNode);
+
         Block functionBody = null;
         // Hide the current default name across function boundaries. E.g. "x3 = function x1() { function() {}}"
         // If we didn't hide the current default name, then the innermost anonymous function would receive "x3".
         hideDefaultName();
-        try{
+        try {
+            final ParserContextBlockNode parameterBlock = newBlock();
+            try {
+                expect(LPAREN);
+                parameters = formalParameterList(generator);
+                functionNode.setParameters(parameters);
+                expect(RPAREN);
+            } finally {
+                restoreBlock(parameterBlock);
+            }
+
             functionBody = functionBody(functionNode);
+
+            functionBody = maybeWrapBodyInParameterBlock(functionBody, parameterBlock);
         } finally {
             defaultNames.pop();
             lc.pop(functionNode);
         }
 
         if (isStatement) {
-            if (topLevel || useBlockScope()) {
+            if (topLevel || useBlockScope() || (!isStrictMode && env._function_statement == ScriptEnvironment.FunctionStatementBehavior.ACCEPT)) {
                 functionNode.setFlag(FunctionNode.IS_DECLARED);
             } else if (isStrictMode) {
                 throw error(JSErrorType.SYNTAX_ERROR, AbstractParser.message("strict.no.func.decl.here"), functionToken);
@@ -2759,45 +3805,14 @@
             functionNode.setFlag(FunctionNode.IS_ANONYMOUS);
         }
 
-        final int arity = parameters.size();
-
-        final boolean strict = functionNode.isStrict();
-        if (arity > 1) {
-            final HashSet<String> parametersSet = new HashSet<>(arity);
-
-            for (int i = arity - 1; i >= 0; i--) {
-                final IdentNode parameter = parameters.get(i);
-                String parameterName = parameter.getName();
-
-                if (isArguments(parameterName)) {
-                    functionNode.setFlag(FunctionNode.DEFINES_ARGUMENTS);
-                }
-
-                if (parametersSet.contains(parameterName)) {
-                    // redefinition of parameter name
-                    if (strict) {
-                        throw error(AbstractParser.message("strict.param.redefinition", parameterName), parameter.getToken());
-                    }
-                    // rename in non-strict mode
-                    parameterName = functionNode.uniqueName(parameterName);
-                    final long parameterToken = parameter.getToken();
-                    parameters.set(i, new IdentNode(parameterToken, Token.descPosition(parameterToken), functionNode.uniqueName(parameterName)));
-                }
-
-                parametersSet.add(parameterName);
-            }
-        } else if (arity == 1) {
-            if (isArguments(parameters.get(0))) {
-                functionNode.setFlag(FunctionNode.DEFINES_ARGUMENTS);
-            }
-        }
+        verifyParameterList(parameters, functionNode);
 
         final FunctionNode function = createFunctionNode(
                 functionNode,
                 functionToken,
                 name,
                 parameters,
-                FunctionNode.Kind.NORMAL,
+                functionKind,
                 functionLine,
                 functionBody);
 
@@ -2822,6 +3837,40 @@
         return function;
     }
 
+    private void verifyParameterList(final List<IdentNode> parameters, final ParserContextFunctionNode functionNode) {
+        final IdentNode duplicateParameter = functionNode.getDuplicateParameterBinding();
+        if (duplicateParameter != null) {
+            if (functionNode.isStrict() || functionNode.getKind() == FunctionNode.Kind.ARROW || !functionNode.isSimpleParameterList()) {
+                throw error(AbstractParser.message("strict.param.redefinition", duplicateParameter.getName()), duplicateParameter.getToken());
+            }
+
+            final int arity = parameters.size();
+            final HashSet<String> parametersSet = new HashSet<>(arity);
+
+            for (int i = arity - 1; i >= 0; i--) {
+                final IdentNode parameter = parameters.get(i);
+                String parameterName = parameter.getName();
+
+                if (parametersSet.contains(parameterName)) {
+                    // redefinition of parameter name, rename in non-strict mode
+                    parameterName = functionNode.uniqueName(parameterName);
+                    final long parameterToken = parameter.getToken();
+                    parameters.set(i, new IdentNode(parameterToken, Token.descPosition(parameterToken), functionNode.uniqueName(parameterName)));
+                }
+                parametersSet.add(parameterName);
+            }
+        }
+    }
+
+    private static Block maybeWrapBodyInParameterBlock(Block functionBody, ParserContextBlockNode parameterBlock) {
+        assert functionBody.isFunctionBody();
+        if (!parameterBlock.getStatements().isEmpty()) {
+            parameterBlock.appendStatement(new BlockStatement(functionBody));
+            return new Block(parameterBlock.getToken(), functionBody.getFinish(), (functionBody.getFlags() | Block.IS_PARAMETER_BLOCK) & ~Block.IS_BODY, parameterBlock.getStatements());
+        }
+        return functionBody;
+    }
+
     private String getDefaultValidFunctionName(final int functionLine, final boolean isStatement) {
         final String defaultFunctionName = getDefaultFunctionName();
         if (isValidIdentifier(defaultFunctionName)) {
@@ -2836,14 +3885,14 @@
     }
 
     private static boolean isValidIdentifier(final String name) {
-        if(name == null || name.isEmpty()) {
+        if (name == null || name.isEmpty()) {
             return false;
         }
-        if(!Character.isJavaIdentifierStart(name.charAt(0))) {
+        if (!Character.isJavaIdentifierStart(name.charAt(0))) {
             return false;
         }
-        for(int i = 1; i < name.length(); ++i) {
-            if(!Character.isJavaIdentifierPart(name.charAt(i))) {
+        for (int i = 1; i < name.length(); ++i) {
+            if (!Character.isJavaIdentifierPart(name.charAt(i))) {
                 return false;
             }
         }
@@ -2851,12 +3900,12 @@
     }
 
     private String getDefaultFunctionName() {
-        if(!defaultNames.isEmpty()) {
+        if (!defaultNames.isEmpty()) {
             final Object nameExpr = defaultNames.peek();
-            if(nameExpr instanceof PropertyKey) {
+            if (nameExpr instanceof PropertyKey) {
                 markDefaultNameUsed();
                 return ((PropertyKey)nameExpr).getPropertyName();
-            } else if(nameExpr instanceof AccessNode) {
+            } else if (nameExpr instanceof AccessNode) {
                 markDefaultNameUsed();
                 return ((AccessNode)nameExpr).getProperty();
             }
@@ -2885,8 +3934,8 @@
      * Parse function parameter list.
      * @return List of parameter nodes.
      */
-    private List<IdentNode> formalParameterList() {
-        return formalParameterList(RPAREN);
+    private List<IdentNode> formalParameterList(final boolean yield) {
+        return formalParameterList(RPAREN, yield);
     }
 
     /**
@@ -2902,7 +3951,7 @@
      * Parse function parameter list.
      * @return List of parameter nodes.
      */
-    private List<IdentNode> formalParameterList(final TokenType endType) {
+    private List<IdentNode> formalParameterList(final TokenType endType, final boolean yield) {
         // Prepare to gather parameters.
         final ArrayList<IdentNode> parameters = new ArrayList<>();
         // Track commas.
@@ -2916,12 +3965,84 @@
                 first = false;
             }
 
-            // Get and add parameter.
-            final IdentNode ident = getIdent();
-
-            // ECMA 13.1 strict mode restrictions
-            verifyStrictIdent(ident, "function parameter");
-
+            boolean restParameter = false;
+            if (type == ELLIPSIS && isES6()) {
+                next();
+                restParameter = true;
+            }
+
+            if (type == YIELD && yield) {
+                expect(IDENT);
+            }
+
+            final long paramToken = token;
+            final int paramLine = line;
+            final String contextString = "function parameter";
+            IdentNode ident;
+            if (isBindingIdentifier() || restParameter || !isES6()) {
+                ident = bindingIdentifier(contextString);
+
+                if (restParameter) {
+                    ident = ident.setIsRestParameter();
+                    // rest parameter must be last
+                    expectDontAdvance(endType);
+                    parameters.add(ident);
+                    break;
+                } else if (type == ASSIGN && isES6()) {
+                    next();
+                    ident = ident.setIsDefaultParameter();
+
+                    if (type == YIELD && yield) {
+                        // error: yield in default expression
+                        expect(IDENT);
+                    }
+
+                    // default parameter
+                    Expression initializer = assignmentExpression(false);
+
+                    ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
+                    if (currentFunction != null) {
+                        // desugar to: param = (param === undefined) ? initializer : param;
+                        // possible alternative: if (param === undefined) param = initializer;
+                        BinaryNode test = new BinaryNode(Token.recast(paramToken, EQ_STRICT), ident, newUndefinedLiteral(paramToken, finish));
+                        TernaryNode value = new TernaryNode(Token.recast(paramToken, TERNARY), test, new JoinPredecessorExpression(initializer), new JoinPredecessorExpression(ident));
+                        BinaryNode assignment = new BinaryNode(Token.recast(paramToken, ASSIGN), ident, value);
+                        lc.getFunctionBody(currentFunction).appendStatement(new ExpressionStatement(paramLine, assignment.getToken(), assignment.getFinish(), assignment));
+                    }
+                }
+
+                ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
+                if (currentFunction != null) {
+                    currentFunction.addParameterBinding(ident);
+                    if (ident.isRestParameter() || ident.isDefaultParameter()) {
+                        currentFunction.setSimpleParameterList(false);
+                    }
+                }
+            } else {
+                final Expression pattern = bindingPattern();
+                // Introduce synthetic temporary parameter to capture the object to be destructured.
+                ident = createIdentNode(paramToken, pattern.getFinish(), String.format("arguments[%d]", parameters.size())).setIsDestructuredParameter();
+                verifyDestructuringParameterBindingPattern(pattern, paramToken, paramLine, contextString);
+
+                Expression value = ident;
+                if (type == ASSIGN) {
+                    next();
+                    ident = ident.setIsDefaultParameter();
+
+                    // binding pattern with initializer. desugar to: (param === undefined) ? initializer : param
+                    Expression initializer = assignmentExpression(false);
+                    // TODO initializer must not contain yield expression if yield=true (i.e. this is generator function's parameter list)
+                    BinaryNode test = new BinaryNode(Token.recast(paramToken, EQ_STRICT), ident, newUndefinedLiteral(paramToken, finish));
+                    value = new TernaryNode(Token.recast(paramToken, TERNARY), test, new JoinPredecessorExpression(initializer), new JoinPredecessorExpression(ident));
+                }
+
+                ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
+                if (currentFunction != null) {
+                    // destructuring assignment
+                    BinaryNode assignment = new BinaryNode(Token.recast(paramToken, ASSIGN), pattern, value);
+                    lc.getFunctionBody(currentFunction).appendStatement(new ExpressionStatement(paramLine, assignment.getToken(), assignment.getFinish(), assignment));
+                }
+            }
             parameters.add(ident);
         }
 
@@ -2929,6 +4050,23 @@
         return parameters;
     }
 
+    private void verifyDestructuringParameterBindingPattern(final Expression pattern, final long paramToken, final int paramLine, final String contextString) {
+        verifyDestructuringBindingPattern(pattern, new Consumer<IdentNode>() {
+            public void accept(IdentNode identNode) {
+                verifyIdent(identNode, contextString);
+
+                ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
+                if (currentFunction != null) {
+                    // declare function-scope variables for destructuring bindings
+                    lc.getFunctionBody(currentFunction).appendStatement(new VarNode(paramLine, Token.recast(paramToken, VAR), pattern.getFinish(), identNode, null));
+                    // detect duplicate bounds names in parameter list
+                    currentFunction.addParameterBinding(identNode);
+                    currentFunction.setSimpleParameterList(false);
+                }
+            }
+        });
+    }
+
     /**
      * FunctionBody :
      *      SourceElements?
@@ -2958,7 +4096,7 @@
             final int functionId = functionNode.getId();
             parseBody = reparsedFunction == null || functionId <= reparsedFunction.getFunctionNodeId();
             // Nashorn extension: expression closures
-            if (!env._no_syntax_extensions && type != LBRACE) {
+            if ((!env._no_syntax_extensions || functionNode.getKind() == FunctionNode.Kind.ARROW) && type != LBRACE) {
                 /*
                  * Example:
                  *
@@ -2967,7 +4105,7 @@
                  */
 
                 // just expression as function body
-                final Expression expr = assignmentExpression(true);
+                final Expression expr = assignmentExpression(false);
                 lastToken = previousToken;
                 functionNode.setLastToken(previousToken);
                 assert lc.getCurrentBlock() == lc.getFunctionBody(functionNode);
@@ -2982,6 +4120,7 @@
                     final ReturnNode returnNode = new ReturnNode(functionNode.getLineNumber(), expr.getToken(), lastFinish, expr);
                     appendStatement(returnNode);
                 }
+                // bodyFinish = finish;
             } else {
                 expectDontAdvance(LBRACE);
                 if (parseBody || !skipFunctionBody(functionNode)) {
@@ -3054,7 +4193,7 @@
                 }
             }
         }
-        functionBody = new Block(bodyToken, bodyFinish, body.getFlags(), body.getStatements());
+        functionBody = new Block(bodyToken, bodyFinish, body.getFlags() | Block.IS_BODY, body.getStatements());
         return functionBody;
     }
 
@@ -3095,8 +4234,7 @@
         // Doesn't really matter, but it's safe to treat it as if there were a semicolon before
         // the RBRACE.
         type = SEMICOLON;
-        k = -1;
-        next();
+        scanFirstToken();
 
         return true;
     }
@@ -3126,11 +4264,11 @@
     }
 
     private void printAST(final FunctionNode functionNode) {
-        if (functionNode.getFlag(FunctionNode.IS_PRINT_AST)) {
+        if (functionNode.getDebugFlag(FunctionNode.DEBUG_PRINT_AST)) {
             env.getErr().println(new ASTWriter(functionNode));
         }
 
-        if (functionNode.getFlag(FunctionNode.IS_PRINT_PARSE)) {
+        if (functionNode.getDebugFlag(FunctionNode.DEBUG_PRINT_PARSE)) {
             env.getErr().println(new PrintVisitor(functionNode, true, false));
         }
     }
@@ -3222,20 +4360,7 @@
                 throw error(AbstractParser.message("expected.lvalue", type.getNameOrType()));
             }
 
-            if (!(lhs instanceof AccessNode ||
-                  lhs instanceof IndexNode ||
-                  lhs instanceof IdentNode)) {
-                return referenceError(lhs, null, env._early_lvalue_error);
-            }
-
-            if (lhs instanceof IdentNode) {
-                if (!checkIdentLValue((IdentNode)lhs)) {
-                    return referenceError(lhs, null, false);
-                }
-                verifyStrictIdent((IdentNode)lhs, "operand for " + opType.getName() + " operator");
-            }
-
-            return incDecExpression(unaryToken, opType, lhs, false);
+            return verifyIncDecExpression(unaryToken, opType, lhs, false);
 
         default:
             break;
@@ -3247,29 +4372,16 @@
             switch (type) {
             case INCPREFIX:
             case DECPREFIX:
+                final long opToken = token;
                 final TokenType opType = type;
                 final Expression lhs = expression;
                 // ++, -- without operand..
                 if (lhs == null) {
                     throw error(AbstractParser.message("expected.lvalue", type.getNameOrType()));
                 }
-
-                if (!(lhs instanceof AccessNode ||
-                   lhs instanceof IndexNode ||
-                   lhs instanceof IdentNode)) {
-                    next();
-                    return referenceError(lhs, null, env._early_lvalue_error);
-                }
-                if (lhs instanceof IdentNode) {
-                    if (!checkIdentLValue((IdentNode)lhs)) {
-                        next();
-                        return referenceError(lhs, null, false);
-                    }
-                    verifyStrictIdent((IdentNode)lhs, "operand for " + opType.getName() + " operator");
-                }
-                expression = incDecExpression(token, type, expression, true);
                 next();
-                break;
+
+                return verifyIncDecExpression(opToken, opType, lhs, true);
             default:
                 break;
             }
@@ -3282,6 +4394,25 @@
         return expression;
     }
 
+    private Expression verifyIncDecExpression(final long unaryToken, final TokenType opType, final Expression lhs, final boolean isPostfix) {
+        assert lhs != null;
+
+        if (!(lhs instanceof AccessNode ||
+              lhs instanceof IndexNode ||
+              lhs instanceof IdentNode)) {
+            return referenceError(lhs, null, env._early_lvalue_error);
+        }
+
+        if (lhs instanceof IdentNode) {
+            if (!checkIdentLValue((IdentNode)lhs)) {
+                return referenceError(lhs, null, false);
+            }
+            verifyIdent((IdentNode)lhs, "operand for " + opType.getName() + " operator");
+        }
+
+        return incDecExpression(unaryToken, opType, lhs, isPostfix);
+    }
+
     /**
      * {@code
      * MultiplicativeExpression :
@@ -3380,7 +4511,42 @@
         // at expression start point!
 
         // Include commas in expression parsing.
-        return expression(unaryExpression(), COMMARIGHT.getPrecedence(), false);
+        return expression(false);
+    }
+
+    private Expression expression(final boolean noIn) {
+        Expression assignmentExpression = assignmentExpression(noIn);
+        while (type == COMMARIGHT) {
+            long commaToken = token;
+            next();
+
+            boolean rhsRestParameter = false;
+            if (type == ELLIPSIS && isES6()) {
+                // (a, b, ...rest) is not a valid expression, unless we're parsing the parameter list of an arrow function (we need to throw the right error).
+                // But since the rest parameter is always last, at least we know that the expression has to end here and be followed by RPAREN and ARROW, so peek ahead.
+                if (isRestParameterEndOfArrowFunctionParameterList()) {
+                    next();
+                    rhsRestParameter = true;
+                }
+            }
+
+            Expression rhs = assignmentExpression(noIn);
+
+            if (rhsRestParameter) {
+                rhs = ((IdentNode)rhs).setIsRestParameter();
+                // Our only valid move is to end Expression here and continue with ArrowFunction.
+                // We've already checked that this is the parameter list of an arrow function (see above).
+                // RPAREN is next, so we'll finish the binary expression and drop out of the loop.
+                assert type == RPAREN;
+            }
+
+            assignmentExpression = new BinaryNode(commaToken, assignmentExpression, rhs);
+        }
+        return assignmentExpression;
+    }
+
+    private Expression expression(final int minPrecedence, final boolean noIn) {
+        return expression(unaryExpression(), minPrecedence, noIn);
     }
 
     private JoinPredecessorExpression joinPredecessorExpression() {
@@ -3448,12 +4614,316 @@
         return lhs;
     }
 
+    /**
+     * AssignmentExpression.
+     *
+     * AssignmentExpression[In, Yield] :
+     *   ConditionalExpression[?In, ?Yield]
+     *   [+Yield] YieldExpression[?In]
+     *   ArrowFunction[?In, ?Yield]
+     *   LeftHandSideExpression[?Yield] = AssignmentExpression[?In, ?Yield]
+     *   LeftHandSideExpression[?Yield] AssignmentOperator AssignmentExpression[?In, ?Yield]
+     */
     protected Expression assignmentExpression(final boolean noIn) {
         // This method is protected so that subclass can get details
         // at assignment expression start point!
 
-        // Exclude commas in expression parsing.
-        return expression(unaryExpression(), ASSIGN.getPrecedence(), noIn);
+        if (type == YIELD && inGeneratorFunction() && isES6()) {
+            return yieldExpression(noIn);
+        }
+
+        final long startToken = token;
+        final int startLine = line;
+        final Expression exprLhs = conditionalExpression(noIn);
+
+        if (type == ARROW && isES6()) {
+            if (checkNoLineTerminator()) {
+                final Expression paramListExpr;
+                if (exprLhs instanceof ExpressionList) {
+                    paramListExpr = (((ExpressionList)exprLhs).getExpressions().isEmpty() ? null : ((ExpressionList)exprLhs).getExpressions().get(0));
+                } else {
+                    paramListExpr = exprLhs;
+                }
+                return arrowFunction(startToken, startLine, paramListExpr);
+            }
+        }
+        assert !(exprLhs instanceof ExpressionList);
+
+        if (isAssignmentOperator(type)) {
+            final boolean isAssign = type == ASSIGN;
+            if (isAssign) {
+                defaultNames.push(exprLhs);
+            }
+            try {
+                final long assignToken = token;
+                next();
+                final Expression exprRhs = assignmentExpression(noIn);
+                return verifyAssignment(assignToken, exprLhs, exprRhs);
+            } finally {
+                if (isAssign) {
+                    defaultNames.pop();
+                }
+            }
+        } else {
+            return exprLhs;
+        }
+    }
+
+    /**
+     * Is type one of {@code = *= /= %= += -= <<= >>= >>>= &= ^= |=}?
+     */
+    private static boolean isAssignmentOperator(TokenType type) {
+        switch (type) {
+        case ASSIGN:
+        case ASSIGN_ADD:
+        case ASSIGN_BIT_AND:
+        case ASSIGN_BIT_OR:
+        case ASSIGN_BIT_XOR:
+        case ASSIGN_DIV:
+        case ASSIGN_MOD:
+        case ASSIGN_MUL:
+        case ASSIGN_SAR:
+        case ASSIGN_SHL:
+        case ASSIGN_SHR:
+        case ASSIGN_SUB:
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * ConditionalExpression.
+     */
+    private Expression conditionalExpression(boolean noIn) {
+        return expression(TERNARY.getPrecedence(), noIn);
+    }
+
+    /**
+     * ArrowFunction.
+     *
+     * @param startToken start token of the ArrowParameters expression
+     * @param functionLine start line of the arrow function
+     * @param paramListExpr ArrowParameters expression or {@code null} for {@code ()} (empty list)
+     */
+    private Expression arrowFunction(final long startToken, final int functionLine, final Expression paramListExpr) {
+        // caller needs to check that there's no LineTerminator between parameter list and arrow
+        assert type != ARROW || checkNoLineTerminator();
+        expect(ARROW);
+
+        final long functionToken = Token.recast(startToken, ARROW);
+        final IdentNode name = new IdentNode(functionToken, Token.descPosition(functionToken), "=>:" + functionLine);
+        final ParserContextFunctionNode functionNode = createParserContextFunctionNode(name, functionToken, FunctionNode.Kind.ARROW, functionLine, null);
+        functionNode.setFlag(FunctionNode.IS_ANONYMOUS);
+
+        lc.push(functionNode);
+        try {
+            ParserContextBlockNode parameterBlock = newBlock();
+            final List<IdentNode> parameters;
+            try {
+                parameters = convertArrowFunctionParameterList(paramListExpr, functionLine);
+                functionNode.setParameters(parameters);
+
+                if (!functionNode.isSimpleParameterList()) {
+                    markEvalInArrowParameterList(parameterBlock);
+                }
+            } finally {
+                restoreBlock(parameterBlock);
+            }
+            Block functionBody = functionBody(functionNode);
+
+            functionBody = maybeWrapBodyInParameterBlock(functionBody, parameterBlock);
+
+            verifyParameterList(parameters, functionNode);
+
+            final FunctionNode function = createFunctionNode(
+                            functionNode,
+                            functionToken,
+                            name,
+                            parameters,
+                            FunctionNode.Kind.ARROW,
+                            functionLine,
+                            functionBody);
+            return function;
+        } finally {
+            lc.pop(functionNode);
+        }
+    }
+
+    private void markEvalInArrowParameterList(final ParserContextBlockNode parameterBlock) {
+        final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
+        final ParserContextFunctionNode current = iter.next();
+        final ParserContextFunctionNode parent = iter.next();
+
+        if (parent.getFlag(FunctionNode.HAS_EVAL) != 0) {
+            // we might have flagged has-eval in the parent function during parsing the parameter list,
+            // if the parameter list contains eval; must tag arrow function as has-eval.
+            for (final Statement st : parameterBlock.getStatements()) {
+                st.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
+                    @Override
+                    public boolean enterCallNode(final CallNode callNode) {
+                        if (callNode.getFunction() instanceof IdentNode && ((IdentNode) callNode.getFunction()).getName().equals("eval")) {
+                            current.setFlag(FunctionNode.HAS_EVAL);
+                        }
+                        return true;
+                    }
+                });
+            }
+            // TODO: function containing the arrow function should not be flagged has-eval
+        }
+    }
+
+    private List<IdentNode> convertArrowFunctionParameterList(final Expression paramListExpr, final int functionLine) {
+        final List<IdentNode> parameters;
+        if (paramListExpr == null) {
+            // empty parameter list, i.e. () =>
+            parameters = Collections.emptyList();
+        } else if (paramListExpr instanceof IdentNode || paramListExpr.isTokenType(ASSIGN) || isDestructuringLhs(paramListExpr)) {
+            parameters = Collections.singletonList(verifyArrowParameter(paramListExpr, 0, functionLine));
+        } else if (paramListExpr instanceof BinaryNode && Token.descType(paramListExpr.getToken()) == COMMARIGHT) {
+            parameters = new ArrayList<>();
+            Expression car = paramListExpr;
+            do {
+                final Expression cdr = ((BinaryNode) car).rhs();
+                parameters.add(0, verifyArrowParameter(cdr, parameters.size(), functionLine));
+                car = ((BinaryNode) car).lhs();
+            } while (car instanceof BinaryNode && Token.descType(car.getToken()) == COMMARIGHT);
+            parameters.add(0, verifyArrowParameter(car, parameters.size(), functionLine));
+        } else {
+            throw error(AbstractParser.message("expected.arrow.parameter"), paramListExpr.getToken());
+        }
+        return parameters;
+    }
+
+    private IdentNode verifyArrowParameter(Expression param, int index, int paramLine) {
+        final String contextString = "function parameter";
+        if (param instanceof IdentNode) {
+            IdentNode ident = (IdentNode)param;
+            verifyStrictIdent(ident, contextString);
+            ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
+            if (currentFunction != null) {
+                currentFunction.addParameterBinding(ident);
+            }
+            return ident;
+        }
+
+        if (param.isTokenType(ASSIGN)) {
+            Expression lhs = ((BinaryNode) param).lhs();
+            long paramToken = lhs.getToken();
+            Expression initializer = ((BinaryNode) param).rhs();
+            if (lhs instanceof IdentNode) {
+                // default parameter
+                IdentNode ident = (IdentNode) lhs;
+
+                ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
+                if (currentFunction != null) {
+                    BinaryNode test = new BinaryNode(Token.recast(paramToken, EQ_STRICT), ident, newUndefinedLiteral(paramToken, finish));
+                    TernaryNode value = new TernaryNode(Token.recast(paramToken, TERNARY), test, new JoinPredecessorExpression(initializer), new JoinPredecessorExpression(ident));
+                    BinaryNode assignment = new BinaryNode(Token.recast(paramToken, ASSIGN), ident, value);
+                    lc.getFunctionBody(currentFunction).appendStatement(new ExpressionStatement(paramLine, assignment.getToken(), assignment.getFinish(), assignment));
+
+                    currentFunction.addParameterBinding(ident);
+                    currentFunction.setSimpleParameterList(false);
+                }
+                return ident;
+            } else if (isDestructuringLhs(lhs)) {
+                // binding pattern with initializer
+                // Introduce synthetic temporary parameter to capture the object to be destructured.
+                IdentNode ident = createIdentNode(paramToken, param.getFinish(), String.format("arguments[%d]", index)).setIsDestructuredParameter().setIsDefaultParameter();
+                verifyDestructuringParameterBindingPattern(param, paramToken, paramLine, contextString);
+
+                ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
+                if (currentFunction != null) {
+                    BinaryNode test = new BinaryNode(Token.recast(paramToken, EQ_STRICT), ident, newUndefinedLiteral(paramToken, finish));
+                    TernaryNode value = new TernaryNode(Token.recast(paramToken, TERNARY), test, new JoinPredecessorExpression(initializer), new JoinPredecessorExpression(ident));
+                    BinaryNode assignment = new BinaryNode(Token.recast(paramToken, ASSIGN), param, value);
+                    lc.getFunctionBody(currentFunction).appendStatement(new ExpressionStatement(paramLine, assignment.getToken(), assignment.getFinish(), assignment));
+                }
+                return ident;
+            }
+        } else if (isDestructuringLhs(param)) {
+            // binding pattern
+            long paramToken = param.getToken();
+
+            // Introduce synthetic temporary parameter to capture the object to be destructured.
+            IdentNode ident = createIdentNode(paramToken, param.getFinish(), String.format("arguments[%d]", index)).setIsDestructuredParameter();
+            verifyDestructuringParameterBindingPattern(param, paramToken, paramLine, contextString);
+
+            ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
+            if (currentFunction != null) {
+                BinaryNode assignment = new BinaryNode(Token.recast(paramToken, ASSIGN), param, ident);
+                lc.getFunctionBody(currentFunction).appendStatement(new ExpressionStatement(paramLine, assignment.getToken(), assignment.getFinish(), assignment));
+            }
+            return ident;
+        }
+        throw error(AbstractParser.message("invalid.arrow.parameter"), param.getToken());
+    }
+
+    private boolean checkNoLineTerminator() {
+        assert type == ARROW;
+        if (last == RPAREN) {
+            return true;
+        } else if (last == IDENT) {
+            return true;
+        }
+        for (int i = k - 1; i >= 0; i--) {
+            TokenType t = T(i);
+            switch (t) {
+            case RPAREN:
+            case IDENT:
+                return true;
+            case EOL:
+                return false;
+            case COMMENT:
+                continue;
+            default:
+                if (t.getKind() == TokenKind.FUTURESTRICT) {
+                    return true;
+                }
+                return false;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Peek ahead to see if what follows after the ellipsis is a rest parameter
+     * at the end of an arrow function parameter list.
+     */
+    private boolean isRestParameterEndOfArrowFunctionParameterList() {
+        assert type == ELLIPSIS;
+        // find IDENT, RPAREN, ARROW, in that order, skipping over EOL (where allowed) and COMMENT
+        int i = 1;
+        for (;;) {
+            TokenType t = T(k + i++);
+            if (t == IDENT) {
+                break;
+            } else if (t == EOL || t == COMMENT) {
+                continue;
+            } else {
+                return false;
+            }
+        }
+        for (;;) {
+            TokenType t = T(k + i++);
+            if (t == RPAREN) {
+                break;
+            } else if (t == EOL || t == COMMENT) {
+                continue;
+            } else {
+                return false;
+            }
+        }
+        for (;;) {
+            TokenType t = T(k + i++);
+            if (t == ARROW) {
+                break;
+            } else if (t == COMMENT) {
+                continue;
+            } else {
+                return false;
+            }
+        }
+        return true;
     }
 
     /**
@@ -3551,6 +5021,380 @@
         cookedStrings.add(LiteralNode.newInstance(stringToken, finish, cookedString));
     }
 
+
+    /**
+     * Parse a module.
+     *
+     * Module :
+     *      ModuleBody?
+     *
+     * ModuleBody :
+     *      ModuleItemList
+     */
+    private FunctionNode module(final String moduleName) {
+        boolean oldStrictMode = isStrictMode;
+        try {
+            isStrictMode = true; // Module code is always strict mode code. (ES6 10.2.1)
+
+            // Make a pseudo-token for the script holding its start and length.
+            int functionStart = Math.min(Token.descPosition(Token.withDelimiter(token)), finish);
+            final long functionToken = Token.toDesc(FUNCTION, functionStart, source.getLength() - functionStart);
+            final int  functionLine  = line;
+
+            final IdentNode ident = new IdentNode(functionToken, Token.descPosition(functionToken), moduleName);
+            final ParserContextFunctionNode script = createParserContextFunctionNode(
+                            ident,
+                            functionToken,
+                            FunctionNode.Kind.MODULE,
+                            functionLine,
+                            Collections.<IdentNode>emptyList());
+            lc.push(script);
+
+            final ParserContextModuleNode module = new ParserContextModuleNode(moduleName);
+            lc.push(module);
+
+            final ParserContextBlockNode body = newBlock();
+
+            functionDeclarations = new ArrayList<>();
+            moduleBody();
+            addFunctionDeclarations(script);
+            functionDeclarations = null;
+
+            restoreBlock(body);
+            body.setFlag(Block.NEEDS_SCOPE);
+            final Block programBody = new Block(functionToken, finish, body.getFlags() | Block.IS_SYNTHETIC | Block.IS_BODY, body.getStatements());
+            lc.pop(module);
+            lc.pop(script);
+            script.setLastToken(token);
+
+            expect(EOF);
+
+            script.setModule(module.createModule());
+            return createFunctionNode(script, functionToken, ident, Collections.<IdentNode>emptyList(), FunctionNode.Kind.MODULE, functionLine, programBody);
+        } finally {
+            isStrictMode = oldStrictMode;
+        }
+    }
+
+    /**
+     * Parse module body.
+     *
+     * ModuleBody :
+     *      ModuleItemList
+     *
+     * ModuleItemList :
+     *      ModuleItem
+     *      ModuleItemList ModuleItem
+     *
+     * ModuleItem :
+     *      ImportDeclaration
+     *      ExportDeclaration
+     *      StatementListItem
+     */
+    private void moduleBody() {
+        loop:
+        while (type != EOF) {
+            switch (type) {
+            case EOF:
+                break loop;
+            case IMPORT:
+                importDeclaration();
+                break;
+            case EXPORT:
+                exportDeclaration();
+                break;
+            default:
+                // StatementListItem
+                statement(true, false, false, false);
+                break;
+            }
+        }
+    }
+
+
+    /**
+     * Parse import declaration.
+     *
+     * ImportDeclaration :
+     *     import ImportClause FromClause ;
+     *     import ModuleSpecifier ;
+     * ImportClause :
+     *     ImportedDefaultBinding
+     *     NameSpaceImport
+     *     NamedImports
+     *     ImportedDefaultBinding , NameSpaceImport
+     *     ImportedDefaultBinding , NamedImports
+     * ImportedDefaultBinding :
+     *     ImportedBinding
+     * ModuleSpecifier :
+     *     StringLiteral
+     * ImportedBinding :
+     *     BindingIdentifier
+     */
+    private void importDeclaration() {
+        expect(IMPORT);
+        final ParserContextModuleNode module = lc.getCurrentModule();
+        if (type == STRING || type == ESCSTRING) {
+            // import ModuleSpecifier ;
+            final String moduleSpecifier = (String) getValue();
+            next();
+            module.addModuleRequest(moduleSpecifier);
+        } else {
+            // import ImportClause FromClause ;
+            List<Module.ImportEntry> importEntries;
+            if (type == MUL) {
+                importEntries = Collections.singletonList(nameSpaceImport());
+            } else if (type == LBRACE) {
+                importEntries = namedImports();
+            } else if (isBindingIdentifier()) {
+                // ImportedDefaultBinding
+                final IdentNode importedDefaultBinding = bindingIdentifier("ImportedBinding");
+                Module.ImportEntry defaultImport = Module.ImportEntry.importDefault(importedDefaultBinding.getName());
+
+                if (type == COMMARIGHT) {
+                    next();
+                    importEntries = new ArrayList<>();
+                    if (type == MUL) {
+                        importEntries.add(nameSpaceImport());
+                    } else if (type == LBRACE) {
+                        importEntries.addAll(namedImports());
+                    } else {
+                        throw error(AbstractParser.message("expected.named.import"));
+                    }
+                } else {
+                    importEntries = Collections.singletonList(defaultImport);
+                }
+            } else {
+                throw error(AbstractParser.message("expected.import"));
+            }
+
+            final String moduleSpecifier = fromClause();
+            module.addModuleRequest(moduleSpecifier);
+            for (int i = 0; i < importEntries.size(); i++) {
+                module.addImportEntry(importEntries.get(i).withFrom(moduleSpecifier));
+            }
+        }
+        expect(SEMICOLON);
+    }
+
+    /**
+     * NameSpaceImport :
+     *     * as ImportedBinding
+     *
+     * @return imported binding identifier
+     */
+    private Module.ImportEntry nameSpaceImport() {
+        assert type == MUL;
+        next();
+        final long asToken = token;
+        final String as = (String) expectValue(IDENT);
+        if (!"as".equals(as)) {
+            throw error(AbstractParser.message("expected.as"), asToken);
+        }
+        final IdentNode localNameSpace = bindingIdentifier("ImportedBinding");
+        return Module.ImportEntry.importStarAsNameSpaceFrom(localNameSpace.getName());
+    }
+
+    /**
+     * NamedImports :
+     *     { }
+     *     { ImportsList }
+     *     { ImportsList , }
+     * ImportsList :
+     *     ImportSpecifier
+     *     ImportsList , ImportSpecifier
+     * ImportSpecifier :
+     *     ImportedBinding
+     *     IdentifierName as ImportedBinding
+     * ImportedBinding :
+     *     BindingIdentifier
+     */
+    private List<Module.ImportEntry> namedImports() {
+        assert type == LBRACE;
+        next();
+        List<Module.ImportEntry> importEntries = new ArrayList<>();
+        while (type != RBRACE) {
+            final boolean bindingIdentifier = isBindingIdentifier();
+            final long nameToken = token;
+            final IdentNode importName = getIdentifierName();
+            if (type == IDENT && "as".equals(getValue())) {
+                next();
+                final IdentNode localName = bindingIdentifier("ImportedBinding");
+                importEntries.add(Module.ImportEntry.importSpecifier(importName.getName(), localName.getName()));
+            } else if (!bindingIdentifier) {
+                throw error(AbstractParser.message("expected.binding.identifier"), nameToken);
+            } else {
+                importEntries.add(Module.ImportEntry.importSpecifier(importName.getName()));
+            }
+            if (type == COMMARIGHT) {
+                next();
+            } else {
+                break;
+            }
+        }
+        expect(RBRACE);
+        return importEntries;
+    }
+
+    /**
+     * FromClause :
+     *     from ModuleSpecifier
+     */
+    private String fromClause() {
+        final long fromToken = token;
+        final String name = (String) expectValue(IDENT);
+        if (!"from".equals(name)) {
+            throw error(AbstractParser.message("expected.from"), fromToken);
+        }
+        if (type == STRING || type == ESCSTRING) {
+            final String moduleSpecifier = (String) getValue();
+            next();
+            return moduleSpecifier;
+        } else {
+            throw error(expectMessage(STRING));
+        }
+    }
+
+    /**
+     * Parse export declaration.
+     *
+     * ExportDeclaration :
+     *     export * FromClause ;
+     *     export ExportClause FromClause ;
+     *     export ExportClause ;
+     *     export VariableStatement
+     *     export Declaration
+     *     export default HoistableDeclaration[Default]
+     *     export default ClassDeclaration[Default]
+     *     export default [lookahead !in {function, class}] AssignmentExpression[In] ;
+     */
+    private void exportDeclaration() {
+        expect(EXPORT);
+        final ParserContextModuleNode module = lc.getCurrentModule();
+        switch (type) {
+            case MUL: {
+                next();
+                final String moduleRequest = fromClause();
+                expect(SEMICOLON);
+                module.addModuleRequest(moduleRequest);
+                module.addStarExportEntry(Module.ExportEntry.exportStarFrom(moduleRequest));
+                break;
+            }
+            case LBRACE: {
+                final List<Module.ExportEntry> exportEntries = exportClause();
+                if (type == IDENT && "from".equals(getValue())) {
+                    final String moduleRequest = fromClause();
+                    module.addModuleRequest(moduleRequest);
+                    for (Module.ExportEntry exportEntry : exportEntries) {
+                        module.addIndirectExportEntry(exportEntry.withFrom(moduleRequest));
+                    }
+                } else {
+                    for (Module.ExportEntry exportEntry : exportEntries) {
+                        module.addLocalExportEntry(exportEntry);
+                    }
+                }
+                expect(SEMICOLON);
+                break;
+            }
+            case DEFAULT:
+                next();
+                final Expression assignmentExpression;
+                IdentNode ident;
+                final int lineNumber = line;
+                final long rhsToken = token;
+                final boolean declaration;
+                switch (type) {
+                    case FUNCTION:
+                        assignmentExpression = functionExpression(false, true);
+                        ident = ((FunctionNode) assignmentExpression).getIdent();
+                        declaration = true;
+                        break;
+                    case CLASS:
+                        assignmentExpression = classDeclaration(true);
+                        ident = ((ClassNode) assignmentExpression).getIdent();
+                        declaration = true;
+                        break;
+                    default:
+                        assignmentExpression = assignmentExpression(false);
+                        ident = null;
+                        declaration = false;
+                        break;
+                }
+                if (ident != null) {
+                    module.addLocalExportEntry(Module.ExportEntry.exportDefault(ident.getName()));
+                } else {
+                    ident = createIdentNode(Token.recast(rhsToken, IDENT), finish, Module.DEFAULT_EXPORT_BINDING_NAME);
+                    lc.appendStatementToCurrentNode(new VarNode(lineNumber, Token.recast(rhsToken, LET), finish, ident, assignmentExpression));
+                    if (!declaration) {
+                        expect(SEMICOLON);
+                    }
+                    module.addLocalExportEntry(Module.ExportEntry.exportDefault());
+                }
+                break;
+            case VAR:
+            case LET:
+            case CONST:
+                final List<Statement> statements = lc.getCurrentBlock().getStatements();
+                final int previousEnd = statements.size();
+                variableStatement(type);
+                for (final Statement statement : statements.subList(previousEnd, statements.size())) {
+                    if (statement instanceof VarNode) {
+                        module.addLocalExportEntry(Module.ExportEntry.exportSpecifier(((VarNode) statement).getName().getName()));
+                    }
+                }
+                break;
+            case CLASS: {
+                final ClassNode classDeclaration = classDeclaration(false);
+                module.addLocalExportEntry(Module.ExportEntry.exportSpecifier(classDeclaration.getIdent().getName()));
+                break;
+            }
+            case FUNCTION: {
+                final FunctionNode functionDeclaration = (FunctionNode) functionExpression(true, true);
+                module.addLocalExportEntry(Module.ExportEntry.exportSpecifier(functionDeclaration.getIdent().getName()));
+                break;
+            }
+            default:
+                throw error(AbstractParser.message("invalid.export"), token);
+        }
+    }
+
+    /**
+     * ExportClause :
+     *     { }
+     *     { ExportsList }
+     *     { ExportsList , }
+     * ExportsList :
+     *     ExportSpecifier
+     *     ExportsList , ExportSpecifier
+     * ExportSpecifier :
+     *     IdentifierName
+     *     IdentifierName as IdentifierName
+     *
+     * @return a list of ExportSpecifiers
+     */
+    private List<Module.ExportEntry> exportClause() {
+        assert type == LBRACE;
+        next();
+        List<Module.ExportEntry> exports = new ArrayList<>();
+        while (type != RBRACE) {
+            final IdentNode localName = getIdentifierName();
+            if (type == IDENT && "as".equals(getValue())) {
+                next();
+                final IdentNode exportName = getIdentifierName();
+                exports.add(Module.ExportEntry.exportSpecifier(exportName.getName(), localName.getName()));
+            } else {
+                exports.add(Module.ExportEntry.exportSpecifier(localName.getName()));
+            }
+            if (type == COMMARIGHT) {
+                next();
+            } else {
+                break;
+            }
+        }
+        expect(RBRACE);
+        return exports;
+    }
+
     @Override
     public String toString() {
         return "'JavaScript Parsing'";
@@ -3564,6 +5408,12 @@
             if (!flaggedCurrentFn) {
                 fn.setFlag(FunctionNode.HAS_EVAL);
                 flaggedCurrentFn = true;
+                if (fn.getKind() == FunctionNode.Kind.ARROW) {
+                    // possible use of this in an eval that's nested in an arrow function, e.g.:
+                    // function fun(){ return (() => eval("this"))(); };
+                    markThis(lc);
+                    markNewTarget(lc);
+                }
             } else {
                 fn.setFlag(FunctionNode.HAS_NESTED_EVAL);
             }
@@ -3583,4 +5433,55 @@
     private void appendStatement(final Statement statement) {
         lc.appendStatementToCurrentNode(statement);
     }
+
+    private static void markSuperCall(final ParserContext lc) {
+        final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
+        while (iter.hasNext()) {
+            final ParserContextFunctionNode fn = iter.next();
+            if (fn.getKind() != FunctionNode.Kind.ARROW) {
+                assert fn.isSubclassConstructor();
+                fn.setFlag(FunctionNode.ES6_HAS_DIRECT_SUPER);
+                break;
+            }
+        }
+    }
+
+    private ParserContextFunctionNode getCurrentNonArrowFunction() {
+        final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
+        while (iter.hasNext()) {
+            final ParserContextFunctionNode fn = iter.next();
+            if (fn.getKind() != FunctionNode.Kind.ARROW) {
+                return fn;
+            }
+        }
+        return null;
+    }
+
+    private static void markThis(final ParserContext lc) {
+        final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
+        while (iter.hasNext()) {
+            final ParserContextFunctionNode fn = iter.next();
+            fn.setFlag(FunctionNode.USES_THIS);
+            if (fn.getKind() != FunctionNode.Kind.ARROW) {
+                break;
+            }
+        }
+    }
+
+    private static void markNewTarget(final ParserContext lc) {
+        final Iterator<ParserContextFunctionNode> iter = lc.getFunctions();
+        while (iter.hasNext()) {
+            final ParserContextFunctionNode fn = iter.next();
+            if (fn.getKind() != FunctionNode.Kind.ARROW) {
+                if (!fn.isProgram()) {
+                    fn.setFlag(FunctionNode.ES6_USES_NEW_TARGET);
+                }
+                break;
+            }
+        }
+    }
+
+    private boolean inGeneratorFunction() {
+        return lc.getCurrentFunction().getKind() == FunctionNode.Kind.GENERATOR;
+    }
 }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/ParserContext.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/ParserContext.java	Thu Apr 28 23:08:16 2016 -0700
@@ -278,7 +278,12 @@
         return new NodeIterator<>(ParserContextFunctionNode.class);
     }
 
-    private class NodeIterator <T extends ParserContextNode> implements Iterator<T> {
+    public ParserContextModuleNode getCurrentModule() {
+        final Iterator<ParserContextModuleNode> iter = new NodeIterator<>(ParserContextModuleNode.class, getCurrentFunction());
+        return iter.hasNext() ? iter.next() : null;
+    }
+
+    private class NodeIterator<T extends ParserContextNode> implements Iterator<T> {
         private int index;
         private T next;
         private final Class<T> clazz;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/ParserContextFunctionNode.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/ParserContextFunctionNode.java	Thu Apr 28 23:08:16 2016 -0700
@@ -24,10 +24,12 @@
  */
 package jdk.nashorn.internal.parser;
 
+import java.util.HashSet;
 import java.util.List;
 import jdk.nashorn.internal.codegen.Namespace;
 import jdk.nashorn.internal.ir.FunctionNode;
 import jdk.nashorn.internal.ir.IdentNode;
+import jdk.nashorn.internal.ir.Module;
 
 /**
  * ParserContextNode that represents a function that is currently being parsed
@@ -46,11 +48,11 @@
     /** Line number for function declaration */
     private final int line;
 
-    /** Function node kind, see {@link FunctionNode#Kind} */
+    /** Function node kind, see {@link FunctionNode.Kind} */
     private final FunctionNode.Kind kind;
 
     /** List of parameter identifiers for function */
-    private final List<IdentNode> parameters;
+    private List<IdentNode> parameters;
 
     /** Token for function start */
     private final long token;
@@ -61,6 +63,14 @@
     /** Opaque node for parser end state, see {@link Parser} */
     private Object endParserState;
 
+    private HashSet<String> parameterBoundNames;
+    private IdentNode duplicateParameterBinding;
+    private boolean simpleParameterList = true;
+
+    private Module module;
+
+    private int debugFlags;
+
     /**
      * @param token The token for the function
      * @param ident External function name
@@ -155,6 +165,10 @@
         return parameters;
     }
 
+    void setParameters(List<IdentNode> parameters) {
+        this.parameters = parameters;
+    }
+
     /**
      * Set last token
      * @param token New last token
@@ -194,4 +208,70 @@
     public int getId() {
         return isProgram() ? -1 : Token.descPosition(token);
     }
+
+    /**
+     * Returns the debug flags for this function.
+     *
+     * @return the debug flags
+     */
+    int getDebugFlags() {
+        return debugFlags;
+    }
+
+    /**
+     * Sets a debug flag for this function.
+     *
+     * @param debugFlag the debug flag
+     */
+    void setDebugFlag(final int debugFlag) {
+        debugFlags |= debugFlag;
+    }
+
+    public boolean isMethod() {
+        return getFlag(FunctionNode.ES6_IS_METHOD) != 0;
+    }
+
+    public boolean isClassConstructor() {
+        return getFlag(FunctionNode.ES6_IS_CLASS_CONSTRUCTOR) != 0;
+    }
+
+    public boolean isSubclassConstructor() {
+        return getFlag(FunctionNode.ES6_IS_SUBCLASS_CONSTRUCTOR) != 0;
+    }
+
+    boolean addParameterBinding(final IdentNode bindingIdentifier) {
+        if (Parser.isArguments(bindingIdentifier)) {
+            setFlag(FunctionNode.DEFINES_ARGUMENTS);
+        }
+
+        if (parameterBoundNames == null) {
+            parameterBoundNames = new HashSet<>();
+        }
+        if (parameterBoundNames.add(bindingIdentifier.getName())) {
+            return true;
+        } else {
+            duplicateParameterBinding = bindingIdentifier;
+            return false;
+        }
+    }
+
+    public IdentNode getDuplicateParameterBinding() {
+        return duplicateParameterBinding;
+    }
+
+    public boolean isSimpleParameterList() {
+        return simpleParameterList;
+    }
+
+    public void setSimpleParameterList(final boolean simpleParameterList) {
+        this.simpleParameterList = simpleParameterList;
+    }
+
+    public Module getModule() {
+        return module;
+    }
+
+    public void setModule(final Module module) {
+        this.module = module;
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/ParserContextModuleNode.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2015, 2016, 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 jdk.nashorn.internal.parser;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jdk.nashorn.internal.ir.Module;
+import jdk.nashorn.internal.ir.Module.ExportEntry;
+import jdk.nashorn.internal.ir.Module.ImportEntry;
+
+/**
+ * ParserContextNode that represents a module.
+ */
+class ParserContextModuleNode extends ParserContextBaseNode {
+
+    /** Module name. */
+    private final String name;
+
+    private List<String> requestedModules = new ArrayList<>();
+    private List<ImportEntry> importEntries = new ArrayList<>();
+    private List<ExportEntry> localExportEntries = new ArrayList<>();
+    private List<ExportEntry> indirectExportEntries = new ArrayList<>();
+    private List<ExportEntry> starExportEntries = new ArrayList<>();
+
+    /**
+     * Constructor.
+     *
+     * @param name name of the module
+     */
+    ParserContextModuleNode(final String name) {
+        this.name = name;
+    }
+
+    /**
+     * Returns the name of the module.
+     *
+     * @return name of the module
+     */
+    public String getModuleName() {
+        return name;
+    }
+
+    public void addModuleRequest(final String moduleRequest) {
+        requestedModules.add(moduleRequest);
+    }
+
+    public void addImportEntry(final ImportEntry importEntry) {
+        importEntries.add(importEntry);
+    }
+
+    public void addLocalExportEntry(final ExportEntry exportEntry) {
+        localExportEntries.add(exportEntry);
+    }
+
+    public void addIndirectExportEntry(final ExportEntry exportEntry) {
+        indirectExportEntries.add(exportEntry);
+    }
+
+    public void addStarExportEntry(final ExportEntry exportEntry) {
+        starExportEntries.add(exportEntry);
+    }
+
+    public Module createModule() {
+        return new Module(requestedModules, importEntries, localExportEntries, indirectExportEntries, starExportEntries);
+    }
+}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/TokenType.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/TokenType.java	Thu Apr 28 23:08:16 2016 -0700
@@ -82,7 +82,7 @@
     ASSIGN         (BINARY,  "=",     2, false),
     EQ             (BINARY,  "==",    9, true),
     EQ_STRICT      (BINARY,  "===",   9, true),
-    BIND           (BINARY,  "=>",    9, true),
+    ARROW          (BINARY,  "=>",    2, true),
     GT             (BINARY,  ">",    10, true),
     GE             (BINARY,  ">=",   10, true),
     SAR            (BINARY,  ">>",   11, true),
@@ -100,6 +100,7 @@
     OR             (BINARY,  "||",    4, true),
     RBRACE         (BRACKET, "}"),
     BIT_NOT        (UNARY,   "~",     14, false),
+    ELLIPSIS       (UNARY,   "..."),
 
     // ECMA 7.6.1.1 Keywords, 7.6.1.2 Future Reserved Words.
     // All other Java keywords are commented out.
@@ -190,7 +191,10 @@
 
     COMMALEFT      (IR,       null),
     DECPOSTFIX     (IR,       null),
-    INCPOSTFIX     (IR,       null);
+    INCPOSTFIX     (IR,       null),
+    SPREAD_ARGUMENT(IR,       null),
+    SPREAD_ARRAY   (IR,       null),
+    YIELD_STAR     (IR,       null);
 
     /** Next token kind in token lookup table. */
     private TokenType next;
@@ -251,7 +255,6 @@
         return kind == BINARY && (!noIn || this != IN) && precedence != 0;
     }
 
-
     public int getLength() {
         assert name != null : "Token name not set";
         return name.length();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java	Thu Apr 28 23:08:16 2016 -0700
@@ -1403,11 +1403,11 @@
                 return null;
             }
 
-            if (env._print_ast || functionNode.getFlag(FunctionNode.IS_PRINT_AST)) {
+            if (env._print_ast || functionNode.getDebugFlag(FunctionNode.DEBUG_PRINT_AST)) {
                 getErr().println(new ASTWriter(functionNode));
             }
 
-            if (env._print_parse || functionNode.getFlag(FunctionNode.IS_PRINT_PARSE)) {
+            if (env._print_parse || functionNode.getDebugFlag(FunctionNode.DEBUG_PRINT_PARSE)) {
                 getErr().println(new PrintVisitor(functionNode, true, false));
             }
         }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/doubleconv/DtoaBuffer.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/doubleconv/DtoaBuffer.java	Thu Apr 28 23:08:16 2016 -0700
@@ -176,6 +176,8 @@
                     buffer.append('0');
                 }
                 buffer.append(chars, 0, length);
+            } else {
+                decimalPoint = 1;
             }
         } else if (decimalPoint >= length) {
             // large integer, add trailing zeroes
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Messages.properties	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Messages.properties	Thu Apr 28 23:08:16 2016 -0700
@@ -63,6 +63,27 @@
 parser.error.missing.const.assignment=Missing assignment to constant "{0}"
 parser.error.unterminated.template.expression=Expected } after expression in template literal
 
+# ES6 mode error messages
+parser.error.multiple.constructors=Class contains more than one constructor
+parser.error.generator.constructor=Class constructor must not be a generator
+parser.error.accessor.constructor=Class constructor must not be an accessor
+parser.error.static.prototype.method=Static class method must not be named 'prototype'
+parser.error.missing.destructuring.assignment=Missing assignment in destructuring declaration
+parser.error.let.binding.for='let' is not a valid binding name in a for loop
+parser.error.invalid.export=invalid export declaration
+parser.error.expected.binding=expected BindingIdentifier or BindingPattern
+parser.error.multiple.proto.key=property name __proto__ appears more than once in object literal
+parser.error.new.target.in.function=new.target expression is only allowed in functions
+parser.error.expected.target=expected 'target'
+parser.error.invalid.super=invalid use of keyword super
+parser.error.expected.arrow.parameter=expected arrow function parameter list
+parser.error.invalid.arrow.parameter=invalid arrow function parameter
+parser.error.expected.named.import=expected NameSpaceImport or NamedImports
+parser.error.expected.import=expected ImportClause or ModuleSpecifier
+parser.error.expected.as=expected 'as'
+parser.error.expected.binding.identifier=expected BindingIdentifier
+parser.error.expected.from=expected 'from'
+
 # strict mode error messages
 parser.error.strict.no.with="with" statement cannot be used in strict mode
 parser.error.strict.name="{0}" cannot be used as {1} in strict mode
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/tools/Shell.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/tools/Shell.java	Thu Apr 28 23:08:16 2016 -0700
@@ -438,6 +438,9 @@
                 final File file = new File(fileName);
                 final ScriptFunction script = context.compileScript(sourceFor(fileName, file), global);
                 if (script == null || errors.getNumberOfErrors() != 0) {
+                    if (context.getEnv()._parse_only && !errors.hasErrors()) {
+                        continue; // No error, continue to consume all files in list
+                    }
                     return COMPILATION_ERROR;
                 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8155025.js	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8155025: 0.001.toFixed(2) should return "0.00" not "0"
+ *
+ * @test
+ * @run
+ */
+
+for (var i = 0, zeros=""; i <= 9; i++, zeros += "0") {
+    var n = Number("0." + zeros + "1");
+    for (var j = 1; j <= i + 3; j++) {
+        print(n + ".toFixed(" + j + ")=" + n.toFixed(j));
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8155025.js.EXPECTED	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,75 @@
+0.1.toFixed(1)=0.1
+0.1.toFixed(2)=0.10
+0.1.toFixed(3)=0.100
+0.01.toFixed(1)=0.0
+0.01.toFixed(2)=0.01
+0.01.toFixed(3)=0.010
+0.01.toFixed(4)=0.0100
+0.001.toFixed(1)=0.0
+0.001.toFixed(2)=0.00
+0.001.toFixed(3)=0.001
+0.001.toFixed(4)=0.0010
+0.001.toFixed(5)=0.00100
+0.0001.toFixed(1)=0.0
+0.0001.toFixed(2)=0.00
+0.0001.toFixed(3)=0.000
+0.0001.toFixed(4)=0.0001
+0.0001.toFixed(5)=0.00010
+0.0001.toFixed(6)=0.000100
+0.00001.toFixed(1)=0.0
+0.00001.toFixed(2)=0.00
+0.00001.toFixed(3)=0.000
+0.00001.toFixed(4)=0.0000
+0.00001.toFixed(5)=0.00001
+0.00001.toFixed(6)=0.000010
+0.00001.toFixed(7)=0.0000100
+0.000001.toFixed(1)=0.0
+0.000001.toFixed(2)=0.00
+0.000001.toFixed(3)=0.000
+0.000001.toFixed(4)=0.0000
+0.000001.toFixed(5)=0.00000
+0.000001.toFixed(6)=0.000001
+0.000001.toFixed(7)=0.0000010
+0.000001.toFixed(8)=0.00000100
+1e-7.toFixed(1)=0.0
+1e-7.toFixed(2)=0.00
+1e-7.toFixed(3)=0.000
+1e-7.toFixed(4)=0.0000
+1e-7.toFixed(5)=0.00000
+1e-7.toFixed(6)=0.000000
+1e-7.toFixed(7)=0.0000001
+1e-7.toFixed(8)=0.00000010
+1e-7.toFixed(9)=0.000000100
+1e-8.toFixed(1)=0.0
+1e-8.toFixed(2)=0.00
+1e-8.toFixed(3)=0.000
+1e-8.toFixed(4)=0.0000
+1e-8.toFixed(5)=0.00000
+1e-8.toFixed(6)=0.000000
+1e-8.toFixed(7)=0.0000000
+1e-8.toFixed(8)=0.00000001
+1e-8.toFixed(9)=0.000000010
+1e-8.toFixed(10)=0.0000000100
+1e-9.toFixed(1)=0.0
+1e-9.toFixed(2)=0.00
+1e-9.toFixed(3)=0.000
+1e-9.toFixed(4)=0.0000
+1e-9.toFixed(5)=0.00000
+1e-9.toFixed(6)=0.000000
+1e-9.toFixed(7)=0.0000000
+1e-9.toFixed(8)=0.00000000
+1e-9.toFixed(9)=0.000000001
+1e-9.toFixed(10)=0.0000000010
+1e-9.toFixed(11)=0.00000000100
+1e-10.toFixed(1)=0.0
+1e-10.toFixed(2)=0.00
+1e-10.toFixed(3)=0.000
+1e-10.toFixed(4)=0.0000
+1e-10.toFixed(5)=0.00000
+1e-10.toFixed(6)=0.000000
+1e-10.toFixed(7)=0.0000000
+1e-10.toFixed(8)=0.00000000
+1e-10.toFixed(9)=0.000000000
+1e-10.toFixed(10)=0.0000000001
+1e-10.toFixed(11)=0.00000000010
+1e-10.toFixed(12)=0.000000000100
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/parser-es6.js	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8134503: support ES6 parsing in Nashorn
+ *
+ * @test
+ * @option --language=es6
+ * @option --parse-only
+ */
+
+
+[].map(v => v + 1);
+
+class A extends B.C {
+    constructor(a, b) {
+        super(a, b);
+    }
+    someMethod(c) {
+        super.someMethod();
+    }
+    get g() {
+        return this.g;
+    }
+    set s(t) {
+        this.t = t;
+    }
+    static m() {
+        return k;
+    }
+}
+
+var obj = {
+    __proto__: theProtoObj,
+    handler,
+    r() {
+        return super.m();
+    },
+    [ '__' + (() => 'x')() ]: 1,
+    *q (x, y) {
+       yield 1;
+    }
+};
+
+var [a, , b] = [1, 2, 3];
+
+var { x: a, y: { z: b }, w: c } = abc();
+
+var {a, b, c} = abc();
+
+var o = { x, y };
+
+function g({name: x}) {
+  return x;
+}
+
+foo(a, ...b);
+
+var c = [ ...s ];
+
+var [a] = [];
+
+var [a = 1] = [];
+
+
+var f = {
+    [Symbol.iterator]: function*() {
+        var cur = 1;
+        for (;;) {
+            yield cur;
+        }
+    }
+};
+
--- a/nashorn/test/script/basic/yield.js	Fri Apr 29 04:44:08 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * 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.
- */
-
-
-/**
- * Check yield keyword is parsed and yield statement does nothing (yet).
- *
- * @test
- * @run
- */
-
-function func() {
-    yield 2;
-}
--- a/nashorn/test/script/error/NASHORN-154/function_mult_params_in_strict.js.EXPECTED	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/test/script/error/NASHORN-154/function_mult_params_in_strict.js.EXPECTED	Thu Apr 28 23:08:16 2016 -0700
@@ -1,3 +1,3 @@
-test/script/error/NASHORN-154/function_mult_params_in_strict.js:38:14 strict mode function cannot have duplicate parameter name "x"
+test/script/error/NASHORN-154/function_mult_params_in_strict.js:38:17 strict mode function cannot have duplicate parameter name "x"
 function func(x, x) {}
-              ^
+                 ^
--- a/nashorn/test/script/nosecurity/parserapi.js.EXPECTED	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/test/script/nosecurity/parserapi.js.EXPECTED	Thu Apr 28 23:08:16 2016 -0700
@@ -100,7 +100,7 @@
             "startPosition": "1181",
             "properties": [
               {
-                "endPosition": "1185",
+                "endPosition": "1187",
                 "kind": "PROPERTY",
                 "value": {
                   "endPosition": "1187",
@@ -2386,7 +2386,7 @@
           "startPosition": "1139",
           "properties": [
             {
-              "endPosition": "1143",
+              "endPosition": "1146",
               "kind": "PROPERTY",
               "value": {
                 "endPosition": "1146",
@@ -2403,7 +2403,7 @@
               }
             },
             {
-              "endPosition": "1150",
+              "endPosition": "1152",
               "kind": "PROPERTY",
               "value": {
                 "endPosition": "1152",
@@ -2443,7 +2443,7 @@
           "startPosition": "1160",
           "properties": [
             {
-              "endPosition": "1166",
+              "endPosition": "1169",
               "kind": "PROPERTY",
               "value": {
                 "endPosition": "1169",
@@ -2460,7 +2460,7 @@
               }
             },
             {
-              "endPosition": "1175",
+              "endPosition": "1177",
               "kind": "PROPERTY",
               "value": {
                 "endPosition": "1177",
@@ -2914,7 +2914,7 @@
         "startPosition": "1178",
         "properties": [
           {
-            "endPosition": "1182",
+            "endPosition": "1184",
             "kind": "PROPERTY",
             "value": {
               "endPosition": "1184",
@@ -3395,7 +3395,7 @@
         "startPosition": "1200",
         "properties": [
           {
-            "endPosition": "1206",
+            "endPosition": "1214",
             "kind": "PROPERTY",
             "value": {
               "endPosition": "1214",
@@ -4709,11 +4709,11 @@
 ,
 {
   "fileName": "parsernegativetests/strict_repeatparam.js",
-  "code": "ident (1119, 1)",
-  "columnNumber": "14",
+  "code": "ident (1122, 1)",
+  "columnNumber": "17",
   "kind": "ERROR",
-  "position": "1119",
-  "message": "parsernegativetests/strict_repeatparam.js:31:14 strict mode function cannot have duplicate parameter name \"x\"\nfunction func(x, x) {}\n              ^",
+  "position": "1122",
+  "message": "parsernegativetests/strict_repeatparam.js:31:17 strict mode function cannot have duplicate parameter name \"x\"\nfunction func(x, x) {}\n                 ^",
   "lineNumber": "31"
 }
 ,
--- a/nashorn/test/script/nosecurity/parserapi_strict.js.EXPECTED	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/test/script/nosecurity/parserapi_strict.js.EXPECTED	Thu Apr 28 23:08:16 2016 -0700
@@ -6,10 +6,10 @@
 
 with({}) {}
        ^
-repeat_param.js:2:15 strict mode function cannot have duplicate parameter name "x"
+repeat_param.js:2:18 strict mode function cannot have duplicate parameter name "x"
 
 function func(x, x) {}
-               ^
+                  ^
 repeat_prop.js:2:22 Property "foo" already defined
 
 var obj = { foo: 34, foo: 'hello' };
--- a/nashorn/test/script/nosecurity/treeapi/array_literal.js.EXPECTED	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/test/script/nosecurity/treeapi/array_literal.js.EXPECTED	Thu Apr 28 23:08:16 2016 -0700
@@ -74,7 +74,7 @@
         "properties": [
           {
             "getter": "null",
-            "endPosition": "74",
+            "endPosition": "76",
             "kind": "PROPERTY",
             "setter": "null",
             "value": {
--- a/nashorn/test/script/nosecurity/treeapi/objectLiteral.js.EXPECTED	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/test/script/nosecurity/treeapi/objectLiteral.js.EXPECTED	Thu Apr 28 23:08:16 2016 -0700
@@ -6,7 +6,7 @@
     "properties": [
       {
         "getter": "null",
-        "endPosition": "8",
+        "endPosition": "12",
         "kind": "PROPERTY",
         "setter": "null",
         "value": {
@@ -38,7 +38,7 @@
     "properties": [
       {
         "getter": "null",
-        "endPosition": "34",
+        "endPosition": "37",
         "kind": "PROPERTY",
         "setter": "null",
         "value": {
@@ -57,7 +57,7 @@
       },
       {
         "getter": "null",
-        "endPosition": "41",
+        "endPosition": "43",
         "kind": "PROPERTY",
         "setter": "null",
         "value": {
@@ -83,7 +83,7 @@
     "properties": [
       {
         "getter": "null",
-        "endPosition": "57",
+        "endPosition": "60",
         "kind": "PROPERTY",
         "setter": "null",
         "value": {
@@ -102,7 +102,7 @@
       },
       {
         "getter": "null",
-        "endPosition": "66",
+        "endPosition": "68",
         "kind": "PROPERTY",
         "setter": "null",
         "value": {
--- a/nashorn/test/script/nosecurity/treeapi/property.js.EXPECTED	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/test/script/nosecurity/treeapi/property.js.EXPECTED	Thu Apr 28 23:08:16 2016 -0700
@@ -1,7 +1,7 @@
 [
   {
     "getter": "null",
-    "endPosition": "17",
+    "endPosition": "22",
     "kind": "PROPERTY",
     "setter": "null",
     "value": {
@@ -20,7 +20,7 @@
   },
   {
     "getter": "null",
-    "endPosition": "31",
+    "endPosition": "38",
     "kind": "PROPERTY",
     "setter": "null",
     "value": {
@@ -45,7 +45,7 @@
   },
   {
     "getter": "null",
-    "endPosition": "46",
+    "endPosition": "61",
     "kind": "PROPERTY",
     "setter": "null",
     "value": {
@@ -72,7 +72,7 @@
   },
   {
     "getter": "null",
-    "endPosition": "69",
+    "endPosition": "72",
     "kind": "PROPERTY",
     "setter": "null",
     "value": {
--- a/nashorn/test/script/nosecurity/treeapi/throw.js.EXPECTED	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/test/script/nosecurity/treeapi/throw.js.EXPECTED	Thu Apr 28 23:08:16 2016 -0700
@@ -80,7 +80,7 @@
       "properties": [
         {
           "getter": "null",
-          "endPosition": "97",
+          "endPosition": "105",
           "kind": "PROPERTY",
           "setter": "null",
           "value": {
--- a/nashorn/test/script/nosecurity/treeapi/with.js.EXPECTED	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/test/script/nosecurity/treeapi/with.js.EXPECTED	Thu Apr 28 23:08:16 2016 -0700
@@ -49,7 +49,7 @@
       "properties": [
         {
           "getter": "null",
-          "endPosition": "34",
+          "endPosition": "39",
           "kind": "PROPERTY",
           "setter": "null",
           "value": {
--- a/nashorn/test/src/jdk/nashorn/internal/test/framework/ScriptRunnable.java	Fri Apr 29 04:44:08 2016 +0200
+++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/ScriptRunnable.java	Thu Apr 28 23:08:16 2016 -0700
@@ -194,9 +194,9 @@
             pb.redirectError(errorFileHandle);
             final Process process = pb.start();
 
-            process.waitFor();
+            final int exitCode = process.waitFor();
 
-            if (errorFileHandle.length() > 0) {
+            if (exitCode != 0 || errorFileHandle.length() > 0) {
                 if (expectRunFailure) {
                     return;
                 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jtreg-ext/requires/VMProps.java	Thu Apr 28 23:08:16 2016 -0700
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2016, 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 requires;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * The Class to be invoked by jtreg prior Test Suite execution to
+ * collect information about VM.
+ * Properties set by this Class will be available in the @requires expressions.
+ */
+public class VMProps implements Callable<Map<String, String>> {
+
+    /**
+     * Collects information about VM properties.
+     * This method will be invoked by jtreg.
+     *
+     * @return Map of property-value pairs.
+     */
+    @Override
+    public Map<String, String> call() {
+        Map<String, String> map = new HashMap<>();
+        map.put("vm.flavor", vmFlavor());
+        map.put("vm.compMode", vmCompMode());
+        map.put("vm.bits", vmBits());
+        dump(map);
+        return map;
+    }
+
+    /**
+     * @return VM type value extracted from the "java.vm.name" property.
+     */
+    protected String vmFlavor() {
+        // E.g. "Java HotSpot(TM) 64-Bit Server VM"
+        String vmName = System.getProperty("java.vm.name");
+        if (vmName == null) {
+            return null;
+        }
+
+        Pattern startP = Pattern.compile(".* (\\S+) VM");
+        Matcher m = startP.matcher(vmName);
+        if (m.matches()) {
+            return m.group(1).toLowerCase();
+        }
+        return null;
+    }
+
+    /**
+     * @return VM compilation mode extracted from the "java.vm.info" property.
+     */
+    protected String vmCompMode() {
+        // E.g. "mixed mode"
+        String vmInfo = System.getProperty("java.vm.info");
+        if (vmInfo == null) {
+            return null;
+        }
+        int k = vmInfo.toLowerCase().indexOf(" mode");
+        if (k < 0) {
+            return null;
+        }
+        vmInfo = vmInfo.substring(0, k);
+        switch (vmInfo) {
+            case "mixed" : return "Xmixed";
+            case "compiled" : return "Xcomp";
+            case "interpreted" : return "Xint";
+            default: return null;
+        }
+    }
+
+    /**
+     * @return VM bitness, the value of the "sun.arch.data.model" property.
+     */
+    protected String vmBits() {
+        return System.getProperty("sun.arch.data.model");
+    }
+
+    /**
+     * Dumps the map to the file if the file name is given as the property.
+     * This functionality could be helpful to know context in the real
+     * execution.
+     *
+     * @param map
+     */
+    protected void dump(Map<String, String> map) {
+        String dumpFileName = System.getProperty("vmprops.dump");
+        if (dumpFileName == null) {
+            return;
+        }
+        List<String> lines = new ArrayList<>();
+        map.forEach((k,v) -> lines.add(k + ":" + v));
+        try {
+             Files.write(Paths.get(dumpFileName), lines);
+        } catch (IOException e) {
+            throw new RuntimeException("Failed to dump properties into '"
+                    + dumpFileName + "'", e);
+        }
+    }
+
+    /**
+     * This method is for the testing purpose only.
+     * @param args
+     */
+    public static void main(String args[]) {
+        Map<String, String> map = new VMProps().call();
+        map.forEach((k,v) -> System.out.println(k + ": '" + v + "'"));
+    }
+}