Merge
authorprr
Thu, 12 May 2016 11:03:07 -0700
changeset 38414 3e22d8fd4912
parent 38413 d9e49b45fd7d (current diff)
parent 37898 ac36c71a44f9 (diff)
child 38415 acea5f7d354b
Merge
jdk/make/non-build-utils/src/build/tools/makeclasslist/makeClasslist.js
jdk/make/src/classes/build/tools/addjsum/AddJsum.java
jdk/src/java.base/share/classes/java/util/regex/UnicodeProp.java
jdk/src/java.httpclient/share/classes/java/net/http/CharsetToolkit.java
jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/CGIHandler.java
jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/HttpAwareServerSocket.java
jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/HttpInputStream.java
jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/HttpOutputStream.java
jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/HttpReceiveSocket.java
jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/HttpSendInputStream.java
jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/HttpSendOutputStream.java
jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/HttpSendSocket.java
jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/RMIDirectSocketFactory.java
jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/RMIHttpToCGISocketFactory.java
jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/RMIHttpToPortSocketFactory.java
jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/RMIMasterSocketFactory.java
jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/RMISocketInfo.java
jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/WrappedSocket.java
jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SortResourcesPlugin.java
jdk/test/java/rmi/transport/httpSocket/HttpSocketTest.java
jdk/test/java/rmi/transport/httpSocket/HttpSocketTest_Stub.java
jdk/test/java/rmi/transport/httpSocket/security.policy
jdk/test/java/util/jar/JarFile/MultiReleaseJarAPI.java
jdk/test/java/util/jar/JarFile/MultiReleaseJarHttpProperties.java
jdk/test/java/util/jar/JarFile/MultiReleaseJarIterators.java
jdk/test/java/util/jar/JarFile/MultiReleaseJarProperties.java
jdk/test/java/util/jar/JarFile/MultiReleaseJarSecurity.java
jdk/test/sun/rmi/transport/proxy/DisableHttpDefaultValue.java
jdk/test/sun/rmi/transport/proxy/EagerHttpFallback.java
jdk/test/sun/rmi/transport/tcp/blockAccept/BlockAcceptTest.java
jdk/test/sun/rmi/transport/tcp/blockAccept/TestIface.java
jdk/test/sun/rmi/transport/tcp/blockAccept/TestImpl.java
jdk/test/sun/rmi/transport/tcp/blockAccept/TestImpl_Stub.java
jdk/test/sun/rmi/transport/tcp/blockAccept/security.policy
jdk/test/tools/jlink/plugins/SorterPluginTest.java
--- a/.hgtags	Thu May 12 20:43:37 2016 +0400
+++ b/.hgtags	Thu May 12 11:03:07 2016 -0700
@@ -359,3 +359,4 @@
 c84d0cce090e161d736de69e941830adf8c2f87a jdk-9+114
 8d78fb40648dd221ce4ef19f9d5aa41ee1a3a884 jdk-9+115
 84aba7335005a3a47751dcf1f37935f97df9f99a jdk-9+116
+82b8d12a553f5617737c238cec060281d52e351c jdk-9+117
--- a/.hgtags-top-repo	Thu May 12 20:43:37 2016 +0400
+++ b/.hgtags-top-repo	Thu May 12 11:03:07 2016 -0700
@@ -359,3 +359,4 @@
 1d992540870ff33fe6cc550443388588df9b9e4f jdk-9+114
 09617ce980b99d49abfd54dacfed353c47e2a115 jdk-9+115
 6743a8e0cab7b5f6f4a0575f6664892f0ab740af jdk-9+116
+e882bcdbdac436523f3d5681611d3118a3804ea7 jdk-9+117
--- a/common/autoconf/boot-jdk.m4	Thu May 12 20:43:37 2016 +0400
+++ b/common/autoconf/boot-jdk.m4	Thu May 12 11:03:07 2016 -0700
@@ -435,6 +435,9 @@
       elif test ! -x "$BUILD_JDK/bin/jlink"; then
         AC_MSG_NOTICE([Potential Build JDK found at $BUILD_JDK did not contain bin/jlink; ignoring])
         BUILD_JDK_FOUND=no
+      elif test ! -x "$BUILD_JDK/bin/jmod"; then
+        AC_MSG_NOTICE([Potential Build JDK found at $BUILD_JDK did not contain bin/jmod; ignoring])
+        BUILD_JDK_FOUND=no
       elif test ! -x "$BUILD_JDK/bin/javac"; then
         # Do we have a bin/javac?
         AC_MSG_NOTICE([Potential Build JDK found at $BUILD_JDK did not contain bin/javac; ignoring])
@@ -474,7 +477,8 @@
   AC_ARG_WITH(build-jdk, [AS_HELP_STRING([--with-build-jdk],
       [path to JDK of same version as is being built@<:@the newly built JDK@:>@])])
 
-  CREATE_BUILDJDK_FOR_HOST=false
+  CREATE_BUILDJDK=false
+  EXTERNAL_BUILDJDK=false
   BUILD_JDK_FOUND="no"
   if test "x$with_build_jdk" != "x"; then
     BOOTJDK_CHECK_BUILD_JDK([
@@ -483,6 +487,7 @@
          BUILD_JDK_FOUND=maybe
          AC_MSG_NOTICE([Found potential Build JDK using configure arguments])
        fi])
+    EXTERNAL_BUILDJDK=true
   else
     if test "x$COMPILE_TYPE" = "xcross"; then
       BUILD_JDK="\$(BUILDJDK_OUTPUTDIR)/jdk"
@@ -498,6 +503,11 @@
     fi
   fi
 
+  JMOD="$BUILD_JDK/bin/jmod"
+  JLINK="$BUILD_JDK/bin/jlink"
+  AC_SUBST(JMOD)
+  AC_SUBST(JLINK)
+
   if test "x$BUILD_JDK_FOUND" != "xyes"; then
     AC_MSG_CHECKING([for Build JDK])
     AC_MSG_RESULT([no])
@@ -506,4 +516,5 @@
 
   AC_SUBST(CREATE_BUILDJDK)
   AC_SUBST(BUILD_JDK)
+  AC_SUBST(EXTERNAL_BUILDJDK)
 ])
--- a/common/autoconf/buildjdk-spec.gmk.in	Thu May 12 20:43:37 2016 +0400
+++ b/common/autoconf/buildjdk-spec.gmk.in	Thu May 12 11:03:07 2016 -0700
@@ -46,6 +46,7 @@
 HOTSPOT_DIST := $(patsubst $(BUILD_OUTPUT)%,$(BUILDJDK_OUTPUTDIR)%,$(HOTSPOT_DIST))
 SUPPORT_OUTPUTDIR := $(patsubst $(BUILD_OUTPUT)%,$(BUILDJDK_OUTPUTDIR)%,$(SUPPORT_OUTPUTDIR))
 JDK_OUTPUTDIR := $(patsubst $(BUILD_OUTPUT)%,$(BUILDJDK_OUTPUTDIR)%,$(JDK_OUTPUTDIR))
+IMAGES_OUTPUTDIR := $(patsubst $(BUILD_OUTPUT)%,$(BUILDJDK_OUTPUTDIR)%,$(IMAGES_OUTPUTDIR))
 
 OPENJDK_BUILD_CPU_LEGACY := @OPENJDK_BUILD_CPU_LEGACY@
 OPENJDK_BUILD_CPU_LEGACY_LIB := @OPENJDK_BUILD_CPU_LEGACY_LIB@
--- a/common/autoconf/generated-configure.sh	Thu May 12 20:43:37 2016 +0400
+++ b/common/autoconf/generated-configure.sh	Thu May 12 11:03:07 2016 -0700
@@ -896,8 +896,11 @@
 JAXP_TOPDIR
 CORBA_TOPDIR
 LANGTOOLS_TOPDIR
+EXTERNAL_BUILDJDK
 BUILD_JDK
 CREATE_BUILDJDK
+JLINK
+JMOD
 BOOT_JDK_BITS
 JAVAC_FLAGS
 BOOT_JDK_MODULAR
@@ -5070,7 +5073,7 @@
 #CUSTOM_AUTOCONF_INCLUDE
 
 # Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1462204427
+DATE_WHEN_GENERATED=1462806878
 
 ###############################################################################
 #
@@ -30171,7 +30174,8 @@
 fi
 
 
-  CREATE_BUILDJDK_FOR_HOST=false
+  CREATE_BUILDJDK=false
+  EXTERNAL_BUILDJDK=false
   BUILD_JDK_FOUND="no"
   if test "x$with_build_jdk" != "x"; then
 
@@ -30196,6 +30200,10 @@
         { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Build JDK found at $BUILD_JDK did not contain bin/jlink; ignoring" >&5
 $as_echo "$as_me: Potential Build JDK found at $BUILD_JDK did not contain bin/jlink; ignoring" >&6;}
         BUILD_JDK_FOUND=no
+      elif test ! -x "$BUILD_JDK/bin/jmod"; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Build JDK found at $BUILD_JDK did not contain bin/jmod; ignoring" >&5
+$as_echo "$as_me: Potential Build JDK found at $BUILD_JDK did not contain bin/jmod; ignoring" >&6;}
+        BUILD_JDK_FOUND=no
       elif test ! -x "$BUILD_JDK/bin/javac"; then
         # Do we have a bin/javac?
         { $as_echo "$as_me:${as_lineno-$LINENO}: Potential Build JDK found at $BUILD_JDK did not contain bin/javac; ignoring" >&5
@@ -30364,6 +30372,7 @@
     fi # end check build jdk found
   fi
 
+    EXTERNAL_BUILDJDK=true
   else
     if test "x$COMPILE_TYPE" = "xcross"; then
       BUILD_JDK="\$(BUILDJDK_OUTPUTDIR)/jdk"
@@ -30383,6 +30392,11 @@
     fi
   fi
 
+  JMOD="$BUILD_JDK/bin/jmod"
+  JLINK="$BUILD_JDK/bin/jlink"
+
+
+
   if test "x$BUILD_JDK_FOUND" != "xyes"; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Build JDK" >&5
 $as_echo_n "checking for Build JDK... " >&6; }
@@ -30395,6 +30409,7 @@
 
 
 
+
 ###############################################################################
 #
 # Configure the sources to use. We can add or override individual directories.
--- a/common/autoconf/spec.gmk.in	Thu May 12 20:43:37 2016 +0400
+++ b/common/autoconf/spec.gmk.in	Thu May 12 11:03:07 2016 -0700
@@ -283,6 +283,7 @@
 
 BUILD_JDK:=@BUILD_JDK@
 CREATE_BUILDJDK:=@CREATE_BUILDJDK@
+EXTERNAL_BUILDJDK:=@EXTERNAL_BUILDJDK@
 
 # When compiling Java source to be run by the boot jdk
 # use these extra flags, eg -source 6 -target 6
@@ -542,6 +543,8 @@
 JAVAC_CMD:=@JAVAC@
 JAVAH_CMD:=@JAVAH@
 JAR_CMD:=@JAR@
+JLINK_CMD := @JLINK@
+JMOD_CMD := @JMOD@
 JARSIGNER_CMD:=@JARSIGNER@
 SJAVAC_SERVER_JAVA_CMD:=@SJAVAC_SERVER_JAVA@
 # These variables are meant to be used. They are defined with = instead of := to make
@@ -552,6 +555,8 @@
 JAVAC=@FIXPATH@ $(JAVAC_CMD)
 JAVAH=@FIXPATH@ $(JAVAH_CMD)
 JAR=@FIXPATH@ $(JAR_CMD)
+JLINK = @FIXPATH@ $(JLINK_CMD) $(JAVA_TOOL_FLAGS_SMALL)
+JMOD = @FIXPATH@ $(JMOD_CMD) $(JAVA_TOOL_FLAGS_SMALL)
 JARSIGNER=@FIXPATH@ $(JARSIGNER_CMD)
 # A specific java binary with specific options can be used to run
 # the long running background sjavac servers and other long running tasks.
@@ -569,14 +574,15 @@
 # Use ?= as this can be overridden from bootcycle-spec.gmk
 BOOT_JDK_MODULAR ?= @BOOT_JDK_MODULAR@
 
+INTERIM_OVERRIDE_MODULES := java.compiler jdk.compiler \
+    jdk.jdeps jdk.javadoc jdk.rmic
 ifeq ($(BOOT_JDK_MODULAR), true)
-  INTERIM_OVERRIDE_MODULES_ARGS = -Xpatch:$(BUILDTOOLS_OUTPUTDIR)/override_modules
+  INTERIM_OVERRIDE_MODULES_ARGS = $(foreach m, $(INTERIM_OVERRIDE_MODULES), \
+      -Xpatch:$m=$(BUILDTOOLS_OUTPUTDIR)/override_modules/$m)
   INTERIM_LANGTOOLS_ARGS = $(INTERIM_OVERRIDE_MODULES_ARGS)
   JAVAC_MAIN_CLASS = -m jdk.compiler/com.sun.tools.javac.Main
   JAVADOC_MAIN_CLASS = -m jdk.javadoc/jdk.javadoc.internal.tool.Main
 else
-  INTERIM_OVERRIDE_MODULES := java.compiler jdk.compiler \
-      jdk.jdeps jdk.javadoc jdk.rmic
   INTERIM_OVERRIDE_MODULES_ARGS = \
       -Xbootclasspath/p:$(call PathList, \
           $(addprefix $(BUILDTOOLS_OUTPUTDIR)/override_modules/, \
@@ -591,12 +597,8 @@
 NEW_JAVAC   = $(INTERIM_LANGTOOLS_ARGS) $(JAVAC_MAIN_CLASS)
 NEW_JAVADOC = $(INTERIM_LANGTOOLS_ARGS) $(JAVADOC_MAIN_CLASS)
 
-# JLink/Jmod are run using the BUILD_JDK, which is normally the jdk output dir.
 JLINK_KEEP_PACKAGED_MODULES:=@JLINK_KEEP_PACKAGED_MODULES@
 
-JLINK = @FIXPATH@ $(BUILD_JDK)/bin/jlink $(JAVA_TOOL_FLAGS_SMALL)
-JMOD = @FIXPATH@ $(BUILD_JDK)/bin/jmod $(JAVA_TOOL_FLAGS_SMALL)
-
 # Base flags for RC
 # Guarding this against resetting value. Legacy make files include spec multiple
 # times.
@@ -776,6 +778,9 @@
 SYMBOLS_IMAGE_SUBDIR:=symbols
 SYMBOLS_IMAGE_DIR=$(IMAGES_OUTPUTDIR)/$(SYMBOLS_IMAGE_SUBDIR)
 
+# Interim image
+INTERIM_IMAGE_DIR := $(SUPPORT_OUTPUTDIR)/interim-image
+
 # Macosx bundles directory definitions
 JDK_MACOSX_BUNDLE_SUBDIR=jdk-bundle/jdk-$(VERSION_NUMBER).jdk/Contents
 JRE_MACOSX_BUNDLE_SUBDIR=jre-bundle/jre-$(VERSION_NUMBER).jre/Contents
--- a/common/conf/jib-profiles.js	Thu May 12 20:43:37 2016 +0400
+++ b/common/conf/jib-profiles.js	Thu May 12 11:03:07 2016 -0700
@@ -404,7 +404,7 @@
         jtreg: {
             server: "javare",
             revision: "4.2",
-            build_number: "b01",
+            build_number: "b02",
             checksum_file: "MD5_VALUES",
             file: "jtreg_bin-4.2.zip",
             environment_name: "JT_HOME"
--- a/corba/.hgtags	Thu May 12 20:43:37 2016 +0400
+++ b/corba/.hgtags	Thu May 12 11:03:07 2016 -0700
@@ -359,3 +359,4 @@
 10d175b0368c30f54350fc648adc41b94ce357ee jdk-9+114
 7bab1b1b36824924b1c657a8419369ba93d198d3 jdk-9+115
 7dfa7377a5e601b8f740741a9a80e04c72dd04d6 jdk-9+116
+7a1b36bf2fe55a9a7732489ccdd326c910329a7e jdk-9+117
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/presentation/rmi/StubFactoryDynamicBase.java	Thu May 12 20:43:37 2016 +0400
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/presentation/rmi/StubFactoryDynamicBase.java	Thu May 12 11:03:07 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2013 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
--- a/corba/src/java.corba/share/classes/com/sun/tools/corba/se/idl/som/cff/FileLocator.java	Thu May 12 20:43:37 2016 +0400
+++ b/corba/src/java.corba/share/classes/com/sun/tools/corba/se/idl/som/cff/FileLocator.java	Thu May 12 11:03:07 2016 -0700
@@ -222,7 +222,8 @@
 
     /**
      * locateFileInClassPath returns a DataInputStream that can be used
-     * to read the requested file.  The CLASSPATH is used to locate the file.
+     * to read the requested file.  The resource is located in the java.corba
+     * module or if not found, then the CLASSPATH is searched.
      *
      * @param fileName The name of the file to locate.  The file name
      * may be qualified with a partial path name, using '/' as the separator
@@ -238,6 +239,12 @@
     public static DataInputStream locateFileInClassPath (String fileName)
         throws FileNotFoundException, IOException {
 
+        // The resource should be in the java.corba module
+        InputStream in = FileLocator.class.getResourceAsStream("/" + fileName);
+        if (in != null) {
+            return new DataInputStream(in);
+        }
+
         boolean notFound = true;
         StringTokenizer st;
         String path = "";
--- a/corba/src/java.corba/share/classes/module-info.java	Thu May 12 20:43:37 2016 +0400
+++ b/corba/src/java.corba/share/classes/module-info.java	Thu May 12 11:03:07 2016 -0700
@@ -71,7 +71,4 @@
         java.naming;
     exports com.sun.jndi.url.iiopname to
         java.naming;
-
-    provides javax.naming.spi.InitialContextFactory
-        with com.sun.jndi.cosnaming.CNCtxFactory;
 }
--- a/hotspot/.hgtags	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/.hgtags	Thu May 12 11:03:07 2016 -0700
@@ -519,3 +519,4 @@
 b64432bae5271735fd53300b2005b713e98ef411 jdk-9+114
 88dd08d7be0fe7fb9f1914b1628f0aae9bf56e25 jdk-9+115
 61a214186dae6811dd989e9165e42f7dbf02acde jdk-9+116
+88170d3642905b9e6cac03e8efcc976885a7e6da jdk-9+117
--- a/hotspot/src/share/vm/classfile/classLoader.cpp	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp	Thu May 12 11:03:07 2016 -0700
@@ -140,9 +140,10 @@
 PerfCounter*    ClassLoader::_isUnsyncloadClass = NULL;
 PerfCounter*    ClassLoader::_load_instance_class_failCounter = NULL;
 
-ClassPathEntry* ClassLoader::_first_entry         = NULL;
-ClassPathEntry* ClassLoader::_last_entry          = NULL;
-int             ClassLoader::_num_entries         = 0;
+GrowableArray<ModuleClassPathList*>* ClassLoader::_xpatch_entries = NULL;
+ClassPathEntry* ClassLoader::_first_entry        = NULL;
+ClassPathEntry* ClassLoader::_last_entry         = NULL;
+int             ClassLoader::_num_entries        = 0;
 ClassPathEntry* ClassLoader::_first_append_entry = NULL;
 bool            ClassLoader::_has_jimage = false;
 #if INCLUDE_CDS
@@ -179,6 +180,44 @@
   return (strncmp(str + (str_len - str_to_find_len), str_to_find, str_to_find_len) == 0);
 }
 
+// Used to obtain the package name from a fully qualified class name.
+// It is the responsibility of the caller to establish ResourceMark.
+const char* ClassLoader::package_from_name(const char* class_name) {
+  const char* last_slash = strrchr(class_name, '/');
+  if (last_slash == NULL) {
+    // No package name
+    return NULL;
+  }
+  int length = last_slash - class_name;
+
+  // A class name could have just the slash character in the name,
+  // resulting in a negative length.
+  if (length <= 0) {
+    // No package name
+    return NULL;
+  }
+
+  // drop name after last slash (including slash)
+  // Ex., "java/lang/String.class" => "java/lang"
+  char* pkg_name = NEW_RESOURCE_ARRAY(char, length + 1);
+  strncpy(pkg_name, class_name, length);
+  *(pkg_name+length) = '\0';
+
+  return (const char *)pkg_name;
+}
+
+// Given a fully qualified class name, find its defining package in the class loader's
+// package entry table.
+static PackageEntry* get_package_entry(const char* class_name, ClassLoaderData* loader_data, TRAPS) {
+  ResourceMark rm(THREAD);
+  const char *pkg_name = ClassLoader::package_from_name(class_name);
+  if (pkg_name == NULL) {
+    return NULL;
+  }
+  PackageEntryTable* pkgEntryTable = loader_data->packages();
+  TempNewSymbol pkg_symbol = SymbolTable::new_symbol(pkg_name, CHECK_NULL);
+  return pkgEntryTable->lookup_only(pkg_symbol);
+}
 
 ClassPathDirEntry::ClassPathDirEntry(const char* dir) : ClassPathEntry() {
   char* copy = NEW_C_HEAP_ARRAY(char, strlen(dir)+1, mtClass);
@@ -281,8 +320,7 @@
 #if INCLUDE_CDS
 u1* ClassPathZipEntry::open_versioned_entry(const char* name, jint* filesize, TRAPS) {
   u1* buffer = NULL;
-  if (!_is_boot_append) {
-    assert(DumpSharedSpaces, "Should be called only for non-boot entries during dump time");
+  if (DumpSharedSpaces) {
     // We presume default is multi-release enabled
     const char* multi_ver = Arguments::get_property("jdk.util.jar.enableMultiRelease");
     const char* verstr = Arguments::get_property("jdk.util.jar.version");
@@ -402,31 +440,6 @@
   }
 }
 
-void ClassPathImageEntry::name_to_package(const char* name, char* buffer, int length) {
-  const char *pslash = strrchr(name, '/');
-  if (pslash == NULL) {
-    buffer[0] = '\0';
-    return;
-  }
-  int len = pslash - name;
-#if INCLUDE_CDS
-  if (len <= 0 && DumpSharedSpaces) {
-    buffer[0] = '\0';
-    return;
-  }
-#endif
-  assert(len > 0, "Bad length for package name");
-  if (len >= length) {
-    buffer[0] = '\0';
-    return;
-  }
-  // drop name after last slash (including slash)
-  // Ex., "java/lang/String.class" => "java/lang"
-  strncpy(buffer, name, len);
-  // ensure string termination (strncpy does not guarantee)
-  buffer[len] = '\0';
-}
-
 // For a class in a named module, look it up in the jimage file using this syntax:
 //    /<module-name>/<package-name>/<base-class>
 //
@@ -439,15 +452,10 @@
   JImageLocationRef location = (*JImageFindResource)(_jimage, "", get_jimage_version_string(), name, &size);
 
   if (location == 0) {
-    char package[JIMAGE_MAX_PATH];
-    name_to_package(name, package, JIMAGE_MAX_PATH);
+    ResourceMark rm;
+    const char* pkg_name = ClassLoader::package_from_name(name);
 
-#if INCLUDE_CDS
-    if (package[0] == '\0' && DumpSharedSpaces) {
-      return NULL;
-    }
-#endif
-    if (package[0] != '\0') {
+    if (pkg_name != NULL) {
       if (!Universe::is_module_initialized()) {
         location = (*JImageFindResource)(_jimage, "java.base", get_jimage_version_string(), name, &size);
 #if INCLUDE_CDS
@@ -455,7 +463,7 @@
         // modules defined for other class loaders.  So, for now, get their module
         // names from the "modules" jimage file.
         if (DumpSharedSpaces && location == 0) {
-          const char* module_name = (*JImagePackageToModule)(_jimage, package);
+          const char* module_name = (*JImagePackageToModule)(_jimage, pkg_name);
           if (module_name != NULL) {
             location = (*JImageFindResource)(_jimage, module_name, get_jimage_version_string(), name, &size);
           }
@@ -463,13 +471,7 @@
 #endif
 
       } else {
-        // Get boot class loader's package entry table
-        PackageEntryTable* pkgEntryTable =
-          ClassLoaderData::the_null_class_loader_data()->packages();
-        // Get package's package entry
-        TempNewSymbol pkg_symbol = SymbolTable::new_symbol(package, CHECK_NULL);
-        PackageEntry* package_entry = pkgEntryTable->lookup_only(pkg_symbol);
-
+        PackageEntry* package_entry = get_package_entry(name, ClassLoaderData::the_null_class_loader_data(), THREAD);
         if (package_entry != NULL) {
           ResourceMark rm;
           // Get the module name
@@ -542,6 +544,33 @@
 }
 #endif
 
+ModuleClassPathList::ModuleClassPathList(Symbol* module_name) {
+  _module_name = module_name;
+  _module_first_entry = NULL;
+  _module_last_entry = NULL;
+}
+
+ModuleClassPathList::~ModuleClassPathList() {
+  // Clean out each ClassPathEntry on list
+  ClassPathEntry* e = _module_first_entry;
+  while (e != NULL) {
+    ClassPathEntry* next_entry = e->next();
+    delete e;
+    e = next_entry;
+  }
+}
+
+void ModuleClassPathList::add_to_list(ClassPathEntry* new_entry) {
+  if (new_entry != NULL) {
+    if (_module_last_entry == NULL) {
+      _module_first_entry = _module_last_entry = new_entry;
+    } else {
+      _module_last_entry->set_next(new_entry);
+      _module_last_entry = new_entry;
+    }
+  }
+}
+
 void ClassLoader::trace_class_path(const char* msg, const char* name) {
   if (log_is_enabled(Info, classpath)) {
     ResourceMark rm;
@@ -619,6 +648,61 @@
 }
 #endif
 
+// Construct the array of module/path pairs as specified to -Xpatch
+// for the boot loader to search ahead of the jimage, if the class being
+// loaded is defined to a module that has been specified to -Xpatch.
+void ClassLoader::setup_xpatch_entries() {
+  Thread* THREAD = Thread::current();
+  GrowableArray<ModuleXPatchPath*>* xpatch_args = Arguments::get_xpatchprefix();
+  int num_of_entries = xpatch_args->length();
+
+  // Set up the boot loader's xpatch_entries list
+  _xpatch_entries = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<ModuleClassPathList*>(num_of_entries, true);
+
+  for (int i = 0; i < num_of_entries; i++) {
+    const char* module_name = (xpatch_args->at(i))->module_name();
+    Symbol* const module_sym = SymbolTable::lookup(module_name, (int)strlen(module_name), CHECK);
+    assert(module_sym != NULL, "Failed to obtain Symbol for module name");
+    ModuleClassPathList* module_cpl = new ModuleClassPathList(module_sym);
+
+    char* class_path = (xpatch_args->at(i))->path_string();
+    int len = (int)strlen(class_path);
+    int end = 0;
+    // Iterate over the module's class path entries
+    for (int start = 0; start < len; start = end) {
+      while (class_path[end] && class_path[end] != os::path_separator()[0]) {
+        end++;
+      }
+      EXCEPTION_MARK;
+      ResourceMark rm(THREAD);
+      char* path = NEW_RESOURCE_ARRAY(char, end - start + 1);
+      strncpy(path, &class_path[start], end - start);
+      path[end - start] = '\0';
+
+      struct stat st;
+      if (os::stat(path, &st) == 0) {
+        // File or directory found
+        Thread* THREAD = Thread::current();
+        ClassPathEntry* new_entry = create_class_path_entry(path, &st, false, false, CHECK);
+        // If the path specification is valid, enter it into this module's list
+        if (new_entry != NULL) {
+          module_cpl->add_to_list(new_entry);
+        }
+      }
+
+      while (class_path[end] == os::path_separator()[0]) {
+        end++;
+      }
+    }
+
+    // Record the module into the list of -Xpatch entries only if
+    // valid ClassPathEntrys have been created
+    if (module_cpl->module_first_entry() != NULL) {
+      _xpatch_entries->push(module_cpl);
+    }
+  }
+}
+
 void ClassLoader::setup_search_path(const char *class_path, bool bootstrap_search) {
   int offset = 0;
   int len = (int)strlen(class_path);
@@ -850,8 +934,29 @@
 }
 
 void ClassLoader::print_bootclasspath() {
-  ClassPathEntry* e = _first_entry;
+  ClassPathEntry* e;
   tty->print("[bootclasspath= ");
+
+  // Print -Xpatch module/path specifications first
+  if (_xpatch_entries != NULL) {
+    ResourceMark rm;
+    int num_of_entries = _xpatch_entries->length();
+    for (int i = 0; i < num_of_entries; i++) {
+      ModuleClassPathList* mpl = _xpatch_entries->at(i);
+      tty->print("%s=", mpl->module_name()->as_C_string());
+      e = mpl->module_first_entry();
+      while (e != NULL) {
+        tty->print("%s", e->name());
+        e = e->next();
+        if (e != NULL) {
+          tty->print("%s", os::path_separator());
+        }
+      }
+      tty->print(" ;");
+    }
+  }
+
+  e = _first_entry;
   while (e != NULL) {
     tty->print("%s ;", e->name());
     e = e->next();
@@ -941,6 +1046,7 @@
 
 #if INCLUDE_CDS
 void ClassLoader::initialize_module_loader_map(JImageFile* jimage) {
+  ResourceMark rm;
   jlong size;
   JImageLocationRef location = (*JImageFindResource)(jimage, "java.base", get_jimage_version_string(), MODULE_LOADER_MAP, &size);
   if (location == 0) {
@@ -985,7 +1091,6 @@
     begin_ptr = ++end_ptr;
     end_ptr = strchr(begin_ptr, '\n');
   }
-  FREE_RESOURCE_ARRAY(u1, buffer, size);
 }
 #endif
 
@@ -1106,8 +1211,7 @@
 }
 #endif
 
-s2 ClassLoader::classloader_type(Symbol* class_name, ClassPathEntry* e,
-                                     int classpath_index, TRAPS) {
+s2 ClassLoader::classloader_type(Symbol* class_name, ClassPathEntry* e, int classpath_index, TRAPS) {
 #if INCLUDE_CDS
   // obtain the classloader type based on the class name.
   // First obtain the package name based on the class name. Then obtain
@@ -1157,12 +1261,11 @@
 }
 
 instanceKlassHandle ClassLoader::load_class(Symbol* name, bool search_append_only, TRAPS) {
-
   assert(name != NULL, "invariant");
   assert(THREAD->is_Java_thread(), "must be a JavaThread");
 
-  ResourceMark rm;
-  HandleMark hm;
+  ResourceMark rm(THREAD);
+  HandleMark hm(THREAD);
 
   const char* const class_name = name->as_C_string();
 
@@ -1178,30 +1281,101 @@
   // Lookup stream for parsing .class file
   ClassFileStream* stream = NULL;
   s2 classpath_index = 0;
+  ClassPathEntry* e = NULL;
 
   // If DumpSharedSpaces is true, boot loader visibility boundaries are set
-  // to be _first_entry to the end (all path entries).
+  // to be _first_entry to the end (all path entries). No -Xpatch entries are
+  // included since CDS and AppCDS are not supported if -Xpatch is specified.
   //
   // If search_append_only is true, boot loader visibility boundaries are
-  // set to be _fist_append_entry to the end. This includes:
+  // set to be _first_append_entry to the end. This includes:
   //   [-Xbootclasspath/a]; [jvmti appended entries]
   //
   // If both DumpSharedSpaces and search_append_only are false, boot loader
   // visibility boundaries are set to be _first_entry to the entry before
   // the _first_append_entry.  This would include:
-  //   [-Xpatch:<dirs>];  [exploded build | modules]
+  //   [-Xpatch:<module>=<file>(<pathsep><file>)*];  [exploded build | jimage]
   //
   // DumpSharedSpaces and search_append_only are mutually exclusive and cannot
   // be true at the same time.
-  ClassPathEntry* e = (search_append_only ? _first_append_entry : _first_entry);
-  ClassPathEntry* last_e =
-      (search_append_only || DumpSharedSpaces ? NULL : _first_append_entry);
+  assert(!(DumpSharedSpaces && search_append_only), "DumpSharedSpaces and search_append_only are both true");
+
+  // Load Attempt #1: -Xpatch
+  // Determine the class' defining module.  If it appears in the _xpatch_entries,
+  // attempt to load the class from those locations specific to the module.
+  // Note: The -Xpatch entries are never searched if the boot loader's
+  //       visibility boundary is limited to only searching the append entries.
+  if (_xpatch_entries != NULL && !search_append_only && !DumpSharedSpaces) {
+    // Find the module in the boot loader's module entry table
+    PackageEntry* pkg_entry = get_package_entry(class_name, ClassLoaderData::the_null_class_loader_data(), THREAD);
+    ModuleEntry* mod_entry = (pkg_entry != NULL) ? pkg_entry->module() : NULL;
+
+    // If the module system has not defined java.base yet, then
+    // classes loaded are assumed to be defined to java.base.
+    // When java.base is eventually defined by the module system,
+    // all packages of classes that have been previously loaded
+    // are verified in ModuleEntryTable::verify_javabase_packages().
+    if (!Universe::is_module_initialized() &&
+        !ModuleEntryTable::javabase_defined() &&
+        mod_entry == NULL) {
+      mod_entry = ModuleEntryTable::javabase_module();
+    }
+
+    // The module must be a named module
+    if (mod_entry != NULL && mod_entry->is_named()) {
+      int num_of_entries = _xpatch_entries->length();
+      const Symbol* class_module_name = mod_entry->name();
+
+      // Loop through all the xpatch entries looking for module
+      for (int i = 0; i < num_of_entries; i++) {
+        ModuleClassPathList* module_cpl = _xpatch_entries->at(i);
+        Symbol* module_cpl_name = module_cpl->module_name();
 
-  {
+        if (module_cpl_name->fast_compare(class_module_name) == 0) {
+          // Class' module has been located, attempt to load
+          // the class from the module's ClassPathEntry list.
+          e = module_cpl->module_first_entry();
+          while (e != NULL) {
+            stream = e->open_stream(file_name, CHECK_NULL);
+            // No context.check is required since both CDS
+            // and AppCDS are turned off if -Xpatch is specified.
+            if (NULL != stream) {
+              break;
+            }
+            e = e->next();
+          }
+          // If the module was located in the xpatch entries, break out
+          // even if the class was not located successfully from that module's
+          // ClassPathEntry list. There will not be another valid entry for
+          // that module in the _xpatch_entries array.
+          break;
+        }
+      }
+    }
+  }
+
+  // Load Attempt #2: [exploded build | jimage]
+  if (!search_append_only && (NULL == stream)) {
+    e = _first_entry;
+    while ((e != NULL) && (e != _first_append_entry)) {
+      stream = e->open_stream(file_name, CHECK_NULL);
+      if (!context.check(stream, classpath_index)) {
+        return NULL;
+      }
+      if (NULL != stream) {
+        break;
+      }
+      e = e->next();
+      ++classpath_index;
+    }
+  }
+
+  // Load Attempt #3: [-Xbootclasspath/a]; [jvmti appended entries]
+  if ((search_append_only || DumpSharedSpaces) && (NULL == stream)) {
+    // For the boot loader append path search, must calculate
+    // the starting classpath_index prior to attempting to
+    // load the classfile.
     if (search_append_only) {
-      // For the boot loader append path search, must calculate
-      // the starting classpath_index prior to attempting to
-      // load the classfile.
       ClassPathEntry *tmp_e = _first_entry;
       while ((tmp_e != NULL) && (tmp_e != _first_append_entry)) {
         tmp_e = tmp_e->next();
@@ -1209,11 +1383,8 @@
       }
     }
 
-    // Attempt to load the classfile from either:
-    //   - [-Xpatch:dir]; exploded build | modules
-    //     or
-    //   - [-Xbootclasspath/a]; [jvmti appended entries]
-    while ((e != NULL) && (e != last_e)) {
+    e = _first_append_entry;
+    while (e != NULL) {
       stream = e->open_stream(file_name, CHECK_NULL);
       if (!context.check(stream, classpath_index)) {
         return NULL;
@@ -1384,10 +1555,23 @@
 }
 
 
-void classLoader_init() {
+void classLoader_init1() {
   ClassLoader::initialize();
 }
 
+// Complete the ClassPathEntry setup for the boot loader
+void classLoader_init2() {
+  // Setup the list of module/path pairs for -Xpatch processing
+  // This must be done after the SymbolTable is created in order
+  // to use fast_compare on module names instead of a string compare.
+  if (Arguments::get_xpatchprefix() != NULL) {
+    ClassLoader::setup_xpatch_entries();
+  }
+
+  // Determine if this is an exploded build
+  ClassLoader::set_has_jimage();
+}
+
 
 bool ClassLoader::get_canonical_path(const char* orig, char* out, int len) {
   assert(orig != NULL && out != NULL && len > 0, "bad arguments");
@@ -1431,17 +1615,19 @@
     }
     ModuleEntryTable::set_javabase_module(jb_module);
   }
+}
 
-  // When looking for the jimage file, only
-  // search the boot loader's module path which
-  // can consist of [-Xpatch]; exploded build | modules
-  // Do not search the boot loader's append path.
+void ClassLoader::set_has_jimage() {
+  // Determine if this is an exploded build. When looking for
+  // the jimage file, only search the piece of the boot
+  // loader's boot class path which contains [exploded build | jimage].
+  // Do not search the boot loader's xpatch entries or append path.
   ClassPathEntry* e = _first_entry;
   ClassPathEntry* last_e = _first_append_entry;
   while ((e != NULL) && (e != last_e)) {
     JImageFile *jimage = e->jimage();
     if (jimage != NULL && e->is_jrt()) {
-      set_has_jimage(true);
+      _has_jimage = true;
 #if INCLUDE_CDS
       ClassLoader::initialize_module_loader_map(jimage);
 #endif
--- a/hotspot/src/share/vm/classfile/classLoader.hpp	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/src/share/vm/classfile/classLoader.hpp	Thu May 12 11:03:07 2016 -0700
@@ -142,13 +142,30 @@
   JImageFile* jimage() const { return _jimage; }
   ClassPathImageEntry(JImageFile* jimage, const char* name);
   ~ClassPathImageEntry();
-  void name_to_package(const char* name, char* package, int length);
   ClassFileStream* open_stream(const char* name, TRAPS);
 
   // Debugging
   NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);)
 };
 
+// ModuleClassPathList contains a linked list of ClassPathEntry's
+// that have been specified for a specific module.  Currently,
+// the only way to specify a module/path pair is via the -Xpatch
+// command line option.
+class ModuleClassPathList : public CHeapObj<mtClass> {
+private:
+  Symbol* _module_name;
+  // First and last entries of class path entries for a specific module
+  ClassPathEntry* _module_first_entry;
+  ClassPathEntry* _module_last_entry;
+public:
+  Symbol* module_name() const { return _module_name; }
+  ClassPathEntry* module_first_entry() const { return _module_first_entry; }
+  ModuleClassPathList(Symbol* module_name);
+  ~ModuleClassPathList();
+  void add_to_list(ClassPathEntry* new_entry);
+};
+
 class SharedPathsMiscInfo;
 
 class ClassLoader: AllStatic {
@@ -195,21 +212,31 @@
   static PerfCounter* _isUnsyncloadClass;
   static PerfCounter* _load_instance_class_failCounter;
 
-  // First entry in linked list of ClassPathEntry instances.
-  // This consists of entries made up by:
-  //   - boot loader modules
-  //     [-Xpatch]; exploded build | modules;
-  //   - boot loader append path
-  //     [-Xbootclasspath/a]; [jvmti appended entries]
+  // The boot class path consists of 3 ordered pieces:
+  //  1. the module/path pairs specified to -Xpatch
+  //    -Xpatch:<module>=<file>(<pathsep><file>)*
+  //  2. the base piece
+  //    [exploded build | jimage]
+  //  3. boot loader append path
+  //    [-Xbootclasspath/a]; [jvmti appended entries]
+  //
+  // The boot loader must obey this order when attempting
+  // to load a class.
+
+  // Contains the module/path pairs specified to -Xpatch
+  static GrowableArray<ModuleClassPathList*>* _xpatch_entries;
+
+  // Contains the ClassPathEntry instances that include
+  // both the base piece and the boot loader append path.
   static ClassPathEntry* _first_entry;
   // Last entry in linked list of ClassPathEntry instances
   static ClassPathEntry* _last_entry;
   static int _num_entries;
 
-  // Pointer into the linked list of ClassPathEntry instances.
   // Marks the start of:
   //   - the boot loader's append path
   //     [-Xbootclasspath/a]; [jvmti appended entries]
+  // within the linked list of ClassPathEntry instances.
   static ClassPathEntry* _first_append_entry;
 
   static const char* _shared_archive;
@@ -325,11 +352,11 @@
     return _load_instance_class_failCounter;
   }
 
+  // Set up the module/path pairs as specified to -Xpatch
+  static void setup_xpatch_entries();
+
   // Sets _has_jimage to TRUE if "modules" jimage file exists
-  static void set_has_jimage(bool val) {
-    _has_jimage = val;
-  }
-
+  static void set_has_jimage();
   static bool has_jimage() { return _has_jimage; }
 
   // Create the ModuleEntry for java.base
@@ -416,6 +443,9 @@
 
   static bool string_ends_with(const char* str, const char* str_to_find);
 
+  // obtain package name from a fully qualified class name
+  static const char* package_from_name(const char* class_name);
+
   static bool is_jrt(const char* name) { return string_ends_with(name, MODULES_IMAGE_NAME); }
 
   // Debugging
--- a/hotspot/src/share/vm/classfile/modules.cpp	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/src/share/vm/classfile/modules.cpp	Thu May 12 11:03:07 2016 -0700
@@ -133,68 +133,31 @@
   return NULL;
 }
 
-// Check if -Xpatch:<dirs> was specified.  If so, prepend each <dir>/module_name,
-// if it exists, to bootpath so boot loader can find the class files.  Also, if
-// using exploded modules, append <java.home>/modules/module_name, if it exists,
-// to bootpath so that its class files can be found by the boot loader.
-static void add_to_boot_loader_list(char *module_name, TRAPS) {
-  // java.base should be handled by argument parsing.
+// If using exploded build, append <java.home>/modules/module_name, if it exists,
+// to the system boot class path in order for the boot loader to locate class files.
+static void add_to_exploded_build_list(char *module_name, TRAPS) {
+  assert(!ClassLoader::has_jimage(), "Exploded build not applicable");
+  // java.base is handled by os::set_boot_path
   assert(strcmp(module_name, "java.base") != 0, "Unexpected java.base module name");
+
   char file_sep = os::file_separator()[0];
   size_t module_len = strlen(module_name);
 
-  // If -Xpatch is set then add <patch-dir>/module_name paths.
-  char** patch_dirs = Arguments::patch_dirs();
-  if (patch_dirs != NULL) {
-    int dir_count = Arguments::patch_dirs_count();
-    for (int x = 0; x < dir_count; x++) {
-      // Really shouldn't be NULL, but check can't hurt
-      if (patch_dirs[x] != NULL) {
-        size_t len = strlen(patch_dirs[x]);
-        if (len != 0) { // Ignore empty strings.
-          len = len + module_len + 2;
-          char* prefix_path = NEW_C_HEAP_ARRAY(char, len, mtInternal);
-          jio_snprintf(prefix_path, len, "%s%c%s", patch_dirs[x], file_sep, module_name);
-
-          // See if Xpatch module path exists.
-          struct stat st;
-          if ((os::stat(prefix_path, &st) != 0)) {
-            FREE_C_HEAP_ARRAY(char, prefix_path);
-          } else {
-            {
-              HandleMark hm;
-              Handle loader_lock = Handle(THREAD, SystemDictionary::system_loader_lock());
-              ObjectLocker ol(loader_lock, THREAD);
-              ClassLoader::prepend_to_list(prefix_path);
-            }
-            log_info(classload)("opened: -Xpatch %s", prefix_path);
-          }
-        }
-      }
-    }
-  }
-
-  // If "modules" jimage does not exist then assume exploded form
-  // ${java.home}/modules/<module-name>
-  char* path = NULL;
-  if (!ClassLoader::has_jimage()) {
-    const char* home = Arguments::get_java_home();
-    size_t len = strlen(home) + module_len + 32;
-    path = NEW_C_HEAP_ARRAY(char, len, mtInternal);
-    jio_snprintf(path, len, "%s%cmodules%c%s", home, file_sep, file_sep, module_name);
-    struct stat st;
-    // See if exploded module path exists.
-    if ((os::stat(path, &st) != 0)) {
-      FREE_C_HEAP_ARRAY(char, path);
-      path = NULL;
-    }
+  const char* home = Arguments::get_java_home();
+  size_t len = strlen(home) + module_len + 32;
+  char* path = NEW_C_HEAP_ARRAY(char, len, mtInternal);
+  jio_snprintf(path, len, "%s%cmodules%c%s", home, file_sep, file_sep, module_name);
+  struct stat st;
+  // See if exploded module path exists
+  if ((os::stat(path, &st) != 0)) {
+    FREE_C_HEAP_ARRAY(char, path);
+    path = NULL;
   }
 
   if (path != NULL) {
     HandleMark hm;
     Handle loader_lock = Handle(THREAD, SystemDictionary::system_loader_lock());
     ObjectLocker ol(loader_lock, THREAD);
-
     log_info(classload)("opened: %s", path);
     ClassLoader::add_to_list(path);
   }
@@ -493,13 +456,12 @@
     }
   }
 
-  if (loader == NULL && !Universe::is_module_initialized()) {
-    // Now that the module is defined, if it is in the bootloader, make sure that
-    // its classes can be found.  Check if -Xpatch:<path> was specified.  If
-    // so prepend <path>/module_name, if it exists, to bootpath.  Also, if using
-    // exploded modules, prepend <java.home>/modules/module_name, if it exists,
-    // to bootpath.
-    add_to_boot_loader_list(module_name, CHECK);
+  // If the module is defined to the boot loader and an exploded build is being
+  // used, prepend <java.home>/modules/modules_name, if it exists, to the system boot class path.
+  if (loader == NULL &&
+      !Universe::is_module_initialized() &&
+      !ClassLoader::has_jimage()) {
+    add_to_exploded_build_list(module_name, CHECK);
   }
 }
 
--- a/hotspot/src/share/vm/memory/filemap.cpp	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/src/share/vm/memory/filemap.cpp	Thu May 12 11:03:07 2016 -0700
@@ -880,7 +880,7 @@
     return false;
   }
 
-  if (Arguments::patch_dirs() != NULL) {
+  if (Arguments::get_xpatchprefix() != NULL) {
     FileMapInfo::fail_continue("The shared archive file cannot be used with -Xpatch.");
     return false;
   }
--- a/hotspot/src/share/vm/memory/metaspaceShared.hpp	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/src/share/vm/memory/metaspaceShared.hpp	Thu May 12 11:03:07 2016 -0700
@@ -43,10 +43,10 @@
 // for the x64 platform
 #define DEFAULT_VTBL_COMMON_CODE_SIZE   (1*K) // conservative size of the "common_code" for the x64 platform
 
-#define DEFAULT_SHARED_READ_WRITE_SIZE  (NOT_LP64(12*M) LP64_ONLY(16*M))
-#define MIN_SHARED_READ_WRITE_SIZE      (NOT_LP64(7*M) LP64_ONLY(12*M))
+#define DEFAULT_SHARED_READ_WRITE_SIZE  (NOT_LP64(8*M) LP64_ONLY(10*M))
+#define MIN_SHARED_READ_WRITE_SIZE      (NOT_LP64(7*M) LP64_ONLY(10*M))
 
-#define DEFAULT_SHARED_READ_ONLY_SIZE   (NOT_LP64(12*M) LP64_ONLY(16*M))
+#define DEFAULT_SHARED_READ_ONLY_SIZE   (NOT_LP64(8*M) LP64_ONLY(10*M))
 #define MIN_SHARED_READ_ONLY_SIZE       (NOT_LP64(8*M) LP64_ONLY(9*M))
 
 // the MIN_SHARED_MISC_DATA_SIZE and MIN_SHARED_MISC_CODE_SIZE estimates are based on
--- a/hotspot/src/share/vm/opto/doCall.cpp	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/src/share/vm/opto/doCall.cpp	Thu May 12 11:03:07 2016 -0700
@@ -415,8 +415,12 @@
   if (symbolic_info->arg_size() != (resolved_method->arg_size() + has_appendix)) {
     return false; // Total size of arguments on stack mismatch.
   }
-  if (!check_type(symbolic_info->return_type(), resolved_method->return_type())) {
-    return false; // Return value size or type mismatch encountered.
+  if (!symbolic_info->return_type()->is_void()) {
+    // Only check the return type if the symbolic method is not void
+    // i.e. the return value of the resolved method can be dropped
+    if (!check_type(symbolic_info->return_type(), resolved_method->return_type())) {
+      return false; // Return value size or type mismatch encountered.
+    }
   }
 
   switch (symbolic_info->intrinsic_id()) {
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Thu May 12 11:03:07 2016 -0700
@@ -84,8 +84,6 @@
 const char*  Arguments::_sun_java_launcher      = DEFAULT_JAVA_LAUNCHER;
 int    Arguments::_sun_java_launcher_pid        = -1;
 bool   Arguments::_sun_java_launcher_is_altjvm  = false;
-int    Arguments::_patch_dirs_count          = 0;
-char** Arguments::_patch_dirs                = NULL;
 int    Arguments::_bootclassloader_append_index = -1;
 
 // These parameters are reset in method parse_vm_init_args()
@@ -112,6 +110,7 @@
 SystemProperty *Arguments::_java_class_path = NULL;
 SystemProperty *Arguments::_jdk_boot_class_path_append = NULL;
 
+GrowableArray<ModuleXPatchPath*> *Arguments::_xpatchprefix = NULL;
 PathString *Arguments::_system_boot_class_path = NULL;
 
 char* Arguments::_ext_dirs = NULL;
@@ -579,204 +578,6 @@
 }
 #endif
 
-// Constructs the system boot class path from the following components, in order:
-//
-//     prefix           // from -Xpatch:...
-//     base             // from os::get_system_properties()
-//     suffix           // from -Xbootclasspath/a:...
-//
-// This could be AllStatic, but it isn't needed after argument processing is
-// complete. After argument processing, the combined components are copied
-// to Arguments::_system_boot_class_path via a call to Arguments::set_sysclasspath.
-class ArgumentBootClassPath: public StackObj {
-public:
-  ArgumentBootClassPath(const char* base);
-  ~ArgumentBootClassPath();
-
-  inline void set_base(const char* base);
-  inline void add_prefix(const char* prefix);
-  inline void add_suffix_to_prefix(const char* suffix);
-  inline void add_suffix(const char* suffix);
-  inline void reset_path(const char* base);
-
-  inline const char* get_base()     const { return _items[_bcp_base]; }
-  inline const char* get_prefix()   const { return _items[_bcp_prefix]; }
-  inline const char* get_suffix()   const { return _items[_bcp_suffix]; }
-
-  // Combine all the components into a single c-heap-allocated string; caller
-  // must free the string if/when no longer needed.
-  char* combined_path();
-
-private:
-  // Utility routines.
-  static char* add_to_path(const char* path, const char* str, bool prepend);
-  static char* add_jars_to_path(char* path, const char* directory);
-
-  inline void reset_item_at(int index);
-
-  // Array indices for the items that make up the sysclasspath.  All except the
-  // base are allocated in the C heap and freed by this class.
-  enum {
-    _bcp_prefix,        // was -Xpatch:...
-    _bcp_base,          // the default system boot class path
-    _bcp_suffix,        // from -Xbootclasspath/a:...
-    _bcp_nitems         // the number of items, must be last.
-  };
-
-  const char* _items[_bcp_nitems];
-};
-
-ArgumentBootClassPath::ArgumentBootClassPath(const char* base) {
-  memset(_items, 0, sizeof(_items));
-  _items[_bcp_base] = base;
-}
-
-ArgumentBootClassPath::~ArgumentBootClassPath() {
-  // Free everything except the base.
-  for (int i = 0; i < _bcp_nitems; ++i) {
-    if (i != _bcp_base) reset_item_at(i);
-  }
-}
-
-inline void ArgumentBootClassPath::set_base(const char* base) {
-  _items[_bcp_base] = base;
-}
-
-inline void ArgumentBootClassPath::add_prefix(const char* prefix) {
-  _items[_bcp_prefix] = add_to_path(_items[_bcp_prefix], prefix, true);
-}
-
-inline void ArgumentBootClassPath::add_suffix_to_prefix(const char* suffix) {
-  _items[_bcp_prefix] = add_to_path(_items[_bcp_prefix], suffix, false);
-}
-
-inline void ArgumentBootClassPath::add_suffix(const char* suffix) {
-  _items[_bcp_suffix] = add_to_path(_items[_bcp_suffix], suffix, false);
-}
-
-inline void ArgumentBootClassPath::reset_item_at(int index) {
-  assert(index < _bcp_nitems && index != _bcp_base, "just checking");
-  if (_items[index] != NULL) {
-    FREE_C_HEAP_ARRAY(char, _items[index]);
-    _items[index] = NULL;
-  }
-}
-
-inline void ArgumentBootClassPath::reset_path(const char* base) {
-  // Clear the prefix and suffix.
-  reset_item_at(_bcp_prefix);
-  reset_item_at(_bcp_suffix);
-  set_base(base);
-}
-
-//------------------------------------------------------------------------------
-
-
-// Combine the bootclasspath elements, some of which may be null, into a single
-// c-heap-allocated string.
-char* ArgumentBootClassPath::combined_path() {
-  assert(_items[_bcp_base] != NULL, "empty default sysclasspath");
-
-  size_t lengths[_bcp_nitems];
-  size_t total_len = 0;
-
-  const char separator = *os::path_separator();
-
-  // Get the lengths.
-  int i;
-  for (i = 0; i < _bcp_nitems; ++i) {
-    if (i == _bcp_suffix) {
-      // Record index of boot loader's append path.
-      Arguments::set_bootclassloader_append_index((int)total_len);
-    }
-    if (_items[i] != NULL) {
-      lengths[i] = strlen(_items[i]);
-      // Include space for the separator char (or a NULL for the last item).
-      total_len += lengths[i] + 1;
-    }
-  }
-  assert(total_len > 0, "empty sysclasspath not allowed");
-
-  // Copy the _items to a single string.
-  char* cp = NEW_C_HEAP_ARRAY(char, total_len, mtArguments);
-  char* cp_tmp = cp;
-  for (i = 0; i < _bcp_nitems; ++i) {
-    if (_items[i] != NULL) {
-      memcpy(cp_tmp, _items[i], lengths[i]);
-      cp_tmp += lengths[i];
-      *cp_tmp++ = separator;
-    }
-  }
-  *--cp_tmp = '\0';     // Replace the extra separator.
-  return cp;
-}
-
-// Note:  path must be c-heap-allocated (or NULL); it is freed if non-null.
-char*
-ArgumentBootClassPath::add_to_path(const char* path, const char* str, bool prepend) {
-  char *cp;
-
-  assert(str != NULL, "just checking");
-  if (path == NULL) {
-    size_t len = strlen(str) + 1;
-    cp = NEW_C_HEAP_ARRAY(char, len, mtArguments);
-    memcpy(cp, str, len);                       // copy the trailing null
-  } else {
-    const char separator = *os::path_separator();
-    size_t old_len = strlen(path);
-    size_t str_len = strlen(str);
-    size_t len = old_len + str_len + 2;
-
-    if (prepend) {
-      cp = NEW_C_HEAP_ARRAY(char, len, mtArguments);
-      char* cp_tmp = cp;
-      memcpy(cp_tmp, str, str_len);
-      cp_tmp += str_len;
-      *cp_tmp = separator;
-      memcpy(++cp_tmp, path, old_len + 1);      // copy the trailing null
-      FREE_C_HEAP_ARRAY(char, path);
-    } else {
-      cp = REALLOC_C_HEAP_ARRAY(char, path, len, mtArguments);
-      char* cp_tmp = cp + old_len;
-      *cp_tmp = separator;
-      memcpy(++cp_tmp, str, str_len + 1);       // copy the trailing null
-    }
-  }
-  return cp;
-}
-
-// Scan the directory and append any jar or zip files found to path.
-// Note:  path must be c-heap-allocated (or NULL); it is freed if non-null.
-char* ArgumentBootClassPath::add_jars_to_path(char* path, const char* directory) {
-  DIR* dir = os::opendir(directory);
-  if (dir == NULL) return path;
-
-  char dir_sep[2] = { '\0', '\0' };
-  size_t directory_len = strlen(directory);
-  const char fileSep = *os::file_separator();
-  if (directory[directory_len - 1] != fileSep) dir_sep[0] = fileSep;
-
-  /* Scan the directory for jars/zips, appending them to path. */
-  struct dirent *entry;
-  char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(directory), mtArguments);
-  while ((entry = os::readdir(dir, (dirent *) dbuf)) != NULL) {
-    const char* name = entry->d_name;
-    const char* ext = name + strlen(name) - 4;
-    bool isJarOrZip = ext > name &&
-      (os::file_name_strcmp(ext, ".jar") == 0 ||
-       os::file_name_strcmp(ext, ".zip") == 0);
-    if (isJarOrZip) {
-      char* jarpath = NEW_C_HEAP_ARRAY(char, directory_len + 2 + strlen(name), mtArguments);
-      sprintf(jarpath, "%s%s%s", directory, dir_sep, name);
-      path = add_to_path(path, jarpath, false);
-      FREE_C_HEAP_ARRAY(char, jarpath);
-    }
-  }
-  FREE_C_HEAP_ARRAY(char, dbuf);
-  os::closedir(dir);
-  return path;
-}
-
 // Parses a memory size specification string.
 static bool atomull(const char *s, julong* result) {
   julong n = 0;
@@ -2687,9 +2488,7 @@
 jint Arguments::parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args,
                                    const JavaVMInitArgs *java_options_args,
                                    const JavaVMInitArgs *cmd_line_args) {
-  // For components of the system classpath.
-  ArgumentBootClassPath bcp(Arguments::get_sysclasspath());
-  bool bcp_assembly_required = false;
+  bool xpatch_javabase = false;
 
   // Save default settings for some mode flags
   Arguments::_AlwaysCompileLoopMethods = AlwaysCompileLoopMethods;
@@ -2706,29 +2505,26 @@
 
   // Parse args structure generated from JAVA_TOOL_OPTIONS environment
   // variable (if present).
-  jint result = parse_each_vm_init_arg(
-      java_tool_options_args, &bcp, &bcp_assembly_required, Flag::ENVIRON_VAR);
+  jint result = parse_each_vm_init_arg(java_tool_options_args, &xpatch_javabase, Flag::ENVIRON_VAR);
   if (result != JNI_OK) {
     return result;
   }
 
   // Parse args structure generated from the command line flags.
-  result = parse_each_vm_init_arg(cmd_line_args, &bcp, &bcp_assembly_required,
-                                  Flag::COMMAND_LINE);
+  result = parse_each_vm_init_arg(cmd_line_args, &xpatch_javabase, Flag::COMMAND_LINE);
   if (result != JNI_OK) {
     return result;
   }
 
   // Parse args structure generated from the _JAVA_OPTIONS environment
   // variable (if present) (mimics classic VM)
-  result = parse_each_vm_init_arg(
-      java_options_args, &bcp, &bcp_assembly_required, Flag::ENVIRON_VAR);
+  result = parse_each_vm_init_arg(java_options_args, &xpatch_javabase, Flag::ENVIRON_VAR);
   if (result != JNI_OK) {
     return result;
   }
 
   // Do final processing now that all arguments have been parsed
-  result = finalize_vm_init_args(&bcp, bcp_assembly_required);
+  result = finalize_vm_init_args();
   if (result != JNI_OK) {
     return result;
   }
@@ -2781,10 +2577,7 @@
   return false;
 }
 
-jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
-                                       ArgumentBootClassPath* bcp_p,
-                                       bool* bcp_assembly_required_p,
-                                       Flag::Flags origin) {
+jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* xpatch_javabase, Flag::Flags origin) {
   // For match_option to return remaining or value part of option string
   const char* tail;
 
@@ -2840,8 +2633,8 @@
         return JNI_EINVAL;
     // -bootclasspath/a:
     } else if (match_option(option, "-Xbootclasspath/a:", &tail)) {
-      bcp_p->add_suffix(tail);
-      *bcp_assembly_required_p = true;
+      Arguments::set_bootclassloader_append_index((int)strlen(Arguments::get_sysclasspath())+1);
+      Arguments::append_sysclasspath(tail);
     // -bootclasspath/p:
     } else if (match_option(option, "-Xbootclasspath/p:", &tail)) {
         jio_fprintf(defaultStream::output_stream(),
@@ -2901,9 +2694,8 @@
       if (tail != NULL) {
         char *options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(tail) + 1, mtArguments), tail);
         add_init_agent("instrument", options, false);
-        // java agents need module java.instrument. Also -addmods ALL-SYSTEM because
-        // the java agent is in the unmamed module of the application class loader
-        if (!Arguments::append_to_addmods_property("java.instrument,ALL-SYSTEM")) {
+        // java agents need module java.instrument
+        if (!Arguments::append_to_addmods_property("java.instrument")) {
           return JNI_ENOMEM;
         }
       }
@@ -3181,37 +2973,30 @@
         return JNI_ERR;
 #endif
       }
-      if (match_option(option, "-Djdk.launcher.patch.0=", &tail)) {
-        // -Xpatch
-        int dir_count;
-        char** patch_dirs = os::split_path(tail, &dir_count);
-        if (patch_dirs == NULL) {
-          jio_fprintf(defaultStream::output_stream(),
-            "Bad value for -Xpatch.\n");
+      if (match_option(option, "-Djdk.launcher.patch.", &tail)) {
+        // -Djdk.launcher.patch.#=<module>=<file>(<pathsep><file>)*
+        // The number, #, specified will be increasing with each -Xpatch
+        // specified on the command line.
+        // Pick up module name, following the -D property's equal sign.
+        const char* property_equal = strchr(tail, '=');
+        if (property_equal == NULL) {
+          jio_fprintf(defaultStream::output_stream(), "Missing '=' in -Xpatch specification\n");
           return JNI_ERR;
-        }
-        set_patch_dirs(patch_dirs);
-        set_patch_dirs_count(dir_count);
-
-        // Create a path for each patch dir consisting of dir/java.base.
-        char file_sep = os::file_separator()[0];
-        for (int x = 0; x < dir_count; x++) {
-          // Really shouldn't be NULL, but check can't hurt
-          if (patch_dirs[x] != NULL) {
-            size_t len = strlen(patch_dirs[x]);
-            if (len != 0) { // Ignore empty strings.
-              len += 11; // file_sep + "java.base" + null terminator.
-              char* dir = NEW_C_HEAP_ARRAY(char, len, mtArguments);
-              jio_snprintf(dir, len, "%s%cjava.base", patch_dirs[x], file_sep);
-
-              // See if Xpatch module path exists.
-              struct stat st;
-              if ((os::stat(dir, &st) == 0)) {
-                bcp_p->add_prefix(dir);
-                *bcp_assembly_required_p = true;
-              }
-              FREE_C_HEAP_ARRAY(char, dir);
-            }
+        } else {
+          // Find the equal sign between the module name and the path specification
+          const char* module_equal = strchr(property_equal + 1, '=');
+          if (module_equal == NULL) {
+            jio_fprintf(defaultStream::output_stream(), "Bad value for -Xpatch, no module name specified\n");
+            return JNI_ERR;
+          } else {
+            // Pick out the module name, in between the two equal signs
+            size_t module_len = module_equal - property_equal - 1;
+            char* module_name = NEW_C_HEAP_ARRAY(char, module_len+1, mtArguments);
+            memcpy(module_name, property_equal + 1, module_len);
+            *(module_name + module_len) = '\0';
+            // The path piece begins one past the module_equal sign
+            Arguments::add_xpatchprefix(module_name, module_equal + 1, xpatch_javabase);
+            FREE_C_HEAP_ARRAY(char, module_name);
           }
         }
       }
@@ -3474,6 +3259,27 @@
   return JNI_OK;
 }
 
+void Arguments::add_xpatchprefix(const char* module_name, const char* path, bool* xpatch_javabase) {
+  // For java.base check for duplicate -Xpatch options being specified on the command line.
+  // This check is only required for java.base, all other duplicate module specifications
+  // will be checked during module system initialization.  The module system initialization
+  // will throw an ExceptionInInitializerError if this situation occurs.
+  if (strcmp(module_name, "java.base") == 0) {
+    if (*xpatch_javabase) {
+      vm_exit_during_initialization("Cannot specify java.base more than once to -Xpatch");
+    } else {
+      *xpatch_javabase = true;
+    }
+  }
+
+  // Create GrowableArray lazily, only if -Xpatch has been specified
+  if (_xpatchprefix == NULL) {
+    _xpatchprefix = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<ModuleXPatchPath*>(10, true);
+  }
+
+  _xpatchprefix->push(new ModuleXPatchPath(module_name, path));
+}
+
 // Set property jdk.boot.class.path.append to the contents of the bootclasspath
 // that follows either the jimage file or exploded module directories.  The
 // property will contain -Xbootclasspath/a and/or jvmti appended additions.
@@ -3572,7 +3378,7 @@
   return nonEmptyDirs;
 }
 
-jint Arguments::finalize_vm_init_args(ArgumentBootClassPath* bcp_p, bool bcp_assembly_required) {
+jint Arguments::finalize_vm_init_args() {
   // check if the default lib/endorsed directory exists; if so, error
   char path[JVM_MAXPATHLEN];
   const char* fileSep = os::file_separator();
@@ -3608,17 +3414,7 @@
     return JNI_ERR;
   }
 
-  if (bcp_assembly_required) {
-    // Assemble the bootclasspath elements into the final path.
-    char *combined_path = bcp_p->combined_path();
-    Arguments::set_sysclasspath(combined_path);
-    FREE_C_HEAP_ARRAY(char, combined_path);
-  } else {
-    // At this point in sysclasspath processing anything
-    // added would be considered in the boot loader's append path.
-    // Record this index, including +1 for the file separator character.
-    Arguments::set_bootclassloader_append_index(((int)strlen(Arguments::get_sysclasspath()))+1);
-  }
+  Arguments::set_bootclassloader_append_index(((int)strlen(Arguments::get_sysclasspath()))+1);
 
   // This must be done after all arguments have been processed.
   // java_compiler() true means set to "NONE" or empty.
@@ -3667,6 +3463,12 @@
   UNSUPPORTED_OPTION(TieredCompilation);
 #endif
 
+#if INCLUDE_JVMCI
+  if (EnableJVMCI && !append_to_addmods_property("jdk.vm.ci")) {
+    return JNI_ENOMEM;
+  }
+#endif
+
   // If we are running in a headless jre, force java.awt.headless property
   // to be true unless the property has already been set.
   // Also allow the OS environment variable JAVA_AWT_HEADLESS to set headless state.
@@ -3968,7 +3770,7 @@
 
 void Arguments::set_shared_spaces_flags() {
   if (DumpSharedSpaces) {
-    if (Arguments::patch_dirs() != NULL) {
+    if (Arguments::get_xpatchprefix() != NULL) {
       vm_exit_during_initialization(
         "Cannot use the following option when dumping the shared archive", "-Xpatch");
     }
--- a/hotspot/src/share/vm/runtime/arguments.hpp	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/src/share/vm/runtime/arguments.hpp	Thu May 12 11:03:07 2016 -0700
@@ -41,17 +41,15 @@
   typedef jint (JNICALL *vfprintf_hook_t)(FILE *fp, const char *format, va_list args)  ATTRIBUTE_PRINTF(2, 0);
 }
 
-// Forward declarations
-class ArgumentBootClassPath;
-
-// PathString is used as the underlying value container for a
-// SystemProperty and for the string that represents the system
-// boot class path, Arguments::_system_boot_class_path.
+// PathString is used as:
+//  - the underlying value for a SystemProperty
+//  - the path portion of an -Xpatch module/path pair
+//  - the string that represents the system boot class path, Arguments::_system_boot_class_path.
 class PathString : public CHeapObj<mtArguments> {
  protected:
-  char*           _value;
+  char* _value;
  public:
-  char* value() const                       { return _value; }
+  char* value() const { return _value; }
 
   bool set_value(const char *value) {
     if (_value != NULL) {
@@ -92,7 +90,6 @@
     }
   }
 
-  // Constructor
   PathString(const char* value) {
     if (value == NULL) {
       _value = NULL;
@@ -101,6 +98,43 @@
       strcpy(_value, value);
     }
   }
+
+  ~PathString() {
+    if (_value != NULL) {
+      FreeHeap(_value);
+      _value = NULL;
+    }
+  }
+};
+
+// ModuleXPatchPath records the module/path pair as specified to -Xpatch.
+class ModuleXPatchPath : public CHeapObj<mtInternal> {
+private:
+  char* _module_name;
+  PathString* _path;
+public:
+  ModuleXPatchPath(const char* module_name, const char* path) {
+    assert(module_name != NULL && path != NULL, "Invalid module name or path value");
+    size_t len = strlen(module_name) + 1;
+    _module_name = AllocateHeap(len, mtInternal);
+    strncpy(_module_name, module_name, len); // copy the trailing null
+    _path =  new PathString(path);
+  }
+
+  ~ModuleXPatchPath() {
+    if (_module_name != NULL) {
+      FreeHeap(_module_name);
+      _module_name = NULL;
+    }
+    if (_path != NULL) {
+      delete _path;
+      _path = NULL;
+    }
+  }
+
+  inline void set_path(const char* path) { _path->set_value(path); }
+  inline const char* module_name() const { return _module_name; }
+  inline char* path_string() const { return _path->value(); }
 };
 
 // Element describing System and User (-Dkey=value flags) defined property.
@@ -114,7 +148,7 @@
   SystemProperty* _next;
   bool            _internal;
   bool            _writeable;
-  bool writeable()   { return _writeable; }
+  bool writeable() { return _writeable; }
 
  public:
   // Accessors
@@ -314,10 +348,19 @@
   static SystemProperty *_java_class_path;
   static SystemProperty *_jdk_boot_class_path_append;
 
+  // -Xpatch:module=<file>(<pathsep><file>)*
+  // Each element contains the associated module name, path
+  // string pair as specified to -Xpatch.
+  static GrowableArray<ModuleXPatchPath*>* _xpatchprefix;
+
   // The constructed value of the system class path after
   // argument processing and JVMTI OnLoad additions via
   // calls to AddToBootstrapClassLoaderSearch.  This is the
   // final form before ClassLoader::setup_bootstrap_search().
+  // Note: since -Xpatch is a module name/path pair, the system
+  // boot class path string no longer contains the "prefix" to
+  // the boot class path base piece as it did when
+  // -Xbootclasspath/p was supported.
   static PathString *_system_boot_class_path;
 
   // temporary: to emit warning if the default ext dirs are not empty.
@@ -373,12 +416,6 @@
   // mark the boot loader's append path observability boundary.
   static int _bootclassloader_append_index;
 
-  // -Xpatch flag
-  static char** _patch_dirs;
-  static int _patch_dirs_count;
-  static void set_patch_dirs(char** dirs) { _patch_dirs = dirs; }
-  static void set_patch_dirs_count(int count) { _patch_dirs_count = count; }
-
   // -Xdebug flag
   static bool _xdebug_mode;
   static void set_xdebug_mode(bool arg) { _xdebug_mode = arg; }
@@ -465,8 +502,8 @@
   static jint parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args,
                                  const JavaVMInitArgs *java_options_args,
                                  const JavaVMInitArgs *cmd_line_args);
-  static jint parse_each_vm_init_arg(const JavaVMInitArgs* args, ArgumentBootClassPath* bcp_p, bool* bcp_assembly_required_p, Flag::Flags origin);
-  static jint finalize_vm_init_args(ArgumentBootClassPath* bcp_p, bool bcp_assembly_required);
+  static jint parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* xpatch_javabase, Flag::Flags origin);
+  static jint finalize_vm_init_args();
   static bool is_bad_option(const JavaVMOption* option, jboolean ignore, const char* option_type);
 
   static bool is_bad_option(const JavaVMOption* option, jboolean ignore) {
@@ -637,13 +674,12 @@
     return _bootclassloader_append_index;
   }
   static void set_bootclassloader_append_index(int value) {
-    _bootclassloader_append_index = value;
+    // Set only if the index has not been set yet
+    if (_bootclassloader_append_index == -1) {
+      _bootclassloader_append_index = value;
+    }
   }
 
-  // -Xpatch
-  static char** patch_dirs()             { return _patch_dirs; }
-  static int patch_dirs_count()          { return _patch_dirs_count; }
-
   // -Xrun
   static AgentLibrary* libraries()          { return _libraryList.first(); }
   static bool init_libraries_at_startup()   { return !_libraryList.is_empty(); }
@@ -701,8 +737,8 @@
   static void set_library_path(const char *value) { _java_library_path->set_value(value); }
   static void set_ext_dirs(char *value)     { _ext_dirs = os::strdup_check_oom(value); }
 
-  // Set up of the underlying system boot class path
-  static void set_jdkbootclasspath_append();
+  // Set up the underlying pieces of the system boot class path
+  static void add_xpatchprefix(const char *module_name, const char *path, bool* xpatch_javabase);
   static void set_sysclasspath(const char *value) {
     _system_boot_class_path->set_value(value);
     set_jdkbootclasspath_append();
@@ -711,11 +747,15 @@
     _system_boot_class_path->append_value(value);
     set_jdkbootclasspath_append();
   }
+  static void set_jdkbootclasspath_append();
 
-  static char* get_java_home() { return _java_home->value(); }
-  static char* get_dll_dir() { return _sun_boot_library_path->value(); }
+  static GrowableArray<ModuleXPatchPath*>* get_xpatchprefix() { return _xpatchprefix; }
   static char* get_sysclasspath() { return _system_boot_class_path->value(); }
-  static char* get_ext_dirs()        { return _ext_dirs;  }
+  static char* get_jdk_boot_class_path_append() { return _jdk_boot_class_path_append->value(); }
+
+  static char* get_java_home()    { return _java_home->value(); }
+  static char* get_dll_dir()      { return _sun_boot_library_path->value(); }
+  static char* get_ext_dirs()     { return _ext_dirs;  }
   static char* get_appclasspath() { return _java_class_path->value(); }
   static void  fix_appclasspath();
 
--- a/hotspot/src/share/vm/runtime/init.cpp	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/src/share/vm/runtime/init.cpp	Thu May 12 11:03:07 2016 -0700
@@ -52,7 +52,8 @@
 // Initialization done by Java thread in init_globals()
 void management_init();
 void bytecodes_init();
-void classLoader_init();
+void classLoader_init1();
+void classLoader_init2(); // note: ClassLoader need 2-phase init
 void compilationPolicy_init();
 void codeCache_init();
 void VM_Version_init();
@@ -102,7 +103,7 @@
   HandleMark hm;
   management_init();
   bytecodes_init();
-  classLoader_init();
+  classLoader_init1();
   compilationPolicy_init();
   codeCache_init();
   CodeCacheExtensions::initialize();
@@ -116,6 +117,7 @@
   if (status != JNI_OK)
     return status;
 
+  classLoader_init2();  // after SymbolTable creation, set up -Xpatch entries
   CodeCacheExtensions::complete_step(CodeCacheExtensionsSteps::Universe);
   interpreter_init();  // before any methods loaded
   CodeCacheExtensions::complete_step(CodeCacheExtensionsSteps::Interpreter);
--- a/hotspot/test/TEST.ROOT	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/TEST.ROOT	Thu May 12 11:03:07 2016 -0700
@@ -36,9 +36,12 @@
 requires.extraPropDefns = ../../test/jtreg-ext/requires/VMProps.java
 requires.properties=sun.arch.data.model
 
-# Tests using jtreg 4.2 b01 features
-requiredVersion=4.2 b01
+# Tests using jtreg 4.2 b02 features
+requiredVersion=4.2 b02
 
 # Path to libraries in the topmost test directory. This is needed so @library
 # does not need ../../ notation to reach them
 external.lib.roots = ../../
+
+# Use new form of -Xpatch
+useNewXpatch=true
--- a/hotspot/test/compiler/intrinsics/bmi/verifycode/AndnTestI.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/AndnTestI.java	Thu May 12 11:03:07 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
@@ -30,7 +30,7 @@
  * @build AndnTestI
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  *                              sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run main/bootclasspath -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * @run main/bootclasspath/othervm -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
  *                         -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions AndnTestI
  */
 
--- a/hotspot/test/compiler/intrinsics/bmi/verifycode/AndnTestL.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/AndnTestL.java	Thu May 12 11:03:07 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
@@ -30,7 +30,7 @@
  * @build AndnTestL
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  *                              sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run main/bootclasspath -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * @run main/bootclasspath/othervm -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
  *                         -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions AndnTestL
  */
 
--- a/hotspot/test/compiler/jsr292/CallSiteDepContextTest.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/compiler/jsr292/CallSiteDepContextTest.java	Thu May 12 11:03:07 2016 -0700
@@ -27,7 +27,7 @@
  * @modules java.base/jdk.internal.org.objectweb.asm
  * @library patches
  * @build java.base/java.lang.invoke.MethodHandleHelper
- * @run main/bootclasspath -Xbatch -XX:+IgnoreUnrecognizedVMOptions -Xlog:classunload
+ * @run main/bootclasspath/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -Xlog:classunload
  *                         -XX:+PrintCompilation -XX:+TraceDependencies -XX:+TraceReferenceGC
  *                         -verbose:gc compiler.jsr292.CallSiteDepContextTest
  */
--- a/hotspot/test/compiler/jsr292/InvokerGC.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/compiler/jsr292/InvokerGC.java	Thu May 12 11:03:07 2016 -0700
@@ -25,7 +25,7 @@
  * @test
  * @bug 8067247
  * @library /test/lib /compiler/whitebox /
- * @run main/bootclasspath -Xcomp -Xbatch
+ * @run main/bootclasspath/othervm -Xcomp -Xbatch
  *      -XX:CompileCommand=compileonly,InvokerGC::test
  *      -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
  *      InvokerGC
--- a/hotspot/test/compiler/jsr292/NonInlinedCall/GCTest.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/compiler/jsr292/NonInlinedCall/GCTest.java	Thu May 12 11:03:07 2016 -0700
@@ -28,7 +28,7 @@
  * @modules java.base/jdk.internal.vm.annotation
  * @build java.base/java.lang.invoke.MethodHandleHelper
  * @build sun.hotspot.WhiteBox
- * @run main/bootclasspath -XX:+IgnoreUnrecognizedVMOptions
+ * @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions
  *                         -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
  *                         -Xbatch -XX:-TieredCompilation -XX:CICompilerCount=1
  *                         -XX:+FoldStableValues
--- a/hotspot/test/compiler/jsr292/NonInlinedCall/InvokeTest.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/compiler/jsr292/NonInlinedCall/InvokeTest.java	Thu May 12 11:03:07 2016 -0700
@@ -29,7 +29,7 @@
  * @build java.base/java.lang.invoke.MethodHandleHelper
  * @build sun.hotspot.WhiteBox
  * @build compiler.jsr292.NonInlinedCall.InvokeTest
- * @run main/bootclasspath -XX:+IgnoreUnrecognizedVMOptions
+ * @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions
  *                         -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
  *                         -Xbatch -XX:-TieredCompilation -XX:CICompilerCount=1
  *                         compiler.jsr292.NonInlinedCall.InvokeTest
--- a/hotspot/test/compiler/jsr292/NonInlinedCall/RedefineTest.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/compiler/jsr292/NonInlinedCall/RedefineTest.java	Thu May 12 11:03:07 2016 -0700
@@ -35,7 +35,7 @@
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  *                              sun.hotspot.WhiteBox$WhiteBoxPermission
  *                              compiler.jsr292.NonInlinedCall.RedefineTest
- * @run main/bootclasspath -javaagent:agent.jar
+ * @run main/bootclasspath/othervm -javaagent:agent.jar
  *                         -XX:+IgnoreUnrecognizedVMOptions
  *                         -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
  *                         -Xbatch -XX:-TieredCompilation -XX:CICompilerCount=1
--- a/hotspot/test/compiler/jsr292/VMAnonymousClasses.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/compiler/jsr292/VMAnonymousClasses.java	Thu May 12 11:03:07 2016 -0700
@@ -26,7 +26,7 @@
  * @bug 8058828
  * @modules java.base/jdk.internal.org.objectweb.asm
  *          java.base/jdk.internal.misc
- * @run main/bootclasspath -Xbatch VMAnonymousClasses
+ * @run main/bootclasspath/othervm -Xbatch VMAnonymousClasses
  */
 
 import jdk.internal.org.objectweb.asm.ClassWriter;
--- a/hotspot/test/compiler/stable/TestStableBoolean.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/compiler/stable/TestStableBoolean.java	Thu May 12 11:03:07 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
@@ -31,23 +31,23 @@
  * @build sun.hotspot.WhiteBox
  * @build compiler.stable.TestStableBoolean
  *
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         compiler.stable.TestStableBoolean
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:-FoldStableValues
  *                         compiler.stable.TestStableBoolean
  *
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:+TieredCompilation -XX:TieredStopAtLevel=1
  *                         -XX:+FoldStableValues
  *                         compiler.stable.TestStableBoolean
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:+TieredCompilation -XX:TieredStopAtLevel=1
  *                         -XX:-FoldStableValues
--- a/hotspot/test/compiler/stable/TestStableByte.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/compiler/stable/TestStableByte.java	Thu May 12 11:03:07 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
@@ -31,23 +31,23 @@
  * @build sun.hotspot.WhiteBox
  * @build compiler.stable.TestStableByte
  *
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         compiler.stable.TestStableByte
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         compiler.stable.TestStableByte
  *
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         compiler.stable.TestStableByte
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
--- a/hotspot/test/compiler/stable/TestStableChar.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/compiler/stable/TestStableChar.java	Thu May 12 11:03:07 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
@@ -31,23 +31,23 @@
  * @build sun.hotspot.WhiteBox
  * @build compiler.stable.TestStableChar
  *
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         compiler.stable.TestStableChar
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         compiler.stable.TestStableChar
  *
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         compiler.stable.TestStableChar
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
--- a/hotspot/test/compiler/stable/TestStableDouble.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/compiler/stable/TestStableDouble.java	Thu May 12 11:03:07 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
@@ -31,23 +31,23 @@
  * @build sun.hotspot.WhiteBox
  * @build compiler.stable.TestStableDouble
  *
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         compiler.stable.TestStableDouble
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         compiler.stable.TestStableDouble
  *
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         compiler.stable.TestStableDouble
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
--- a/hotspot/test/compiler/stable/TestStableFloat.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/compiler/stable/TestStableFloat.java	Thu May 12 11:03:07 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
@@ -31,23 +31,23 @@
  * @build sun.hotspot.WhiteBox
  * @build compiler.stable.TestStableFloat
  *
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         compiler.stable.TestStableFloat
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         compiler.stable.TestStableFloat
  *
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         compiler.stable.TestStableFloat
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
--- a/hotspot/test/compiler/stable/TestStableInt.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/compiler/stable/TestStableInt.java	Thu May 12 11:03:07 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
@@ -31,23 +31,23 @@
  * @build sun.hotspot.WhiteBox
  * @build compiler.stable.TestStableInt
  *
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         compiler.stable.TestStableInt
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         compiler.stable.TestStableInt
  *
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         compiler.stable.TestStableInt
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
--- a/hotspot/test/compiler/stable/TestStableLong.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/compiler/stable/TestStableLong.java	Thu May 12 11:03:07 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
@@ -31,23 +31,23 @@
  * @build sun.hotspot.WhiteBox
  * @build compiler.stable.TestStableLong
  *
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         compiler.stable.TestStableLong
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         compiler.stable.TestStableLong
  *
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         compiler.stable.TestStableLong
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
--- a/hotspot/test/compiler/stable/TestStableMemoryBarrier.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/compiler/stable/TestStableMemoryBarrier.java	Thu May 12 11:03:07 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
@@ -30,7 +30,7 @@
  * @library /testlibrary /test/lib
  * @modules java.base/jdk.internal.vm.annotation
  *
- * @run main/bootclasspath -Xcomp -XX:CompileOnly=::testCompile
+ * @run main/bootclasspath/othervm -Xcomp -XX:CompileOnly=::testCompile
  *                         compiler.stable.TestStableMemoryBarrier
  *
  * @author hui.shi@linaro.org
--- a/hotspot/test/compiler/stable/TestStableObject.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/compiler/stable/TestStableObject.java	Thu May 12 11:03:07 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
@@ -31,23 +31,23 @@
  * @build sun.hotspot.WhiteBox
  * @build compiler.stable.TestStableObject
  *
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         compiler.stable.TestStableObject
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         compiler.stable.TestStableObject
  *
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         compiler.stable.TestStableObject
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
--- a/hotspot/test/compiler/stable/TestStableShort.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/compiler/stable/TestStableShort.java	Thu May 12 11:03:07 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
@@ -31,23 +31,23 @@
  * @build sun.hotspot.WhiteBox
  * @build compiler.stable.TestStableShort
  *
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         compiler.stable.TestStableShort
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         compiler.stable.TestStableShort
  *
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         compiler.stable.TestStableShort
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
--- a/hotspot/test/compiler/stable/TestStableUByte.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/compiler/stable/TestStableUByte.java	Thu May 12 11:03:07 2016 -0700
@@ -31,26 +31,26 @@
  * @build sun.hotspot.WhiteBox
  * @build compiler.stable.TestStableUByte
  *
- * @run main/bootclasspath -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline
+ * @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline
  *                         -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         -XX:CompileOnly=::get,::get1
  *                         compiler.stable.TestStableUByte
- * @run main/bootclasspath -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline
+ * @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline
  *                         -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:-TieredCompilation
  *                         -XX:-FoldStableValues
  *                         -XX:CompileOnly=::get,::get1
  *                         compiler.stable.TestStableUByte
  *
- * @run main/bootclasspath -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline
+ * @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline
  *                         -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:+TieredCompilation -XX:TieredStopAtLevel=1
  *                         -XX:+FoldStableValues
  *                         -XX:CompileOnly=::get,::get1
  *                         compiler.stable.TestStableUByte
- * @run main/bootclasspath -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline
+ * @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline
  *                         -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:+TieredCompilation -XX:TieredStopAtLevel=1
  *                         -XX:-FoldStableValues
--- a/hotspot/test/compiler/stable/TestStableUShort.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/compiler/stable/TestStableUShort.java	Thu May 12 11:03:07 2016 -0700
@@ -31,26 +31,26 @@
  * @build sun.hotspot.WhiteBox
  * @build compiler.stable.TestStableUShort
  *
- * @run main/bootclasspath -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline
+ * @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline
  *                         -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         -XX:CompileOnly=::get,::get1
  *                         compiler.stable.TestStableUShort
- * @run main/bootclasspath -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline
+ * @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline
  *                         -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:-TieredCompilation
  *                         -XX:-FoldStableValues
  *                         -XX:CompileOnly=::get,::get1
  *                         compiler.stable.TestStableUShort
  *
- * @run main/bootclasspath -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline
+ * @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline
  *                         -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:+TieredCompilation -XX:TieredStopAtLevel=1
  *                         -XX:+FoldStableValues
  *                         -XX:CompileOnly=::get,::get1
  *                         compiler.stable.TestStableUShort
- * @run main/bootclasspath -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline
+ * @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline
  *                         -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
  *                         -XX:+TieredCompilation -XX:TieredStopAtLevel=1
  *                         -XX:-FoldStableValues
--- a/hotspot/test/compiler/unsafe/UnsafeGetConstantField.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/compiler/unsafe/UnsafeGetConstantField.java	Thu May 12 11:03:07 2016 -0700
@@ -33,21 +33,23 @@
  * @modules java.base/jdk.internal.org.objectweb.asm
  *          java.base/jdk.internal.vm.annotation
  *          java.base/jdk.internal.misc
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions
  *                         -Xbatch -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         -XX:CompileCommand=dontinline,UnsafeGetConstantField.checkGetAddress()
  *                         -XX:CompileCommand=dontinline,*.test*
  *                         -XX:+UseUnalignedAccesses
+ *                         -XaddReads:java.base=ALL-UNNAMED
  *                         compiler.unsafe.UnsafeGetConstantField
  *
- * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions
+ * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions
  *                         -Xbatch -XX:-TieredCompilation
  *                         -XX:+FoldStableValues
  *                         -XX:CompileCommand=dontinline,UnsafeGetConstantField.checkGetAddress()
  *                         -XX:CompileCommand=dontinline,*.test*
  *                         -XX:CompileCommand=inline,*Unsafe.get*
  *                         -XX:-UseUnalignedAccesses
+ *                         -XaddReads:java.base=ALL-UNNAMED
  *                         compiler.unsafe.UnsafeGetConstantField
  */
 package compiler.unsafe;
--- a/hotspot/test/runtime/BadObjectClass/BootstrapRedefine.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/runtime/BadObjectClass/BootstrapRedefine.java	Thu May 12 11:03:07 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
@@ -48,7 +48,7 @@
                                         "-Xmodule:java.base"),
                                         "mods/java.base");
 
-        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:mods", "-version");
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.base=mods/java.base", "-version");
         new OutputAnalyzer(pb.start())
             .shouldContain("Incompatible definition of java.lang.Object")
             .shouldHaveExitValue(1);
--- a/hotspot/test/runtime/SharedArchiveFile/MaxMetaspaceSize.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/runtime/SharedArchiveFile/MaxMetaspaceSize.java	Thu May 12 11:03:07 2016 -0700
@@ -35,7 +35,7 @@
 public class MaxMetaspaceSize {
   public static void main(String[] args) throws Exception {
     ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
-        "-XX:MaxMetaspaceSize=20m", "-Xshare:dump");
+        "-XX:MaxMetaspaceSize=10m", "-Xshare:dump");
     OutputAnalyzer output = new OutputAnalyzer(pb.start());
       output.shouldContain("is not large enough.\nEither don't specify the -XX:MaxMetaspaceSize=<size>\nor increase the size to at least");
       output.shouldHaveExitValue(2);
--- a/hotspot/test/runtime/getSysPackage/GetSysPkgTest.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/runtime/getSysPackage/GetSysPkgTest.java	Thu May 12 11:03:07 2016 -0700
@@ -119,9 +119,9 @@
         getPkg("java/nio/charset", "jrt:/java.base");
 
         // Test a package in a module not owned by boot loader.
-        Class clss = Class.forName("javax.activation.DataHandler");
+        Class clss = Class.forName("jdk.nio.zipfs.ZipPath");
         if (clss == null)
-            throw new RuntimeException("Could not find class javax.activation.DataHandler");
+            throw new RuntimeException("Could not find class jdk.nio.zipfs.ZipPath");
         getPkg("javax/activation", null);       // Not owned by boot loader
 
         // Test a package not in jimage file.
--- a/hotspot/test/runtime/modules/AccessCheck/DiffCL_Umod.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/runtime/modules/AccessCheck/DiffCL_Umod.java	Thu May 12 11:03:07 2016 -0700
@@ -209,9 +209,9 @@
      // now use the same loader to load class p1.c1Loose
      Class p1_c1_class = MyDiffClassLoader.loader1.loadClass("p1.c1Loose");
 
-     // change m1 to be a loose module
+     // change m1 to read all unnamed modules
      Module m1 = layer.findModule("m1").get();
-     jdk.internal.module.Modules.addReads(m1, null);
+     jdk.internal.module.Modules.addReadsAllUnnamed(m1);
 
      try {
          p1_c1_class.newInstance();
--- a/hotspot/test/runtime/modules/AccessCheck/Umod.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/runtime/modules/AccessCheck/Umod.java	Thu May 12 11:03:07 2016 -0700
@@ -200,9 +200,9 @@
      // now use the same loader to load class p1.c1Loose
      Class p1_c1_class = loader.loadClass("p1.c1Loose");
 
-     // change m1 to be a loose module
+     // change m1 to read all unnamed modules
      Module m1 = layer.findModule("m1").get();
-     jdk.internal.module.Modules.addReads(m1, null);
+     jdk.internal.module.Modules.addReadsAllUnnamed(m1);
 
      try {
          p1_c1_class.newInstance();
--- a/hotspot/test/runtime/modules/JVMAddReadsModule.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/runtime/modules/JVMAddReadsModule.java	Thu May 12 11:03:07 2016 -0700
@@ -48,26 +48,27 @@
         assertNotNull(to_module, "Module should not be null");
         ModuleHelper.DefineModule(to_module, "9.0", "to_module/here", new String[] { "yourpackage" });
 
-        // Null from_module argument, expect an NPE
+        // Null from_module argument, expect NPE
         try {
             ModuleHelper.AddReadsModule(null, to_module);
             throw new RuntimeException("Failed to get the expected NPE");
-        } catch(NullPointerException e) {
+        } catch (NullPointerException e) {
             // Expected
         }
 
-        // Null to_module argument, do not expect an NPE
+        // Null to_module argument, expect NPE
         try {
             ModuleHelper.AddReadsModule(from_module, null);
-        } catch(NullPointerException e) {
             throw new RuntimeException("Unexpected NPE was thrown");
+        } catch (NullPointerException e) {
+            // Expected
         }
 
-        // Null from_module and to_module arguments, expect an NPE
+        // Null from_module and to_module arguments, expect NPE
         try {
             ModuleHelper.AddReadsModule(null, null);
             throw new RuntimeException("Failed to get the expected NPE");
-        } catch(NullPointerException e) {
+        } catch (NullPointerException e) {
             // Expected
         }
 
--- a/hotspot/test/runtime/modules/Visibility/XpatchVisibility.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/runtime/modules/Visibility/XpatchVisibility.java	Thu May 12 11:03:07 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
@@ -83,7 +83,7 @@
                                                            "p2" + File.separator + "Vis2_B.class"));
 
       new OutputAnalyzer(ProcessTools.createJavaProcessBuilder(
-              "-Xpatch:mods2",
+              "-Xpatch:java.base=mods2/java.base",
               "-XaddExports:java.base/p2=ALL-UNNAMED",
               "Vis2_A")
           .start()).shouldHaveExitValue(0);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/Xpatch/BasicJarBuilder.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+/*
+ * @summary Simple jar builder
+ *   Input: jarName className1 className2 ...
+ *     do not specify extensions, just the names
+ *     E.g. prot_domain ProtDomainA ProtDomainB
+ *   Output: A jar containing compiled classes, placed in a test classes folder
+ */
+
+import jdk.test.lib.*;
+
+import java.io.File;
+import java.util.ArrayList;
+import sun.tools.jar.Main;
+
+// Using JarBuilder requires that all to-be-jarred classes should be placed
+// in the current working directory, aka "."
+public class BasicJarBuilder {
+    private static final String classDir = System.getProperty("test.classes");
+
+    public static void build(boolean classesInWorkDir, String jarName,
+        String ...classNames) throws Exception {
+
+        if (classesInWorkDir) {
+            createSimpleJar(".", classDir + File.separator + jarName + ".jar", classNames);
+        } else {
+            build(jarName, classNames);
+        }
+    }
+
+    public static void build(String jarName, String ...classNames) throws Exception {
+        createSimpleJar(classDir, classDir + File.separator + jarName + ".jar",
+            classNames);
+    }
+
+    private static void createSimpleJar(String jarclassDir, String jarName,
+        String[] classNames) throws Exception {
+        ArrayList<String> args = new ArrayList<String>();
+        args.add("cf");
+        args.add(jarName);
+        addClassArgs(args, jarclassDir, classNames);
+        createJar(args);
+    }
+
+    private static void addClassArgs(ArrayList<String> args, String jarclassDir,
+        String[] classNames) {
+
+        for (String name : classNames) {
+            args.add("-C");
+            args.add(jarclassDir);
+            args.add(name + ".class");
+        }
+    }
+
+    private static void createJar(ArrayList<String> args) {
+        Main jarTool = new Main(System.out, System.err, "jar");
+        if (!jarTool.run(args.toArray(new String[1]))) {
+            throw new RuntimeException("jar operation failed");
+        }
+    }
+
+    // Get full path to the test jar
+    public static String getTestJar(String jar) {
+        File dir = new File(System.getProperty("test.classes", "."));
+        File jarFile = new File(dir, jar);
+        if (!jarFile.exists()) {
+            throw new RuntimeException("Cannot find " + jarFile.getPath());
+        }
+        if (!jarFile.isFile()) {
+            throw new RuntimeException("Not a regular file: " + jarFile.getPath());
+        }
+        return jarFile.getPath();
+    }
+}
--- a/hotspot/test/runtime/modules/Xpatch/Xpatch2Dirs.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/runtime/modules/Xpatch/Xpatch2Dirs.java	Thu May 12 11:03:07 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
@@ -57,7 +57,8 @@
              "mods2/java.desktop");
 
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
-             "-Xpatch:mods" + File.pathSeparator + "mods2",
+             "-Xpatch:java.naming=mods/java.naming",
+             "-Xpatch:java.desktop=mods2/java.desktop",
              "Xpatch2DirsMain", "javax.naming.spi.NamingManager", "java.beans.Encoder");
 
         OutputAnalyzer oa = new OutputAnalyzer(pb.start());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/Xpatch/XpatchDupJavaBase.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,45 @@
+/*
+ * 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 VM exit initialization results if java.base is specificed more than once to Xpatch.
+ * @library /testlibrary
+ */
+
+import jdk.test.lib.*;
+
+public class XpatchDupJavaBase {
+  // The VM should exit initialization if java.base is specified
+  // more than once to -Xpatch.
+  public static void main(String args[]) throws Exception {
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+      "-Xpatch:java.base=javabase_dir",
+      "-Xpatch:java.base=javabase_dir",
+      "-version");
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+    output.shouldContain("Cannot specify java.base more than once to -Xpatch");
+    output.shouldHaveExitValue(1);
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/Xpatch/XpatchDupModule.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,47 @@
+/*
+ * 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 Module system initialization exception results if a module is specificed twice to Xpatch.
+ * @library /testlibrary
+ */
+
+import jdk.test.lib.*;
+
+public class XpatchDupModule {
+
+  // The module system initialization should generate an ExceptionInInitializerError
+  // if -Xpatch is specified with the same module more than once.
+
+  public static void main(String args[]) throws Exception {
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+      "-Xpatch:module1=module1_dir",
+      "-Xpatch:module1=module1_dir",
+      "-version");
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+    output.shouldContain("java.lang.ExceptionInInitializerError");
+    output.shouldHaveExitValue(1);
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/Xpatch/XpatchJavaBase.java	Thu May 12 11:03:07 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 8130399
+ * @summary Make sure -Xpatch works for java.base.
+ * @library /testlibrary
+ * @compile XpatchMain.java
+ * @run main XpatchJavaBase
+ */
+
+import jdk.test.lib.*;
+
+public class XpatchJavaBase {
+
+    public static void main(String[] args) throws Exception {
+        String source = "package java.lang; "                       +
+                        "public class NewClass { "                  +
+                        "    static { "                             +
+                        "        System.out.println(\"I pass!\"); " +
+                        "    } "                                    +
+                        "}";
+
+        ClassFileInstaller.writeClassToDisk("java/lang/NewClass",
+             InMemoryJavaCompiler.compile("java.lang.NewClass", source, "-Xmodule:java.base"),
+             "mods/java.base");
+
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.base=mods/java.base",
+             "XpatchMain", "java.lang.NewClass");
+
+        new OutputAnalyzer(pb.start())
+            .shouldContain("I pass!")
+            .shouldHaveExitValue(0);
+    }
+}
--- a/hotspot/test/runtime/modules/Xpatch/XpatchTest.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/runtime/modules/Xpatch/XpatchTest.java	Thu May 12 11:03:07 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
@@ -46,7 +46,7 @@
              InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "-Xmodule:java.naming"),
              "mods/java.naming");
 
-        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:mods",
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.naming=mods/java.naming",
              "XpatchMain", "javax.naming.spi.NamingManager");
 
         new OutputAnalyzer(pb.start())
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/Xpatch/XpatchTestJar.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,83 @@
+/*
+ * 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 Make sure -Xpatch works when a jar file is specified for a module
+ * @library /testlibrary
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ * @build BasicJarBuilder
+ * @compile XpatchMain.java
+ * @run main XpatchTestJar
+ */
+
+import jdk.test.lib.*;
+
+public class XpatchTestJar {
+    private static String moduleJar;
+
+    public static void main(String[] args) throws Exception {
+
+        // Create a class file in the module java.naming. This class file
+        // will be put in the javanaming.jar file.
+        String source = "package javax.naming.spi; "                +
+                        "public class NamingManager { "             +
+                        "    static { "                             +
+                        "        System.out.println(\"I pass!\"); " +
+                        "    } "                                    +
+                        "}";
+
+        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager",
+             InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "-Xmodule:java.naming"),
+             System.getProperty("test.classes"));
+
+        // Build the jar file that will be used for the module "java.naming".
+        BasicJarBuilder.build("javanaming", "javax/naming/spi/NamingManager");
+        moduleJar = BasicJarBuilder.getTestJar("javanaming.jar");
+
+        // Just to make sure we are not fooled by the class file being on the
+        // class path where all the test classes are stored, write the NamingManager.class
+        // file out again with output that does not contain what OutputAnalyzer
+        // expects. This will provide confidence that the contents of the class
+        // is truly coming from the jar file and not the class file.
+        source =        "package javax.naming.spi; "                +
+                        "public class NamingManager { "             +
+                        "    static { "                             +
+                        "        System.out.println(\"Fail!\"); "   +
+                        "    } "                                    +
+                        "}";
+
+        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager",
+             InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "-Xmodule:java.naming"),
+             System.getProperty("test.classes"));
+
+        // Supply -Xpatch with the name of the jar file for the module java.naming.
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.naming=" + moduleJar,
+             "XpatchMain", "javax.naming.spi.NamingManager");
+
+        new OutputAnalyzer(pb.start())
+            .shouldContain("I pass!")
+            .shouldHaveExitValue(0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/Xpatch/XpatchTestJarDir.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,105 @@
+/*
+ * 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 Make sure -Xpatch works when a jar file and a directory is specified for a module
+ * @library /testlibrary
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ * @build BasicJarBuilder
+ * @compile Xpatch2DirsMain.java
+ * @run main XpatchTestJarDir
+ */
+
+import java.io.File;
+import java.nio.file.Files;
+import jdk.test.lib.*;
+
+public class XpatchTestJarDir {
+    private static String moduleJar;
+
+    public static void main(String[] args) throws Exception {
+
+        // Create a class file in the module java.naming. This class file
+        // will be put in the javanaming.jar file.
+        String source = "package javax.naming.spi; "                    +
+                        "public class NamingManager1 { "                +
+                        "    static { "                                 +
+                        "        System.out.println(\"I pass one!\"); " +
+                        "    } "                                        +
+                        "}";
+
+        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager1",
+             InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager1", source, "-Xmodule:java.naming"),
+             System.getProperty("test.classes"));
+
+        // Build the jar file that will be used for the module "java.naming".
+        BasicJarBuilder.build("javanaming", "javax/naming/spi/NamingManager1");
+        moduleJar = BasicJarBuilder.getTestJar("javanaming.jar");
+
+        // Just to make sure we are not fooled by the class file being on the
+        // class path where all the test classes are stored, write the NamingManager.class
+        // file out again with output that does not contain what OutputAnalyzer
+        // expects. This will provide confidence that the contents of the class
+        // is truly coming from the jar file and not the class file.
+        source = "package javax.naming.spi; "                +
+                 "public class NamingManager1 { "            +
+                 "    static { "                             +
+                 "        System.out.println(\"Fail!\"); "   +
+                 "    } "                                    +
+                 "}";
+
+        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager1",
+             InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager1", source, "-Xmodule:java.naming"),
+             System.getProperty("test.classes"));
+
+        // Create a second class file in the module java.naming. This class file
+        // will be put in the mods/java.naming directory.
+        source = "package javax.naming.spi; "                    +
+                 "public class NamingManager2 { "                +
+                 "    static { "                                 +
+                 "        System.out.println(\"I pass two!\"); " +
+                 "    } "                                        +
+                 "}";
+
+        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager2",
+             InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager2", source, "-Xmodule:java.naming"),
+             (System.getProperty("test.classes") + "/mods/java.naming"));
+
+
+        // Supply -Xpatch with the name of the jar file for the module java.naming.
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.naming=" +
+                                                                           moduleJar +
+                                                                           File.pathSeparator +
+                                                                           System.getProperty("test.classes") + "/mods/java.naming",
+                                                                  "Xpatch2DirsMain",
+                                                                  "javax.naming.spi.NamingManager1",
+                                                                  "javax.naming.spi.NamingManager2");
+
+        new OutputAnalyzer(pb.start())
+            .shouldContain("I pass one!")
+            .shouldContain("I pass two!")
+            .shouldHaveExitValue(0);
+    }
+}
--- a/hotspot/test/runtime/modules/Xpatch/XpatchTraceCL.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/runtime/modules/Xpatch/XpatchTraceCL.java	Thu May 12 11:03:07 2016 -0700
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8069469
- * @summary Make sure -XX:+TraceClassLoading works properly with "modules" jimage,
+ * @summary Make sure -Xlog:classload=info works properly with "modules" jimage,
             -Xpatch, and with -Xbootclasspath/a
  * @library /testlibrary
  * @compile XpatchMain.java
@@ -44,24 +44,23 @@
                         "    } "                                    +
                         "}";
 
-        // Test -XX:+TraceClassLoading output for -Xpatch
+        // Test -Xlog:classload=info output for -Xpatch
         ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager",
              InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "-Xmodule:java.naming"),
              "mods/java.naming");
 
-        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:mods",
-             "-XX:+TraceClassLoading", "XpatchMain", "javax.naming.spi.NamingManager");
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.naming=mods/java.naming",
+             "-Xlog:classload=info", "XpatchMain", "javax.naming.spi.NamingManager");
 
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
         // "modules" jimage case.
         output.shouldContain("[classload] java.lang.Thread source: jrt:/java.base");
         // -Xpatch case.
-        output.shouldContain("[classload] javax.naming.spi.NamingManager source: mods" +
-            File.separator + "java.naming");
+        output.shouldContain("[classload] javax.naming.spi.NamingManager source: mods/java.naming");
         // -cp case.
         output.shouldContain("[classload] XpatchMain source: file");
 
-        // Test -XX:+TraceClassLoading output for -Xbootclasspath/a
+        // Test -Xlog:classload=info output for -Xbootclasspath/a
         source = "package XpatchTraceCL_pkg; "                 +
                  "public class ItIsI { "                          +
                  "    static { "                                  +
@@ -74,7 +73,7 @@
              "xbcp");
 
         pb = ProcessTools.createJavaProcessBuilder("-Xbootclasspath/a:xbcp",
-             "-XX:+TraceClassLoading", "XpatchMain", "XpatchTraceCL_pkg.ItIsI");
+             "-Xlog:classload=info", "XpatchMain", "XpatchTraceCL_pkg.ItIsI");
         output = new OutputAnalyzer(pb.start());
         // -Xbootclasspath/a case.
         output.shouldContain("[classload] XpatchTraceCL_pkg.ItIsI source: xbcp");
--- a/hotspot/test/runtime/modules/XpatchCDS.java	Thu May 12 20:43:37 2016 +0400
+++ b/hotspot/test/runtime/modules/XpatchCDS.java	Thu May 12 11:03:07 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
@@ -35,7 +35,7 @@
 
     public static void main(String args[]) throws Throwable {
         System.out.println("Test that -Xpatch and -Xshare:dump are incompatibable");
-        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:.", "-Xshare:dump");
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.naming=mods/java.naming", "-Xshare:dump");
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
         output.shouldContain("Cannot use the following option when dumping the shared archive: -Xpatch");
 
@@ -52,7 +52,7 @@
             "-XX:+UnlockDiagnosticVMOptions",
             "-XX:SharedArchiveFile=" + filename,
             "-Xshare:on",
-            "-Xpatch:.",
+            "-Xpatch:java.naming=mods/java.naming",
             "-version");
         output = new OutputAnalyzer(pb.start());
         output.shouldContain("The shared archive file cannot be used with -Xpatch");
--- a/jaxp/.hgtags	Thu May 12 20:43:37 2016 +0400
+++ b/jaxp/.hgtags	Thu May 12 11:03:07 2016 -0700
@@ -359,3 +359,4 @@
 147114dd0641cd7c9fe6e81642eb993a7b9c6f0b jdk-9+114
 1902a5bda18e794b31fc5f520f5e7d827714b50d jdk-9+115
 9d71d20e614777cd23c1a43b38b5c08a9094d27a jdk-9+116
+46b57560cd06ebcdd21489250628ff5f9d9d8916 jdk-9+117
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java	Thu May 12 20:43:37 2016 +0400
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java	Thu May 12 11:03:07 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -32,19 +32,26 @@
 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
 import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
 import java.io.IOException;
+import java.io.UncheckedIOException;
 import java.io.NotSerializableException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.ObjectStreamField;
 import java.io.Serializable;
-import java.util.Arrays;
-import java.util.Collections;
+import java.lang.module.Configuration;
+import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleFinder;
+import java.lang.module.ModuleReference;
+import java.lang.reflect.Layer;
+import java.lang.reflect.Module;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-import java.lang.reflect.Module;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Properties;
+import java.util.Set;
 import javax.xml.XMLConstants;
 import javax.xml.transform.Templates;
 import javax.xml.transform.Transformer;
@@ -389,6 +396,48 @@
         return _name;
     }
 
+
+    /**
+     * Creates a module layer with one module that is defined to the given class
+     * loader.
+     */
+    private Module createModule(ModuleDescriptor descriptor, ClassLoader loader) {
+        String mn = descriptor.name();
+
+        ModuleReference mref = new ModuleReference(descriptor, null, () -> {
+            IOException ioe = new IOException("<dynamic module>");
+            throw new UncheckedIOException(ioe);
+        });
+
+        ModuleFinder finder = new ModuleFinder() {
+            @Override
+            public Optional<ModuleReference> find(String name) {
+                if (name.equals(mn)) {
+                    return Optional.of(mref);
+                } else {
+                    return Optional.empty();
+                }
+            }
+            @Override
+            public Set<ModuleReference> findAll() {
+                return Set.of(mref);
+            }
+        };
+
+        Layer bootLayer = Layer.boot();
+
+        Configuration cf = bootLayer.configuration()
+                .resolveRequires(finder, ModuleFinder.empty(), Set.of(mn));
+
+        PrivilegedAction<Layer> pa = () -> bootLayer.defineModules(cf, name -> loader);
+        Layer layer = AccessController.doPrivileged(pa);
+
+        Module m = layer.findModule(mn).get();
+        assert m.getLayer() == layer;
+
+        return m;
+    }
+
     /**
      * Defines the translet class and auxiliary classes.
      * Returns a reference to the Class object that defines the main class
@@ -417,29 +466,32 @@
             }
 
             // create a module for the translet
-            Module xmlModule = TemplatesImpl.class.getModule();
+
+            String mn = "jdk.translet";
+
             String pn = _tfactory.getPackageName();
             assert pn != null && pn.length() > 0;
 
-            Module m = Modules.defineModule(loader, "jdk.translet",
-                                            Collections.singleton(pn));
+            ModuleDescriptor descriptor
+                = new ModuleDescriptor.Builder(mn)
+                    .requires("java.xml")
+                    .exports(pn)
+                    .build();
 
-            // jdk.translate reads java.base && java.xml
-            Modules.addReads(m, Object.class.getModule());
-            Modules.addReads(m, xmlModule);
+            Module m = createModule(descriptor, loader);
 
-            // jdk.translet needs access to runtime classes
+            // the module needs access to runtime classes
+            Module thisModule = TemplatesImpl.class.getModule();
             Arrays.asList(Constants.PKGS_USED_BY_TRANSLET_CLASSES).forEach(p -> {
-                xmlModule.addExports(p, m);
+                thisModule.addExports(p, m);
             });
 
-            // jdk.translate also needs to be loose as the XSL may bind to
-            // java types in an unnamed module
-            Modules.addReads(m, null);
+            // For now, the module reads all unnnamed modules. This will be changed once
+            // the XSLT compiler is updated to generate code to invoke addReads.
+            Modules.addReadsAllUnnamed(m);
 
-            // java.xml needs to instanitate the translate class
-            xmlModule.addReads(m);
-            Modules.addExports(m, pn, xmlModule);
+            // java.xml needs to instanitate the translet class
+            thisModule.addReads(m);
 
             for (int i = 0; i < classCount; i++) {
                 _class[i] = loader.defineClass(_bytecodes[i]);
--- a/jaxp/test/ProblemList.txt	Thu May 12 20:43:37 2016 +0400
+++ b/jaxp/test/ProblemList.txt	Thu May 12 11:03:07 2016 -0700
@@ -26,3 +26,6 @@
 # 8147431 
 javax/xml/jaxp/isolatedjdk/catalog/PropertiesTest.sh            generic-all
 
+# 8150145
+javax/xml/jaxp/unittest/common/TransformationWarningsTest.java	generic-all
+
--- a/jaxp/test/TEST.ROOT	Thu May 12 20:43:37 2016 +0400
+++ b/jaxp/test/TEST.ROOT	Thu May 12 11:03:07 2016 -0700
@@ -18,4 +18,4 @@
 groups=TEST.groups 
 
 # Minimum jtreg version
-requiredVersion=4.2 b01
+requiredVersion=4.2 b02
--- a/jaxp/test/javax/xml/jaxp/libs/jaxp/library/TestPolicy.java	Thu May 12 20:43:37 2016 +0400
+++ b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/TestPolicy.java	Thu May 12 11:03:07 2016 -0700
@@ -36,6 +36,7 @@
 import java.util.PropertyPermission;
 import java.util.StringJoiner;
 
+
 /*
  * Simple Policy class that supports the required Permissions to validate the
  * JAXP concrete classes.
@@ -45,6 +46,8 @@
 public class TestPolicy extends Policy {
     protected final PermissionCollection permissions = new Permissions();
 
+    private static Policy defaultPolicy = Policy.getPolicy();
+
     /**
      * Constructor which sets the minimum permissions by default allowing testNG
      * to work with a SecurityManager.
@@ -87,11 +90,8 @@
                 "read"));
         permissions.add(new PropertyPermission("user.dir", "read"));
         permissions.add(new PropertyPermission("test.src", "read"));
-        permissions.add(new PropertyPermission("file.separator", "read"));
-        permissions.add(new PropertyPermission("line.separator", "read"));
         permissions.add(new PropertyPermission("fileStringBuffer", "read"));
         permissions.add(new PropertyPermission("dataproviderthreadcount", "read"));
-        permissions.add(new RuntimePermission("charsetProvider"));
     }
 
     /*
@@ -145,6 +145,9 @@
 
     @Override
     public boolean implies(ProtectionDomain domain, Permission perm) {
+        if (defaultPolicy.implies(domain, perm))
+            return true;
+
         return permissions.implies(perm);
     }
 }
--- a/jaxws/.hgtags	Thu May 12 20:43:37 2016 +0400
+++ b/jaxws/.hgtags	Thu May 12 11:03:07 2016 -0700
@@ -362,3 +362,4 @@
 b314bb02182b9ca94708a91f312c377f5435f740 jdk-9+114
 4ff86e5489e4c0513dadfa69def8601c110ca5cd jdk-9+115
 529f0bf896e58525614d863e283ad155531941cb jdk-9+116
+58265b39fc74b932bda4d4f4649c530a89f55c4e jdk-9+117
--- a/jaxws/src/jdk.xml.bind/share/classes/com/sun/tools/internal/jxc/SchemaGenerator.java	Thu May 12 20:43:37 2016 +0400
+++ b/jaxws/src/jdk.xml.bind/share/classes/com/sun/tools/internal/jxc/SchemaGenerator.java	Thu May 12 11:03:07 2016 -0700
@@ -140,6 +140,9 @@
         aptargs.add("-cp");
         aptargs.add(setClasspath(options.classpath)); // set original classpath + jaxb-api to be visible to annotation processor
 
+        aptargs.add("-addmods");
+        aptargs.add("java.xml.bind");
+
         if(options.targetDir!=null) {
             aptargs.add("-d");
             aptargs.add(options.targetDir.getPath());
--- a/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/wscompile/WsgenTool.java	Thu May 12 20:43:37 2016 +0400
+++ b/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/wscompile/WsgenTool.java	Thu May 12 11:03:07 2016 -0700
@@ -162,6 +162,8 @@
         boolean bootCP = useBootClasspath(EndpointReference.class) || useBootClasspath(XmlSeeAlso.class);
         List<String> args = new ArrayList<String>(6 + (bootCP ? 1 : 0) + (options.nocompile ? 1 : 0)
                 + (options.encoding != null ? 2 : 0));
+        args.add("-addmods");
+        args.add("java.xml.ws");
         args.add("-d");
         args.add(options.destDir.getAbsolutePath());
         args.add("-classpath");
--- a/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/wscompile/WsimportTool.java	Thu May 12 20:43:37 2016 +0400
+++ b/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/wscompile/WsimportTool.java	Thu May 12 11:03:07 2016 -0700
@@ -525,6 +525,8 @@
             String classpathString = createClasspathString();
             boolean bootCP = useBootClasspath(EndpointContext.class) || useBootClasspath(JAXBPermission.class);
             List<String> args = new ArrayList<String>();
+            args.add("-addmods");
+            args.add("java.xml.ws");
             args.add("-d");
             args.add(classDir);
             args.add("-classpath");
--- a/jdk/make/Tools.gmk	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/make/Tools.gmk	Thu May 12 11:03:07 2016 -0700
@@ -37,10 +37,6 @@
 
 ################################################################################
 
-# Add a checksum ("jsum") to the end of a text file. Prevents trivial tampering with class lists.
-TOOL_ADDJSUM = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
-    build.tools.addjsum.AddJsum
-
 ifeq ($(BOOT_JDK_MODULAR), true)
   COMPILEFONTCONFIG_ADD_EXPORTS := -XaddExports:java.desktop/sun.awt=ALL-UNNAMED
 endif
--- a/jdk/make/non-build-utils/src/build/tools/makeclasslist/makeClasslist.js	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +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.
- */
-
-/**
- * This tool is used to help create the class list for class data sharing.
- *
- * The classlist is produced internally by first running a select number of
- * startup benchmarks with the -XX:DumpLoadedClassList=<file> option, then
- * running this tool in the following fashion to produce a complete classlist:
- *
- * jjs -scripting makeClasslist.js -- list1 list2 list3 > classlist.platform
- *
- * The lists should be listed in roughly smallest to largest order based on
- * application size.
- *
- * After generating the classlist it's necessary to add a checksum (using
- * AddJsum.java) before checking it into the workspace as the corresponding
- * platform-specific classlist, such as make/data/classlist/classlist.linux 
- */
-"use strict";
-var classlist = [];
-var seenClasses = {};
-
-for (var a in $ARG) {
-  var arg = $ARG[a];
-
-  var classes = readFully(arg).replace(/[\r\n]+/g, "\n").split("\n");
-
-  for (var c in classes) {
-    var clazz = classes[c];
-    if (clazz !== "" && seenClasses[clazz] === undefined) {
-      seenClasses[clazz] = clazz;
-      classlist.push(clazz);
-    }
-  }
-}
-
-for (c in classlist) {
-  print(classlist[c]);
-}
--- a/jdk/make/src/classes/build/tools/addjsum/AddJsum.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package build.tools.addjsum;
-
-import java.io.*;
-import java.util.regex.*;
-
-/** Adds a checksum ("jsum") to the end of a text file. The algorithm
-    used is known to the JVM and prevents trivial tampering with the
-    class list used for class data sharing.
-*/
-
-public class AddJsum {
-  private static final long JSUM_SEED = 0xCAFEBABEBABECAFEL;
-
-  public static void main(String[] args) throws Exception {
-    if (args.length != 2) {
-      System.err.println("Usage: java AddJsum [input file name] [output file name]");
-      System.exit(1);
-    }
-
-    try {
-      File inFile  = new File(args[0]);
-      File outFile = new File(args[1]);
-      BufferedReader reader = new BufferedReader(new FileReader(inFile));
-      BufferedWriter writer = new BufferedWriter(new FileWriter(outFile));
-      Pattern p = Pattern.compile("# [0-9A-Fa-f]*");
-      long computedJsum = JSUM_SEED;
-
-      String line = null;
-      while ((line = reader.readLine()) != null) {
-        if (line.length() > 0 && line.charAt(0) == '#') {
-          Matcher m = p.matcher(line);
-          if (!m.matches()) {
-            writer.write(line);
-            writer.newLine();
-          }
-        } else {
-          computedJsum = jsum(computedJsum, line);
-          writer.write(line);
-          writer.newLine();
-        }
-      }
-      String hex = Long.toHexString(computedJsum);
-      int diff = 16 - hex.length();
-      for (int i = 0; i < diff; i++) {
-        hex = "0" + hex;
-      }
-      writer.write("# " + hex);
-      writer.newLine();
-      reader.close();
-      writer.close();
-    } catch (IOException e) {
-      System.err.println("Error reading or writing file");
-      throw(e);
-    }
-  }
-
-  private static long jsum(long start, String str) {
-    long h = start;
-    int len = str.length();
-    for (int i = 0; i < len; i++) {
-      char c = str.charAt(i);
-      if (c <= ' ') {
-        /* Skip spaces and control characters */
-        continue;
-      }
-      h = 31 * h + c;
-    }
-    return h;
-  }
-}
--- a/jdk/src/java.base/share/classes/java/lang/Integer.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/lang/Integer.java	Thu May 12 11:03:07 2016 -0700
@@ -1221,13 +1221,13 @@
     }
 
     /**
-     * Returns a hash code for a {@code int} value; compatible with
+     * Returns a hash code for an {@code int} value; compatible with
      * {@code Integer.hashCode()}.
      *
      * @param value the value to hash
      * @since 1.8
      *
-     * @return a hash code value for a {@code int} value.
+     * @return a hash code value for an {@code int} value.
      */
     public static int hashCode(int value) {
         return value;
@@ -1596,7 +1596,7 @@
     @Native public static final int SIZE = 32;
 
     /**
-     * The number of bytes used to represent a {@code int} value in two's
+     * The number of bytes used to represent an {@code int} value in two's
      * complement binary form.
      *
      * @since 1.8
@@ -1790,9 +1790,8 @@
         i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
         i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
         i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
-        i = (i << 24) | ((i & 0xff00) << 8) |
-            ((i >>> 8) & 0xff00) | (i >>> 24);
-        return i;
+
+        return reverseBytes(i);
     }
 
     /**
@@ -1820,10 +1819,10 @@
      */
     @HotSpotIntrinsicCandidate
     public static int reverseBytes(int i) {
-        return ((i >>> 24)           ) |
-               ((i >>   8) &   0xFF00) |
-               ((i <<   8) & 0xFF0000) |
-               ((i << 24));
+        return (i << 24)            |
+               ((i & 0xff00) << 8)  |
+               ((i >>> 8) & 0xff00) |
+               (i >>> 24);
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/lang/Long.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/lang/Long.java	Thu May 12 11:03:07 2016 -0700
@@ -1952,10 +1952,8 @@
         i = (i & 0x5555555555555555L) << 1 | (i >>> 1) & 0x5555555555555555L;
         i = (i & 0x3333333333333333L) << 2 | (i >>> 2) & 0x3333333333333333L;
         i = (i & 0x0f0f0f0f0f0f0f0fL) << 4 | (i >>> 4) & 0x0f0f0f0f0f0f0f0fL;
-        i = (i & 0x00ff00ff00ff00ffL) << 8 | (i >>> 8) & 0x00ff00ff00ff00ffL;
-        i = (i << 48) | ((i & 0xffff0000L) << 16) |
-            ((i >>> 16) & 0xffff0000L) | (i >>> 48);
-        return i;
+
+        return reverseBytes(i);
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/lang/SecurityManager.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/lang/SecurityManager.java	Thu May 12 11:03:07 2016 -0700
@@ -1627,8 +1627,7 @@
      * @deprecated This method relies on the caller being at a stack depth
      *             of 4 which is error-prone and cannot be enforced by the runtime.
      *             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}.
+     *             directly.
      *             This method is subject to removal in a future version of Java SE.
      *
      * @see java.lang.reflect.Member
--- a/jdk/src/java.base/share/classes/java/lang/StackFrameInfo.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/lang/StackFrameInfo.java	Thu May 12 11:03:07 2016 -0700
@@ -29,21 +29,20 @@
 
 import static java.lang.StackWalker.Option.*;
 import java.lang.StackWalker.StackFrame;
-import java.lang.reflect.Module;
 import java.util.Optional;
 import java.util.OptionalInt;
 
 class StackFrameInfo implements StackFrame {
-    private final static JavaLangInvokeAccess jlInvokeAccess =
+    private final static JavaLangInvokeAccess JLIA =
         SharedSecrets.getJavaLangInvokeAccess();
 
     // Footprint improvement: MemberName::clazz can replace
     // StackFrameInfo::declaringClass.
 
-    final StackWalker walker;
-    final Class<?> declaringClass;
-    final Object memberName;
-    final short bci;
+    private final StackWalker walker;
+    private final Class<?> declaringClass;
+    private final Object memberName;
+    private final short bci;
     private volatile StackTraceElement ste;
 
     /*
@@ -54,9 +53,17 @@
         this.walker = walker;
         this.declaringClass = null;
         this.bci = -1;
-        this.memberName = jlInvokeAccess.newMemberName();
+        this.memberName = JLIA.newMemberName();
     }
 
+    // package-private called by StackStreamFactory to skip
+    // the capability check
+    Class<?> declaringClass() {
+        return declaringClass;
+    }
+
+    // ----- implementation of StackFrame methods
+
     @Override
     public String getClassName() {
         return declaringClass.getName();
@@ -70,31 +77,39 @@
 
     @Override
     public String getMethodName() {
-        return jlInvokeAccess.getName(memberName);
+        return JLIA.getName(memberName);
     }
 
     @Override
-    public final Optional<String> getFileName() {
-        StackTraceElement ste = toStackTraceElement();
-        return ste.getFileName() != null ? Optional.of(ste.getFileName()) : Optional.empty();
+    public int getByteCodeIndex() {
+        return bci;
     }
 
     @Override
-    public final OptionalInt getLineNumber() {
-        StackTraceElement ste = toStackTraceElement();
-        return ste.getLineNumber() > 0 ? OptionalInt.of(ste.getLineNumber()) : OptionalInt.empty();
+    public String getFileName() {
+        if (isNativeMethod())
+            return null;
+
+        return toStackTraceElement().getFileName();
     }
 
     @Override
-    public final boolean isNativeMethod() {
-        StackTraceElement ste = toStackTraceElement();
-        return ste.isNativeMethod();
+    public int getLineNumber() {
+        if (isNativeMethod())
+            return -2;
+
+        return toStackTraceElement().getLineNumber();
+    }
+
+
+    @Override
+    public boolean isNativeMethod() {
+        return JLIA.isNative(memberName);
     }
 
     @Override
     public String toString() {
-        StackTraceElement ste = toStackTraceElement();
-        return ste.toString();
+        return toStackTraceElement().toString();
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java	Thu May 12 11:03:07 2016 -0700
@@ -492,7 +492,7 @@
 
             @Override
             final Class<?> at(int index) {
-                return stackFrames[index].declaringClass;
+                return stackFrames[index].declaringClass();
             }
         }
 
@@ -761,7 +761,7 @@
 
             @Override
             final Class<?> at(int index) {
-                return stackFrames[index].declaringClass;
+                return stackFrames[index].declaringClass();
             }
         }
 
--- a/jdk/src/java.base/share/classes/java/lang/StackWalker.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/lang/StackWalker.java	Thu May 12 11:03:07 2016 -0700
@@ -127,6 +127,20 @@
         public Class<?> getDeclaringClass();
 
         /**
+         * Returns the index to the code array of the {@code Code} attribute
+         * containing the execution point represented by this stack frame.
+         * The code array gives the actual bytes of Java Virtual Machine code
+         * that implement the method.
+         *
+         * @return the index to the code array of the {@code Code} attribute
+         *         containing the execution point represented by this stack frame,
+         *         or a negative number if the method is native.
+         *
+         * @jvms 4.7.3 The {@code Code} Attribute
+         */
+        public int getByteCodeIndex();
+
+        /**
          * Returns the name of the source file containing the execution point
          * represented by this stack frame.  Generally, this corresponds
          * to the {@code SourceFile} attribute of the relevant {@code class}
@@ -135,12 +149,12 @@
          * other than a file, such as an entry in a source repository.
          *
          * @return the name of the file containing the execution point
-         *         represented by this stack frame, or empty {@code Optional}
-         *         is unavailable.
+         *         represented by this stack frame, or {@code null} if
+         *         this information is unavailable.
          *
          * @jvms 4.7.10 The {@code SourceFile} Attribute
          */
-        public Optional<String> getFileName();
+        public String getFileName();
 
         /**
          * Returns the line number of the source line containing the execution
@@ -150,12 +164,12 @@
          * Specification</cite>.
          *
          * @return the line number of the source line containing the execution
-         *         point represented by this stack frame, or empty
-         *         {@code Optional} if this information is unavailable.
+         *         point represented by this stack frame, or a negative number if
+         *         this information is unavailable.
          *
          * @jvms 4.7.12 The {@code LineNumberTable} Attribute
          */
-        public OptionalInt getLineNumber();
+        public int getLineNumber();
 
         /**
          * Returns {@code true} if the method containing the execution point
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java	Thu May 12 11:03:07 2016 -0700
@@ -25,6 +25,8 @@
 
 package java.lang.invoke;
 
+import jdk.internal.misc.JavaLangInvokeAccess;
+import jdk.internal.misc.SharedSecrets;
 import sun.invoke.util.BytecodeDescriptor;
 import sun.invoke.util.VerifyAccess;
 
@@ -1143,15 +1145,25 @@
     }
 
     static {
-        // Allow privileged classes outside of java.lang
-        jdk.internal.misc.SharedSecrets.setJavaLangInvokeAccess(new jdk.internal.misc.JavaLangInvokeAccess() {
+        // StackFrameInfo stores Member and this provides the shared secrets
+        // for stack walker to access MemberName information.
+        SharedSecrets.setJavaLangInvokeAccess(new JavaLangInvokeAccess() {
+            @Override
             public Object newMemberName() {
                 return new MemberName();
             }
+
+            @Override
             public String getName(Object mname) {
                 MemberName memberName = (MemberName)mname;
                 return memberName.getName();
             }
+
+            @Override
+            public boolean isNative(Object mname) {
+                MemberName memberName = (MemberName)mname;
+                return memberName.isNative();
+            }
         });
     }
 }
--- a/jdk/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java	Thu May 12 11:03:07 2016 -0700
@@ -318,7 +318,7 @@
         /**
          * Tests this module export for equality with the given object.
          *
-         * <p> If the given object is not a {@code Exports} then this method
+         * <p> If the given object is not an {@code Exports} then this method
          * returns {@code false}. Two module exports objects are equal if the
          * package names are equal and the set of target module names is equal.
          * </p>
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Field.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Field.java	Thu May 12 11:03:07 2016 -0700
@@ -903,7 +903,7 @@
      * Sets the value of a field as an {@code int} on the specified object.
      * This method is equivalent to
      * {@code set(obj, iObj)},
-     * where {@code iObj} is a {@code Integer} object and
+     * where {@code iObj} is an {@code Integer} object and
      * {@code iObj.intValue() == i}.
      *
      * @param obj the object whose field should be modified
--- a/jdk/src/java.base/share/classes/java/lang/reflect/InaccessibleObjectException.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/InaccessibleObjectException.java	Thu May 12 11:03:07 2016 -0700
@@ -36,13 +36,13 @@
     private static final long serialVersionUID = 4158786093378140901L;
 
     /**
-     * Constructs a {@code InaccessibleObjectException} with no detail message.
+     * Constructs an {@code InaccessibleObjectException} with no detail message.
      */
     public InaccessibleObjectException() {
     }
 
     /**
-     * Constructs a {@code InaccessibleObjectException} with the given detail
+     * Constructs an {@code InaccessibleObjectException} with the given detail
      * message.
      *
      * @param msg
--- a/jdk/src/java.base/share/classes/java/math/BigInteger.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/math/BigInteger.java	Thu May 12 11:03:07 2016 -0700
@@ -4676,7 +4676,7 @@
      *
      * @return this {@code BigInteger} converted to an {@code int}.
      * @throws ArithmeticException if the value of {@code this} will
-     * not exactly fit in a {@code int}.
+     * not exactly fit in an {@code int}.
      * @see BigInteger#intValue
      * @since  1.8
      */
--- a/jdk/src/java.base/share/classes/java/net/InetSocketAddress.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/net/InetSocketAddress.java	Thu May 12 11:03:07 2016 -0700
@@ -246,7 +246,7 @@
      *                  the range of valid port values, or if the hostname
      *                  parameter is {@code null}.
      * @see     #isUnresolved()
-     * @return  a {@code InetSocketAddress} representing the unresolved
+     * @return  an {@code InetSocketAddress} representing the unresolved
      *          socket address
      * @since 1.5
      */
--- a/jdk/src/java.base/share/classes/java/net/URLDecoder.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/net/URLDecoder.java	Thu May 12 11:03:07 2016 -0700
@@ -106,8 +106,8 @@
     }
 
     /**
-     * Decodes a {@code application/x-www-form-urlencoded} string using a specific
-     * encoding scheme.
+     * Decodes an {@code application/x-www-form-urlencoded} string using
+     * a specific encoding scheme.
      * The supplied encoding is used to determine
      * what characters are represented by any consecutive sequences of the
      * form "<i>{@code %xy}</i>".
--- a/jdk/src/java.base/share/classes/java/net/URLEncoder.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/net/URLEncoder.java	Thu May 12 11:03:07 2016 -0700
@@ -225,7 +225,7 @@
                     /*
                      * If this character represents the start of a Unicode
                      * surrogate pair, then pass in two characters. It's not
-                     * clear what should be done if a bytes reserved in the
+                     * clear what should be done if a byte reserved in the
                      * surrogate pairs range occurs outside of a legal
                      * surrogate pair. For now, just treat it as if it were
                      * any other character.
--- a/jdk/src/java.base/share/classes/java/security/DrbgParameters.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/security/DrbgParameters.java	Thu May 12 11:03:07 2016 -0700
@@ -196,10 +196,9 @@
  * of the JDK reference implementation.
  * <p>
  * This implementation supports the Hash_DRBG and HMAC_DRBG mechanisms with
- * DRBG algorithm SHA-1, SHA-224, SHA-512/224, SHA-256, SHA-512/256,
- * SHA-384 and SHA-512, and CTR_DRBG (both using derivation function and
- * not using derivation function) with DRBG algorithm 3KeyTDEA
- * (also known as DESede in JCE), AES-128, AES-192 and AES-256.
+ * DRBG algorithm SHA-224, SHA-512/224, SHA-256, SHA-512/256, SHA-384 and
+ * SHA-512, and CTR_DRBG (both using derivation function and not using
+ * derivation function) with DRBG algorithm AES-128, AES-192 and AES-256.
  * <p>
  * The mechanism name and DRBG algorithm name are determined by the
  * {@linkplain Security#getProperty(String) security property}
--- a/jdk/src/java.base/share/classes/java/security/InvalidAlgorithmParameterException.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/security/InvalidAlgorithmParameterException.java	Thu May 12 11:03:07 2016 -0700
@@ -65,7 +65,7 @@
     }
 
     /**
-     * Creates a {@code InvalidAlgorithmParameterException} with the
+     * Creates an {@code InvalidAlgorithmParameterException} with the
      * specified detail message and cause.
      *
      * @param message the detail message (which is saved for later retrieval
@@ -80,7 +80,7 @@
     }
 
     /**
-     * Creates a {@code InvalidAlgorithmParameterException} with the
+     * Creates an {@code InvalidAlgorithmParameterException} with the
      * specified cause and a detail message of
      * {@code (cause==null ? null : cause.toString())}
      * (which typically contains the class and detail message of
--- a/jdk/src/java.base/share/classes/java/security/InvalidKeyException.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/security/InvalidKeyException.java	Thu May 12 11:03:07 2016 -0700
@@ -58,7 +58,7 @@
     }
 
     /**
-     * Creates a {@code InvalidKeyException} with the specified
+     * Creates an {@code InvalidKeyException} with the specified
      * detail message and cause.
      *
      * @param message the detail message (which is saved for later retrieval
@@ -73,7 +73,7 @@
     }
 
     /**
-     * Creates a {@code InvalidKeyException} with the specified cause
+     * Creates an {@code InvalidKeyException} with the specified cause
      * and a detail message of {@code (cause==null ? null : cause.toString())}
      * (which typically contains the class and detail message of
      * {@code cause}).
--- a/jdk/src/java.base/share/classes/java/security/ProtectionDomain.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/security/ProtectionDomain.java	Thu May 12 11:03:07 2016 -0700
@@ -139,12 +139,10 @@
      */
     final Key key = new Key();
 
-    private static final Debug debug = Debug.getInstance("domain");
-
     /**
      * Creates a new ProtectionDomain with the given CodeSource and
      * Permissions. If the permissions object is not null, then
-     *  {@code setReadOnly())} will be called on the passed in
+     *  {@code setReadOnly()} will be called on the passed in
      * Permissions object. The only permissions granted to this domain
      * are the ones specified; the current Policy will not be consulted.
      *
@@ -338,6 +336,13 @@
             " "+pc+"\n";
     }
 
+    /*
+     * holder class for the static field "debug" to delay its initialization
+     */
+    private static class DebugHolder {
+        private static final Debug debug = Debug.getInstance("domain");
+    }
+
     /**
      * Return true (merge policy permissions) in the following cases:
      *
@@ -359,7 +364,7 @@
         if (sm == null) {
             return true;
         } else {
-            if (debug != null) {
+            if (DebugHolder.debug != null) {
                 if (sm.getClass().getClassLoader() == null &&
                     Policy.getPolicyNoCheck().getClass().getClassLoader()
                                                                 == null) {
--- a/jdk/src/java.base/share/classes/java/security/Provider.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/security/Provider.java	Thu May 12 11:03:07 2016 -0700
@@ -1809,7 +1809,7 @@
         }
 
         /**
-         * Return whether this service has its Supported* properties for
+         * Return whether this service has its supported properties for
          * keys defined. Parses the attributes if not yet initialized.
          */
         private boolean hasKeyAttributes() {
--- a/jdk/src/java.base/share/classes/java/security/SecureClassLoader.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/security/SecureClassLoader.java	Thu May 12 11:03:07 2016 -0700
@@ -62,8 +62,6 @@
     private final Map<CodeSourceKey, ProtectionDomain> pdcache
             = new ConcurrentHashMap<>(11);
 
-    private static final Debug debug = Debug.getInstance("scl");
-
     static {
         ClassLoader.registerAsParallelCapable();
     }
@@ -203,6 +201,13 @@
     }
 
     /*
+     * holder class for the static field "debug" to delay its initialization
+     */
+    private static class DebugHolder {
+        private static final Debug debug = Debug.getInstance("scl");
+    }
+
+    /*
      * Returned cached ProtectionDomain for the specified CodeSource.
      */
     private ProtectionDomain getProtectionDomain(CodeSource cs) {
@@ -222,9 +227,9 @@
                         = SecureClassLoader.this.getPermissions(cs);
                 ProtectionDomain pd = new ProtectionDomain(
                         cs, perms, SecureClassLoader.this, null);
-                if (debug != null) {
-                    debug.println(" getPermissions " + pd);
-                    debug.println("");
+                if (DebugHolder.debug != null) {
+                    DebugHolder.debug.println(" getPermissions " + pd);
+                    DebugHolder.debug.println("");
                 }
                 return pd;
             }
--- a/jdk/src/java.base/share/classes/java/security/Security.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/security/Security.java	Thu May 12 11:03:07 2016 -0700
@@ -549,7 +549,7 @@
 
     /**
      * Returns an array containing all installed providers that satisfy the
-     * specified* selection criteria, or null if no such providers have been
+     * specified selection criteria, or null if no such providers have been
      * installed. The returned providers are ordered
      * according to their
      * {@linkplain #insertProviderAt(java.security.Provider, int)
--- a/jdk/src/java.base/share/classes/java/security/spec/InvalidKeySpecException.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/security/spec/InvalidKeySpecException.java	Thu May 12 11:03:07 2016 -0700
@@ -63,7 +63,7 @@
     }
 
     /**
-     * Creates a {@code InvalidKeySpecException} with the specified
+     * Creates an {@code InvalidKeySpecException} with the specified
      * detail message and cause.
      *
      * @param message the detail message (which is saved for later retrieval
@@ -78,7 +78,7 @@
     }
 
     /**
-     * Creates a {@code InvalidKeySpecException} with the specified cause
+     * Creates an {@code InvalidKeySpecException} with the specified cause
      * and a detail message of {@code (cause==null ? null : cause.toString())}
      * (which typically contains the class and detail message of
      * {@code cause}).
--- a/jdk/src/java.base/share/classes/java/time/Instant.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/time/Instant.java	Thu May 12 11:03:07 2016 -0700
@@ -799,33 +799,33 @@
      * The supported fields behave as follows:
      * <ul>
      * <li>{@code NANOS} -
-     *  Returns a {@code Instant} with the specified number of nanoseconds added.
+     *  Returns an {@code Instant} with the specified number of nanoseconds added.
      *  This is equivalent to {@link #plusNanos(long)}.
      * <li>{@code MICROS} -
-     *  Returns a {@code Instant} with the specified number of microseconds added.
+     *  Returns an {@code Instant} with the specified number of microseconds added.
      *  This is equivalent to {@link #plusNanos(long)} with the amount
      *  multiplied by 1,000.
      * <li>{@code MILLIS} -
-     *  Returns a {@code Instant} with the specified number of milliseconds added.
+     *  Returns an {@code Instant} with the specified number of milliseconds added.
      *  This is equivalent to {@link #plusNanos(long)} with the amount
      *  multiplied by 1,000,000.
      * <li>{@code SECONDS} -
-     *  Returns a {@code Instant} with the specified number of seconds added.
+     *  Returns an {@code Instant} with the specified number of seconds added.
      *  This is equivalent to {@link #plusSeconds(long)}.
      * <li>{@code MINUTES} -
-     *  Returns a {@code Instant} with the specified number of minutes added.
+     *  Returns an {@code Instant} with the specified number of minutes added.
      *  This is equivalent to {@link #plusSeconds(long)} with the amount
      *  multiplied by 60.
      * <li>{@code HOURS} -
-     *  Returns a {@code Instant} with the specified number of hours added.
+     *  Returns an {@code Instant} with the specified number of hours added.
      *  This is equivalent to {@link #plusSeconds(long)} with the amount
      *  multiplied by 3,600.
      * <li>{@code HALF_DAYS} -
-     *  Returns a {@code Instant} with the specified number of half-days added.
+     *  Returns an {@code Instant} with the specified number of half-days added.
      *  This is equivalent to {@link #plusSeconds(long)} with the amount
      *  multiplied by 43,200 (12 hours).
      * <li>{@code DAYS} -
-     *  Returns a {@code Instant} with the specified number of days added.
+     *  Returns an {@code Instant} with the specified number of days added.
      *  This is equivalent to {@link #plusSeconds(long)} with the amount
      *  multiplied by 86,400 (24 hours).
      * </ul>
@@ -958,7 +958,7 @@
     /**
      * Returns a copy of this instant with the specified amount subtracted.
      * <p>
-     * This returns a {@code Instant}, based on this one, with the amount
+     * This returns an {@code Instant}, based on this one, with the amount
      * in terms of the unit subtracted. If it is not possible to subtract the amount,
      * because the unit is not supported or for some other reason, an exception is thrown.
      * <p>
--- a/jdk/src/java.base/share/classes/java/time/LocalDateTime.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/time/LocalDateTime.java	Thu May 12 11:03:07 2016 -0700
@@ -665,7 +665,7 @@
      * The {@link #isSupported(TemporalField) supported fields} will return valid
      * values based on this date-time, except {@code NANO_OF_DAY}, {@code MICRO_OF_DAY},
      * {@code EPOCH_DAY} and {@code PROLEPTIC_MONTH} which are too large to fit in
-     * an {@code int} and throw a {@code UnsupportedTemporalTypeException}.
+     * an {@code int} and throw an {@code UnsupportedTemporalTypeException}.
      * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
--- a/jdk/src/java.base/share/classes/java/time/LocalTime.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/time/LocalTime.java	Thu May 12 11:03:07 2016 -0700
@@ -619,7 +619,7 @@
      * If the field is a {@link ChronoField} then the query is implemented here.
      * The {@link #isSupported(TemporalField) supported fields} will return valid
      * values based on this time, except {@code NANO_OF_DAY} and {@code MICRO_OF_DAY}
-     * which are too large to fit in an {@code int} and throw a {@code UnsupportedTemporalTypeException}.
+     * which are too large to fit in an {@code int} and throw an {@code UnsupportedTemporalTypeException}.
      * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
--- a/jdk/src/java.base/share/classes/java/time/OffsetDateTime.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/time/OffsetDateTime.java	Thu May 12 11:03:07 2016 -0700
@@ -576,7 +576,7 @@
      * The {@link #isSupported(TemporalField) supported fields} will return valid
      * values based on this date-time, except {@code NANO_OF_DAY}, {@code MICRO_OF_DAY},
      * {@code EPOCH_DAY}, {@code PROLEPTIC_MONTH} and {@code INSTANT_SECONDS} which are too
-     * large to fit in an {@code int} and throw a {@code UnsupportedTemporalTypeException}.
+     * large to fit in an {@code int} and throw an {@code UnsupportedTemporalTypeException}.
      * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
--- a/jdk/src/java.base/share/classes/java/time/OffsetTime.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/time/OffsetTime.java	Thu May 12 11:03:07 2016 -0700
@@ -481,7 +481,7 @@
      * If the field is a {@link ChronoField} then the query is implemented here.
      * The {@link #isSupported(TemporalField) supported fields} will return valid
      * values based on this time, except {@code NANO_OF_DAY} and {@code MICRO_OF_DAY}
-     * which are too large to fit in an {@code int} and throw a {@code UnsupportedTemporalTypeException}.
+     * which are too large to fit in an {@code int} and throw an {@code UnsupportedTemporalTypeException}.
      * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
--- a/jdk/src/java.base/share/classes/java/time/ZonedDateTime.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/time/ZonedDateTime.java	Thu May 12 11:03:07 2016 -0700
@@ -793,7 +793,7 @@
      * The {@link #isSupported(TemporalField) supported fields} will return valid
      * values based on this date-time, except {@code NANO_OF_DAY}, {@code MICRO_OF_DAY},
      * {@code EPOCH_DAY}, {@code PROLEPTIC_MONTH} and {@code INSTANT_SECONDS} which are too
-     * large to fit in an {@code int} and throw a {@code UnsupportedTemporalTypeException}.
+     * large to fit in an {@code int} and throw an {@code UnsupportedTemporalTypeException}.
      * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
--- a/jdk/src/java.base/share/classes/java/time/temporal/IsoFields.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/time/temporal/IsoFields.java	Thu May 12 11:03:07 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
@@ -402,6 +402,12 @@
                 long moy = temporal.getLong(MONTH_OF_YEAR);
                 return ((moy + 2) / 3);
             }
+            public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
+                if (isSupportedBy(temporal) == false) {
+                    throw new UnsupportedTemporalTypeException("Unsupported field: QuarterOfYear");
+                }
+                return super.rangeRefinedBy(temporal);
+            }
             @SuppressWarnings("unchecked")
             @Override
             public <R extends Temporal> R adjustInto(R temporal, long newValue) {
@@ -529,6 +535,12 @@
                 }
                 return getWeekBasedYear(LocalDate.from(temporal));
             }
+            public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
+                if (isSupportedBy(temporal) == false) {
+                    throw new UnsupportedTemporalTypeException("Unsupported field: WeekBasedYear");
+                }
+                return super.rangeRefinedBy(temporal);
+            }
             @SuppressWarnings("unchecked")
             @Override
             public <R extends Temporal> R adjustInto(R temporal, long newValue) {
--- a/jdk/src/java.base/share/classes/java/util/Comparator.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/util/Comparator.java	Thu May 12 11:03:07 2016 -0700
@@ -267,7 +267,7 @@
 
     /**
      * Returns a lexicographic-order comparator with a function that
-     * extracts a {@code int} sort key.
+     * extracts an {@code int} sort key.
      *
      * @implSpec This default implementation behaves as if {@code
      *           thenComparing(comparingInt(keyExtractor))}.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/util/regex/CharPredicates.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,375 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.util.regex;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.regex.Pattern.CharPredicate;
+import java.util.regex.Pattern.BmpCharPredicate;
+
+class CharPredicates {
+
+    static final CharPredicate ALPHABETIC  = Character::isAlphabetic;
+
+    // \p{gc=Decimal_Number}
+    static final CharPredicate DIGIT       = Character::isDigit;
+
+    static final CharPredicate LETTER      = Character::isLetter;
+
+    static final CharPredicate IDEOGRAPHIC = Character::isIdeographic;
+
+    static final CharPredicate LOWERCASE   = Character::isLowerCase;
+
+    static final CharPredicate UPPERCASE   = Character::isUpperCase;
+
+    static final CharPredicate TITLECASE   = Character::isTitleCase;
+
+    // \p{Whitespace}
+    static final CharPredicate WHITE_SPACE = ch ->
+        ((((1 << Character.SPACE_SEPARATOR) |
+           (1 << Character.LINE_SEPARATOR) |
+           (1 << Character.PARAGRAPH_SEPARATOR)) >> Character.getType(ch)) & 1)
+        != 0 || (ch >= 0x9 && ch <= 0xd) || (ch == 0x85);
+
+    // \p{gc=Control}
+    static final CharPredicate CONTROL     = ch ->
+        Character.getType(ch) == Character.CONTROL;
+
+    // \p{gc=Punctuation}
+    static final CharPredicate PUNCTUATION = ch ->
+        ((((1 << Character.CONNECTOR_PUNCTUATION) |
+           (1 << Character.DASH_PUNCTUATION) |
+           (1 << Character.START_PUNCTUATION) |
+           (1 << Character.END_PUNCTUATION) |
+           (1 << Character.OTHER_PUNCTUATION) |
+           (1 << Character.INITIAL_QUOTE_PUNCTUATION) |
+           (1 << Character.FINAL_QUOTE_PUNCTUATION)) >> Character.getType(ch)) & 1)
+        != 0;
+
+    // \p{gc=Decimal_Number}
+    // \p{Hex_Digit}    -> PropList.txt: Hex_Digit
+    static final CharPredicate HEX_DIGIT = DIGIT.union(
+        ch -> (ch >= 0x0030 && ch <= 0x0039) ||
+              (ch >= 0x0041 && ch <= 0x0046) ||
+              (ch >= 0x0061 && ch <= 0x0066) ||
+              (ch >= 0xFF10 && ch <= 0xFF19) ||
+              (ch >= 0xFF21 && ch <= 0xFF26) ||
+              (ch >= 0xFF41 && ch <= 0xFF46));
+
+    static final CharPredicate ASSIGNED = ch ->
+        Character.getType(ch) != Character.UNASSIGNED;
+
+    // PropList.txt:Noncharacter_Code_Point
+    static final CharPredicate NONCHARACTER_CODE_POINT = ch ->
+        (ch & 0xfffe) == 0xfffe || (ch >= 0xfdd0 && ch <= 0xfdef);
+
+    // \p{alpha}
+    // \p{digit}
+    static final CharPredicate ALNUM = ALPHABETIC.union(DIGIT);
+
+    // \p{Whitespace} --
+    // [\N{LF} \N{VT} \N{FF} \N{CR} \N{NEL}  -> 0xa, 0xb, 0xc, 0xd, 0x85
+    //  \p{gc=Line_Separator}
+    //  \p{gc=Paragraph_Separator}]
+    static final CharPredicate BLANK = ch ->
+        Character.getType(ch) == Character.SPACE_SEPARATOR ||
+        ch == 0x9; // \N{HT}
+
+    // [^
+    //  \p{space}
+    //  \p{gc=Control}
+    //  \p{gc=Surrogate}
+    //  \p{gc=Unassigned}]
+    static final CharPredicate GRAPH = ch ->
+        ((((1 << Character.SPACE_SEPARATOR) |
+           (1 << Character.LINE_SEPARATOR) |
+           (1 << Character.PARAGRAPH_SEPARATOR) |
+           (1 << Character.CONTROL) |
+           (1 << Character.SURROGATE) |
+           (1 << Character.UNASSIGNED)) >> Character.getType(ch)) & 1)
+        == 0;
+
+    // \p{graph}
+    // \p{blank}
+    // -- \p{cntrl}
+    static final CharPredicate PRINT = GRAPH.union(BLANK).and(CONTROL.negate());
+
+    //  200C..200D    PropList.txt:Join_Control
+    static final CharPredicate JOIN_CONTROL = ch -> ch == 0x200C || ch == 0x200D;
+
+    //  \p{alpha}
+    //  \p{gc=Mark}
+    //  \p{digit}
+    //  \p{gc=Connector_Punctuation}
+    //  \p{Join_Control}    200C..200D
+    static final CharPredicate WORD =
+        ALPHABETIC.union(ch -> ((((1 << Character.NON_SPACING_MARK) |
+                                  (1 << Character.ENCLOSING_MARK) |
+                                  (1 << Character.COMBINING_SPACING_MARK) |
+                                  (1 << Character.DECIMAL_DIGIT_NUMBER) |
+                                  (1 << Character.CONNECTOR_PUNCTUATION))
+                                 >> Character.getType(ch)) & 1) != 0,
+                         JOIN_CONTROL);
+
+    /////////////////////////////////////////////////////////////////////////////
+
+    private static final HashMap<String, CharPredicate> posix = new HashMap<>(12);
+    private static final HashMap<String, CharPredicate> uprops = new HashMap<>(18);
+
+    private static void defPosix(String name, CharPredicate p) {
+        posix.put(name, p);
+    }
+    private static void defUProp(String name, CharPredicate p) {
+        uprops.put(name, p);
+    }
+
+    static {
+        defPosix("ALPHA", ALPHABETIC);
+        defPosix("LOWER", LOWERCASE);
+        defPosix("UPPER", UPPERCASE);
+        defPosix("SPACE", WHITE_SPACE);
+        defPosix("PUNCT", PUNCTUATION);
+        defPosix("XDIGIT",HEX_DIGIT);
+        defPosix("ALNUM", ALNUM);
+        defPosix("CNTRL", CONTROL);
+        defPosix("DIGIT", DIGIT);
+        defPosix("BLANK", BLANK);
+        defPosix("GRAPH", GRAPH);
+        defPosix("PRINT", PRINT);
+
+        defUProp("ALPHABETIC", ALPHABETIC);
+        defUProp("ASSIGNED", ASSIGNED);
+        defUProp("CONTROL", CONTROL);
+        defUProp("HEXDIGIT", HEX_DIGIT);
+        defUProp("IDEOGRAPHIC", IDEOGRAPHIC);
+        defUProp("JOINCONTROL", JOIN_CONTROL);
+        defUProp("LETTER", LETTER);
+        defUProp("LOWERCASE", LOWERCASE);
+        defUProp("NONCHARACTERCODEPOINT", NONCHARACTER_CODE_POINT);
+        defUProp("TITLECASE", TITLECASE);
+        defUProp("PUNCTUATION", PUNCTUATION);
+        defUProp("UPPERCASE", UPPERCASE);
+        defUProp("WHITESPACE", WHITE_SPACE);
+        defUProp("WORD", WORD);
+        defUProp("WHITE_SPACE", WHITE_SPACE);
+        defUProp("HEX_DIGIT", HEX_DIGIT);
+        defUProp("NONCHARACTER_CODE_POINT", NONCHARACTER_CODE_POINT);
+        defUProp("JOIN_CONTROL", JOIN_CONTROL);
+    }
+
+    public static CharPredicate forUnicodeProperty(String propName) {
+        propName = propName.toUpperCase(Locale.ROOT);
+        CharPredicate p = uprops.get(propName);
+        if (p != null)
+            return p;
+        return posix.get(propName);
+    }
+
+    public static CharPredicate forPOSIXName(String propName) {
+        return posix.get(propName.toUpperCase(Locale.ENGLISH));
+    }
+
+    /////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Returns a predicate matching all characters belong to a named
+     * UnicodeScript.
+     */
+    static CharPredicate forUnicodeScript(String name) {
+        final Character.UnicodeScript script;
+        try {
+            script = Character.UnicodeScript.forName(name);
+            return ch -> script == Character.UnicodeScript.of(ch);
+        } catch (IllegalArgumentException iae) {}
+        return null;
+    }
+
+    /**
+     * Returns a predicate matching all characters in a UnicodeBlock.
+     */
+    static CharPredicate forUnicodeBlock(String name) {
+        final Character.UnicodeBlock block;
+        try {
+            block = Character.UnicodeBlock.forName(name);
+            return ch -> block == Character.UnicodeBlock.of(ch);
+        } catch (IllegalArgumentException iae) {}
+         return null;
+    }
+
+    /////////////////////////////////////////////////////////////////////////////
+
+    // unicode categories, aliases, properties, java methods ...
+
+    private static final HashMap<String, CharPredicate> props = new HashMap<>(128);
+
+    /**
+     * Returns a predicate matching all characters in a named property.
+     */
+    static CharPredicate forProperty(String name) {
+        return props.get(name);
+    }
+
+    private static void defProp(String name, CharPredicate p) {
+        props.put(name, p);
+    }
+
+    private static void defCategory(String name, final int typeMask) {
+        CharPredicate p = ch -> (typeMask & (1 << Character.getType(ch))) != 0;
+        props.put(name, p);
+    }
+
+    private static void defRange(String name, final int lower, final int upper) {
+        BmpCharPredicate p = ch -> lower <= ch && ch <= upper;
+        props.put(name, p);
+    }
+
+    private static void defCtype(String name, final int ctype) {
+        BmpCharPredicate p = ch -> ch < 128 && ASCII.isType(ch, ctype);
+        // PrintPattern.pmap.put(p, name);
+        props.put(name, p);
+    }
+
+    static {
+        // Unicode character property aliases, defined in
+        // http://www.unicode.org/Public/UNIDATA/PropertyValueAliases.txt
+        defCategory("Cn", 1<<Character.UNASSIGNED);
+        defCategory("Lu", 1<<Character.UPPERCASE_LETTER);
+        defCategory("Ll", 1<<Character.LOWERCASE_LETTER);
+        defCategory("Lt", 1<<Character.TITLECASE_LETTER);
+        defCategory("Lm", 1<<Character.MODIFIER_LETTER);
+        defCategory("Lo", 1<<Character.OTHER_LETTER);
+        defCategory("Mn", 1<<Character.NON_SPACING_MARK);
+        defCategory("Me", 1<<Character.ENCLOSING_MARK);
+        defCategory("Mc", 1<<Character.COMBINING_SPACING_MARK);
+        defCategory("Nd", 1<<Character.DECIMAL_DIGIT_NUMBER);
+        defCategory("Nl", 1<<Character.LETTER_NUMBER);
+        defCategory("No", 1<<Character.OTHER_NUMBER);
+        defCategory("Zs", 1<<Character.SPACE_SEPARATOR);
+        defCategory("Zl", 1<<Character.LINE_SEPARATOR);
+        defCategory("Zp", 1<<Character.PARAGRAPH_SEPARATOR);
+        defCategory("Cc", 1<<Character.CONTROL);
+        defCategory("Cf", 1<<Character.FORMAT);
+        defCategory("Co", 1<<Character.PRIVATE_USE);
+        defCategory("Cs", 1<<Character.SURROGATE);
+        defCategory("Pd", 1<<Character.DASH_PUNCTUATION);
+        defCategory("Ps", 1<<Character.START_PUNCTUATION);
+        defCategory("Pe", 1<<Character.END_PUNCTUATION);
+        defCategory("Pc", 1<<Character.CONNECTOR_PUNCTUATION);
+        defCategory("Po", 1<<Character.OTHER_PUNCTUATION);
+        defCategory("Sm", 1<<Character.MATH_SYMBOL);
+        defCategory("Sc", 1<<Character.CURRENCY_SYMBOL);
+        defCategory("Sk", 1<<Character.MODIFIER_SYMBOL);
+        defCategory("So", 1<<Character.OTHER_SYMBOL);
+        defCategory("Pi", 1<<Character.INITIAL_QUOTE_PUNCTUATION);
+        defCategory("Pf", 1<<Character.FINAL_QUOTE_PUNCTUATION);
+        defCategory("L", ((1<<Character.UPPERCASE_LETTER) |
+                          (1<<Character.LOWERCASE_LETTER) |
+                          (1<<Character.TITLECASE_LETTER) |
+                          (1<<Character.MODIFIER_LETTER)  |
+                          (1<<Character.OTHER_LETTER)));
+        defCategory("M", ((1<<Character.NON_SPACING_MARK) |
+                          (1<<Character.ENCLOSING_MARK)   |
+                          (1<<Character.COMBINING_SPACING_MARK)));
+        defCategory("N", ((1<<Character.DECIMAL_DIGIT_NUMBER) |
+                          (1<<Character.LETTER_NUMBER)        |
+                          (1<<Character.OTHER_NUMBER)));
+        defCategory("Z", ((1<<Character.SPACE_SEPARATOR) |
+                          (1<<Character.LINE_SEPARATOR)  |
+                          (1<<Character.PARAGRAPH_SEPARATOR)));
+        defCategory("C", ((1<<Character.CONTROL)     |
+                          (1<<Character.FORMAT)      |
+                          (1<<Character.PRIVATE_USE) |
+                          (1<<Character.SURROGATE))); // Other
+        defCategory("P", ((1<<Character.DASH_PUNCTUATION)      |
+                          (1<<Character.START_PUNCTUATION)     |
+                          (1<<Character.END_PUNCTUATION)       |
+                          (1<<Character.CONNECTOR_PUNCTUATION) |
+                          (1<<Character.OTHER_PUNCTUATION)     |
+                          (1<<Character.INITIAL_QUOTE_PUNCTUATION) |
+                          (1<<Character.FINAL_QUOTE_PUNCTUATION)));
+        defCategory("S", ((1<<Character.MATH_SYMBOL)     |
+                          (1<<Character.CURRENCY_SYMBOL) |
+                          (1<<Character.MODIFIER_SYMBOL) |
+                          (1<<Character.OTHER_SYMBOL)));
+        defCategory("LC", ((1<<Character.UPPERCASE_LETTER) |
+                           (1<<Character.LOWERCASE_LETTER) |
+                           (1<<Character.TITLECASE_LETTER)));
+        defCategory("LD", ((1<<Character.UPPERCASE_LETTER) |
+                           (1<<Character.LOWERCASE_LETTER) |
+                           (1<<Character.TITLECASE_LETTER) |
+                           (1<<Character.MODIFIER_LETTER)  |
+                           (1<<Character.OTHER_LETTER)     |
+                           (1<<Character.DECIMAL_DIGIT_NUMBER)));
+        defRange("L1", 0x00, 0xFF); // Latin-1
+        props.put("all", ch -> true);
+
+        // Posix regular expression character classes, defined in
+        // http://www.unix.org/onlinepubs/009695399/basedefs/xbd_chap09.html
+        defRange("ASCII", 0x00, 0x7F);   // ASCII
+        defCtype("Alnum", ASCII.ALNUM);  // Alphanumeric characters
+        defCtype("Alpha", ASCII.ALPHA);  // Alphabetic characters
+        defCtype("Blank", ASCII.BLANK);  // Space and tab characters
+        defCtype("Cntrl", ASCII.CNTRL);  // Control characters
+        defRange("Digit", '0', '9');     // Numeric characters
+        defCtype("Graph", ASCII.GRAPH);  // printable and visible
+        defRange("Lower", 'a', 'z');     // Lower-case alphabetic
+        defRange("Print", 0x20, 0x7E);   // Printable characters
+        defCtype("Punct", ASCII.PUNCT);  // Punctuation characters
+        defCtype("Space", ASCII.SPACE);  // Space characters
+        defRange("Upper", 'A', 'Z');     // Upper-case alphabetic
+        defCtype("XDigit",ASCII.XDIGIT); // hexadecimal digits
+
+        // Java character properties, defined by methods in Character.java
+        defProp("javaLowerCase", java.lang.Character::isLowerCase);
+        defProp("javaUpperCase",  Character::isUpperCase);
+        defProp("javaAlphabetic", java.lang.Character::isAlphabetic);
+        defProp("javaIdeographic", java.lang.Character::isIdeographic);
+        defProp("javaTitleCase", java.lang.Character::isTitleCase);
+        defProp("javaDigit", java.lang.Character::isDigit);
+        defProp("javaDefined", java.lang.Character::isDefined);
+        defProp("javaLetter", java.lang.Character::isLetter);
+        defProp("javaLetterOrDigit", java.lang.Character::isLetterOrDigit);
+        defProp("javaJavaIdentifierStart", java.lang.Character::isJavaIdentifierStart);
+        defProp("javaJavaIdentifierPart", java.lang.Character::isJavaIdentifierPart);
+        defProp("javaUnicodeIdentifierStart", java.lang.Character::isUnicodeIdentifierStart);
+        defProp("javaUnicodeIdentifierPart", java.lang.Character::isUnicodeIdentifierPart);
+        defProp("javaIdentifierIgnorable", java.lang.Character::isIdentifierIgnorable);
+        defProp("javaSpaceChar", java.lang.Character::isSpaceChar);
+        defProp("javaWhitespace", java.lang.Character::isWhitespace);
+        defProp("javaISOControl", java.lang.Character::isISOControl);
+        defProp("javaMirrored", java.lang.Character::isMirrored);
+    }
+
+    /////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Posix ASCII variants, not in the lookup map
+     */
+    static final BmpCharPredicate ASCII_DIGIT = ch -> ch < 128 && ASCII.isDigit(ch);
+    static final BmpCharPredicate ASCII_WORD  = ch -> ch < 128 && ASCII.isWord(ch);
+    static final BmpCharPredicate ASCII_SPACE = ch -> ch < 128 && ASCII.isSpace(ch);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/util/regex/IntHashSet.java	Thu May 12 11:03:07 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 java.util.regex;
+
+import java.util.Arrays;
+
+/**
+ * A lightweight hashset implementation for positive 'int'. Not safe for
+ * concurrent access.
+ */
+class IntHashSet {
+    private int[] entries;
+    private int[] hashes;
+    private int pos = 0;
+
+    public IntHashSet() {
+        this.entries = new int[16 << 1];      // initCapacity = 16;
+        this.hashes = new int[(16 / 2) | 1];  // odd -> fewer collisions
+        Arrays.fill(this.entries, -1);
+        Arrays.fill(this.hashes, -1);
+    }
+
+    public boolean contains(int i) {
+        int h = hashes[i % hashes.length];
+        while (h != -1) {
+            if (entries[h] == i)
+                return true;
+            h = entries[h + 1];
+        }
+        return false;
+    }
+
+    public void add(int i) {
+        int h0 = i % hashes.length;
+        int next = hashes[h0];
+        //  if invoker guarantees contains(i) checked before add(i)
+        //  the following check is not needed.
+        int next0 = next;
+        while (next0 != -1) {
+            if (entries[next0 ] == i)
+                return;
+            next0 = entries[next0 + 1];
+        }
+        hashes[h0] = pos;
+        entries[pos++] = i;
+        entries[pos++] = next;
+        if (pos == entries.length)
+            expand();
+    }
+
+    public void clear() {
+        Arrays.fill(this.entries, -1);
+        Arrays.fill(this.hashes, -1);
+        pos = 0;
+    }
+
+    private void expand() {
+        int[] old = entries;
+        int[] es = new int[old.length << 1];
+        int hlen = (old.length / 2) | 1;
+        int[] hs = new int[hlen];
+        Arrays.fill(es, -1);
+        Arrays.fill(hs, -1);
+        for (int n = 0; n < pos;) {  // re-hashing
+            int i = old[n];
+            int hsh = i % hlen;
+            int next = hs[hsh];
+            hs[hsh] = n;
+            es[n++] = i;
+            es[n++] = next;
+        }
+        this.entries = es;
+        this.hashes = hs;
+    }
+}
--- a/jdk/src/java.base/share/classes/java/util/regex/Matcher.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/util/regex/Matcher.java	Thu May 12 11:03:07 2016 -0700
@@ -178,6 +178,14 @@
     int[] locals;
 
     /**
+     * Storage used by top greedy Loop node to store a specific hash set to
+     * keep the beginning index of the failed repetition match. The nodes
+     * themselves are stateless, so they rely on this field to hold state
+     * during a match.
+     */
+    IntHashSet[] localsPos;
+
+    /**
      * Boolean indicating whether or not more input could change
      * the results of the last match.
      *
@@ -239,6 +247,7 @@
         int parentGroupCount = Math.max(parent.capturingGroupCount, 10);
         groups = new int[parentGroupCount * 2];
         locals = new int[parent.localCount];
+        localsPos = new IntHashSet[parent.localTCNCount];
 
         // Put fields into initial states
         reset();
@@ -375,6 +384,7 @@
             groups[i] = -1;
         for (int i = 0; i < locals.length; i++)
             locals[i] = -1;
+        localsPos = new IntHashSet[parentPattern.localTCNCount];
         modCount++;
         return this;
     }
@@ -397,6 +407,10 @@
             groups[i] = -1;
         for(int i=0; i<locals.length; i++)
             locals[i] = -1;
+        for (int i = 0; i < localsPos.length; i++) {
+            if (localsPos[i] != null)
+                localsPos[i].clear();
+        }
         lastAppendPosition = 0;
         from = 0;
         to = getTextLength();
@@ -1706,6 +1720,10 @@
         this.oldLast = oldLast < 0 ? from : oldLast;
         for (int i = 0; i < groups.length; i++)
             groups[i] = -1;
+        for (int i = 0; i < localsPos.length; i++) {
+            if (localsPos[i] != null)
+                localsPos[i].clear();
+        }
         acceptMode = NOANCHOR;
         boolean result = parentPattern.root.match(this, from, text);
         if (!result)
@@ -1729,6 +1747,10 @@
         this.oldLast = oldLast < 0 ? from : oldLast;
         for (int i = 0; i < groups.length; i++)
             groups[i] = -1;
+        for (int i = 0; i < localsPos.length; i++) {
+            if (localsPos[i] != null)
+                localsPos[i].clear();
+        }
         acceptMode = anchor;
         boolean result = parentPattern.matchRoot.match(this, from, text);
         if (!result)
--- a/jdk/src/java.base/share/classes/java/util/regex/Pattern.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/java/util/regex/Pattern.java	Thu May 12 11:03:07 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,11 +26,15 @@
 package java.util.regex;
 
 import java.text.Normalizer;
+import java.text.Normalizer.Form;
 import java.util.Locale;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
 import java.util.Arrays;
 import java.util.NoSuchElementException;
 import java.util.Spliterator;
@@ -469,7 +473,7 @@
  *
  *   <li> A line-separator character&nbsp;(<code>'&#92;u2028'</code>), or
  *
- *   <li> A paragraph-separator character&nbsp;(<code>'&#92;u2029</code>).
+ *   <li> A paragraph-separator character&nbsp;(<code>'&#92;u2029'</code>).
  *
  * </ul>
  * <p>If {@link #UNIX_LINES} mode is activated, then the only line terminators
@@ -984,6 +988,11 @@
     transient int[] buffer;
 
     /**
+     * A temporary storage used for predicate for double return.
+     */
+    transient CharPredicate predicate;
+
+    /**
      * Map the "name" of the "named capturing group" to its group id
      * node.
      */
@@ -995,6 +1004,24 @@
     transient GroupHead[] groupNodes;
 
     /**
+     * Temporary storage used to store the top level closure nodes.
+     */
+    transient List<Node> topClosureNodes;
+
+    /**
+     * The number of top greedy closure nodes in this Pattern. Used by
+     * matchers to allocate storage needed for a IntHashSet to keep the
+     * beginning pos {@code i} of all failed match.
+     */
+    transient int localTCNCount;
+
+    /*
+     * Turn off the stop-exponential-backtracking optimization if there
+     * is a group ref in the pattern.
+     */
+    transient boolean hasGroupRef;
+
+    /**
      * Temporary null terminated code point array used by pattern compiling.
      */
     private transient int[] temp;
@@ -1026,7 +1053,7 @@
      * If the Start node might possibly match supplementary characters.
      * It is set to true during compiling if
      * (1) There is supplementary char in pattern, or
-     * (2) There is complement node of Category or Block
+     * (2) There is complement node of a "family" CharProperty
      */
     private transient boolean hasSupplementary;
 
@@ -1338,6 +1365,7 @@
         // Initialize counts
         capturingGroupCount = 1;
         localCount = 0;
+        localTCNCount = 0;
 
         // if length > 0, the Pattern is lazily compiled
         if (pattern.length() == 0) {
@@ -1368,6 +1396,7 @@
         // Reset group index count
         capturingGroupCount = 1;
         localCount = 0;
+        localTCNCount = 0;
 
         if (pattern.length() > 0) {
             compile();
@@ -1378,105 +1407,114 @@
     }
 
     /**
-     * The pattern is converted to normalized form ({@linkplain
-     * java.text.Normalizer.Form.NFD NFD}, canonical decomposition)
-     * and then a pure group is constructed to match canonical
-     * equivalences of the characters.
-     */
-    private void normalize() {
-        int lastCodePoint = -1;
-
-        // Convert pattern into normalized form
-        normalizedPattern = Normalizer.normalize(pattern, Normalizer.Form.NFD);
-        patternLength = normalizedPattern.length();
-
-        // Modify pattern to match canonical equivalences
-        StringBuilder newPattern = new StringBuilder(patternLength);
-        for(int i=0; i<patternLength; ) {
-            int c = normalizedPattern.codePointAt(i);
-            StringBuilder sequenceBuffer;
-            if ((Character.getType(c) == Character.NON_SPACING_MARK)
-                && (lastCodePoint != -1)) {
-                sequenceBuffer = new StringBuilder();
-                sequenceBuffer.appendCodePoint(lastCodePoint);
-                sequenceBuffer.appendCodePoint(c);
-                while(Character.getType(c) == Character.NON_SPACING_MARK) {
-                    i += Character.charCount(c);
-                    if (i >= patternLength)
-                        break;
-                    c = normalizedPattern.codePointAt(i);
-                    sequenceBuffer.appendCodePoint(c);
-                }
-                String ea = produceEquivalentAlternation(
-                                               sequenceBuffer.toString());
-                newPattern.setLength(newPattern.length()-Character.charCount(lastCodePoint));
-                newPattern.append("(?:").append(ea).append(")");
-            } else if (c == '[' && lastCodePoint != '\\') {
-                i = normalizeCharClass(newPattern, i);
-            } else {
-                newPattern.appendCodePoint(c);
-            }
-            lastCodePoint = c;
-            i += Character.charCount(c);
-        }
-        normalizedPattern = newPattern.toString();
-    }
-
-    /**
-     * Complete the character class being parsed and add a set
-     * of alternations to it that will match the canonical equivalences
-     * of the characters within the class.
+     * The pattern is converted to normalized form ({@link
+     * java.text.Normalizer.Form.NFC NFC}, canonical decomposition,
+     * followed by canonical composition for the character class
+     * part, and {@link java.text.Normalizer.Form.NFD NFD},
+     * canonical decomposition) for the rest), and then a pure
+     * group is constructed to match canonical equivalences of the
+     * characters.
      */
-    private int normalizeCharClass(StringBuilder newPattern, int i) {
-        StringBuilder charClass = new StringBuilder();
-        StringBuilder eq = null;
-        int lastCodePoint = -1;
-        String result;
-
-        i++;
-        charClass.append("[");
-        while(true) {
-            int c = normalizedPattern.codePointAt(i);
-            StringBuilder sequenceBuffer;
-
-            if (c == ']' && lastCodePoint != '\\') {
-                charClass.append((char)c);
-                break;
-            } else if (Character.getType(c) == Character.NON_SPACING_MARK) {
-                sequenceBuffer = new StringBuilder();
-                sequenceBuffer.appendCodePoint(lastCodePoint);
-                while(Character.getType(c) == Character.NON_SPACING_MARK) {
-                    sequenceBuffer.appendCodePoint(c);
-                    i += Character.charCount(c);
-                    if (i >= normalizedPattern.length())
-                        break;
-                    c = normalizedPattern.codePointAt(i);
+    private static String normalize(String pattern) {
+        int plen = pattern.length();
+        StringBuilder pbuf = new StringBuilder(plen);
+        char last = 0;
+        int lastStart = 0;
+        char cc = 0;
+        for (int i = 0; i < plen;) {
+            char c = pattern.charAt(i);
+            if (cc == 0 &&    // top level
+                c == '\\' && i + 1 < plen && pattern.charAt(i + 1) == '\\') {
+                i += 2; last = 0;
+                continue;
+            }
+            if (c == '[' && last != '\\') {
+                if (cc == 0) {
+                    if (lastStart < i)
+                        normalizeSlice(pattern, lastStart, i, pbuf);
+                    lastStart = i;
+                }
+                cc++;
+            } else if (c == ']' && last != '\\') {
+                cc--;
+                if (cc == 0) {
+                    normalizeClazz(pattern, lastStart, i + 1, pbuf);
+                    lastStart = i + 1;
                 }
-                String ea = produceEquivalentAlternation(
-                                                  sequenceBuffer.toString());
-
-                charClass.setLength(charClass.length()-Character.charCount(lastCodePoint));
-                if (eq == null)
-                    eq = new StringBuilder();
-                eq.append('|');
-                eq.append(ea);
-            } else {
-                charClass.appendCodePoint(c);
-                i++;
+            }
+            last = c;
+            i++;
+        }
+        assert (cc == 0);
+        if (lastStart < plen)
+            normalizeSlice(pattern, lastStart, plen, pbuf);
+        return pbuf.toString();
+    }
+
+    private static void normalizeSlice(String src, int off, int limit,
+                                       StringBuilder dst)
+    {
+        int len = src.length();
+        int off0 = off;
+        while (off < limit && ASCII.isAscii(src.charAt(off))) {
+            off++;
+        }
+        if (off == limit) {
+            dst.append(src, off0, limit);
+            return;
+        }
+        off--;
+        if (off < off0)
+            off = off0;
+        else
+            dst.append(src, off0, off);
+        while (off < limit) {
+            int ch0 = src.codePointAt(off);
+            if (".$|()[]{}^?*+\\".indexOf(ch0) != -1) {
+                dst.append((char)ch0);
+                off++;
+                continue;
             }
-            if (i == normalizedPattern.length())
-                throw error("Unclosed character class");
-            lastCodePoint = c;
-        }
-
-        if (eq != null) {
-            result = "(?:"+charClass.toString()+eq.toString()+")";
-        } else {
-            result = charClass.toString();
-        }
-
-        newPattern.append(result);
-        return i;
+            int j = off + Character.charCount(ch0);
+            int ch1;
+            while (j < limit) {
+                ch1 = src.codePointAt(j);
+                if (Grapheme.isBoundary(ch0, ch1))
+                    break;
+                ch0 = ch1;
+                j += Character.charCount(ch1);
+            }
+            String seq = src.substring(off, j);
+            String nfd = Normalizer.normalize(seq, Normalizer.Form.NFD);
+            off = j;
+            if (nfd.length() > 1) {
+                ch0 = nfd.codePointAt(0);
+                ch1 = nfd.codePointAt(Character.charCount(ch0));
+                if (Character.getType(ch1) == Character.NON_SPACING_MARK) {
+                    Set<String> altns = new LinkedHashSet<>();
+                    altns.add(seq);
+                    produceEquivalentAlternation(nfd, altns);
+                    dst.append("(?:");
+                    altns.forEach( s -> dst.append(s + "|"));
+                    dst.delete(dst.length() - 1, dst.length());
+                    dst.append(")");
+                    continue;
+                }
+            }
+            String nfc = Normalizer.normalize(seq, Normalizer.Form.NFC);
+            if (!seq.equals(nfc) && !nfd.equals(nfc))
+                dst.append("(?:" + seq + "|" + nfd  + "|" + nfc + ")");
+            else if (!seq.equals(nfd))
+                dst.append("(?:" + seq + "|" + nfd + ")");
+            else
+                dst.append(seq);
+        }
+    }
+
+    private static void normalizeClazz(String src, int off, int limit,
+                                       StringBuilder dst)
+    {
+        dst.append(Normalizer.normalize(src.substring(off, limit), Form.NFC));
     }
 
     /**
@@ -1484,28 +1522,26 @@
      * combining marks that follow it, produce the alternation that will
      * match all canonical equivalences of that sequence.
      */
-    private String produceEquivalentAlternation(String source) {
-        int len = countChars(source, 0, 1);
-        if (source.length() == len)
-            // source has one character.
-            return source;
-
-        String base = source.substring(0,len);
-        String combiningMarks = source.substring(len);
-
+    private static void produceEquivalentAlternation(String src,
+                                                     Set<String> dst)
+    {
+        int len = countChars(src, 0, 1);
+        if (src.length() == len) {
+            dst.add(src);  // source has one character.
+            return;
+        }
+        String base = src.substring(0,len);
+        String combiningMarks = src.substring(len);
         String[] perms = producePermutations(combiningMarks);
-        StringBuilder result = new StringBuilder(source);
-
         // Add combined permutations
-        for(int x=0; x<perms.length; x++) {
+        for(int x = 0; x < perms.length; x++) {
             String next = base + perms[x];
-            if (x>0)
-                result.append("|"+next);
+            dst.add(next);
             next = composeOneStep(next);
-            if (next != null)
-                result.append("|"+produceEquivalentAlternation(next));
-        }
-        return result.toString();
+            if (next != null) {
+                produceEquivalentAlternation(next, dst);
+            }
+        }
     }
 
     /**
@@ -1517,7 +1553,7 @@
      * possibilities must be removed because they are not canonically
      * equivalent.
      */
-    private String[] producePermutations(String input) {
+    private static String[] producePermutations(String input) {
         if (input.length() == countChars(input, 0, 1))
             return new String[] {input};
 
@@ -1575,7 +1611,7 @@
         return result;
     }
 
-    private int getClass(int c) {
+    private static int getClass(int c) {
         return sun.text.Normalizer.getCombiningClass(c);
     }
 
@@ -1586,11 +1622,10 @@
      * combining mark followed by the remaining combining marks. Returns
      * null if the first two characters cannot be further composed.
      */
-    private String composeOneStep(String input) {
+    private static String composeOneStep(String input) {
         int len = countChars(input, 0, 2);
         String firstTwoCharacters = input.substring(0, len);
         String result = Normalizer.normalize(firstTwoCharacters, Normalizer.Form.NFC);
-
         if (result.equals(firstTwoCharacters))
             return null;
         else {
@@ -1677,7 +1712,7 @@
     private void compile() {
         // Handle canonical equivalences
         if (has(CANON_EQ) && !has(LITERAL)) {
-            normalize();
+            normalizedPattern = normalize(pattern);
         } else {
             normalizedPattern = pattern;
         }
@@ -1707,6 +1742,7 @@
         buffer = new int[32];
         groupNodes = new GroupHead[10];
         namedGroups = null;
+        topClosureNodes = new ArrayList<>(10);
 
         if (has(LITERAL)) {
             // Literal pattern handling
@@ -1737,12 +1773,26 @@
             root = hasSupplementary ? new StartS(matchRoot) : new Start(matchRoot);
         }
 
+        // Optimize the greedy Loop to prevent exponential backtracking, IF there
+        // is no group ref in this pattern. With a non-negative localTCNCount value,
+        // the greedy type Loop, Curly will skip the backtracking for any starting
+        // position "i" that failed in the past.
+        if (!hasGroupRef) {
+            for (Node node : topClosureNodes) {
+                if (node instanceof Loop) {
+                    // non-deterministic-greedy-group
+                    ((Loop)node).posIndex = localTCNCount++;
+                }
+            }
+        }
+
         // Release temporary storage
         temp = null;
         buffer = null;
         groupNodes = null;
         patternLength = 0;
         compiled = true;
+        topClosureNodes = null;
     }
 
     Map<String, Integer> namedGroups() {
@@ -1754,44 +1804,6 @@
     }
 
     /**
-     * Used to print out a subtree of the Pattern to help with debugging.
-     */
-    private static void printObjectTree(Node node) {
-        while(node != null) {
-            if (node instanceof Prolog) {
-                System.out.println(node);
-                printObjectTree(((Prolog)node).loop);
-                System.out.println("**** end contents prolog loop");
-            } else if (node instanceof Loop) {
-                System.out.println(node);
-                printObjectTree(((Loop)node).body);
-                System.out.println("**** end contents Loop body");
-            } else if (node instanceof Curly) {
-                System.out.println(node);
-                printObjectTree(((Curly)node).atom);
-                System.out.println("**** end contents Curly body");
-            } else if (node instanceof GroupCurly) {
-                System.out.println(node);
-                printObjectTree(((GroupCurly)node).atom);
-                System.out.println("**** end contents GroupCurly body");
-            } else if (node instanceof GroupTail) {
-                System.out.println(node);
-                System.out.println("Tail next is "+node.next);
-                return;
-            } else {
-                System.out.println(node);
-            }
-            node = node.next;
-            if (node != null)
-                System.out.println("->next:");
-            if (node == Pattern.accept) {
-                System.out.println("Accept Node");
-                node = null;
-            }
-       }
-    }
-
-    /**
      * Used to accumulate information about a subtree of the object graph
      * so that optimizations can be applied to the subtree.
      */
@@ -2083,7 +2095,10 @@
                 tail = root;
                 continue;
             case '[':
-                node = clazz(true);
+                if (has(CANON_EQ) && !has(LITERAL))
+                    node = new NFCCharProperty(clazz(true));
+                else
+                    node = newCharProperty(clazz(true));
                 break;
             case '\\':
                 ch = nextEscaped();
@@ -2096,7 +2111,11 @@
                     } else {
                         oneLetter = false;
                     }
-                    node = family(oneLetter, comp);
+                    // node = newCharProperty(family(oneLetter, comp));
+                    if (has(CANON_EQ) && !has(LITERAL))
+                        node = new NFCCharProperty(family(oneLetter, comp));
+                    else
+                        node = newCharProperty(family(oneLetter, comp));
                 } else {
                     unread();
                     node = atom();
@@ -2123,12 +2142,12 @@
             case '.':
                 next();
                 if (has(DOTALL)) {
-                    node = new All();
+                    node = new CharProperty(ALL);
                 } else {
-                    if (has(UNIX_LINES))
-                        node = new UnixDot();
-                    else {
-                        node = new Dot();
+                    if (has(UNIX_LINES)) {
+                        node = new CharProperty(UNIXDOT);
+                    } else {
+                        node = new CharProperty(DOT);
                     }
                 }
                 break;
@@ -2155,7 +2174,12 @@
             }
 
             node = closure(node);
-
+            /* save the top dot-greedy nodes (.*, .+) as well
+            if (node instanceof GreedyCharProperty &&
+                ((GreedyCharProperty)node).cp instanceof Dot) {
+                topClosureNodes.add(node);
+            }
+            */
             if (head == null) {
                 head = tail = node;
             } else {
@@ -2213,7 +2237,10 @@
                             unread();
                         else
                             oneLetter = false;
-                        return family(oneLetter, comp);
+                        if (has(CANON_EQ) && !has(LITERAL))
+                            return new NFCCharProperty(family(oneLetter, comp));
+                        else
+                            return newCharProperty(family(oneLetter, comp));
                     }
                 }
                 unread();
@@ -2251,7 +2278,7 @@
             break;
         }
         if (first == 1) {
-            return newSingle(buffer[0]);
+            return newCharProperty(single(buffer[0]));
         } else {
             return newSlice(buffer, first, hasSupplementary);
         }
@@ -2302,6 +2329,7 @@
                 break;
             }
         }
+        hasGroupRef = true;
         if (has(CASE_INSENSITIVE))
             return new CIBackRef(refNum, has(UNICODE_CASE));
         else
@@ -2346,9 +2374,13 @@
         case 'C':
             break;
         case 'D':
-            if (create) root = has(UNICODE_CHARACTER_CLASS)
-                               ? new Utype(UnicodeProp.DIGIT).complement()
-                               : new Ctype(ASCII.DIGIT).complement();
+            if (create) {
+                predicate = has(UNICODE_CHARACTER_CLASS) ?
+                            CharPredicates.DIGIT : CharPredicates.ASCII_DIGIT;
+                predicate = predicate.negate();
+                if (!inclass)
+                    root = newCharProperty(predicate);
+            }
             return -1;
         case 'E':
         case 'F':
@@ -2358,7 +2390,11 @@
             if (create) root = new LastMatch();
             return -1;
         case 'H':
-            if (create) root = new HorizWS().complement();
+            if (create) {
+                predicate = HorizWS.negate();
+                if (!inclass)
+                    root = newCharProperty(predicate);
+            }
             return -1;
         case 'I':
         case 'J':
@@ -2377,20 +2413,32 @@
             if (create) root = new LineEnding();
             return -1;
         case 'S':
-            if (create) root = has(UNICODE_CHARACTER_CLASS)
-                               ? new Utype(UnicodeProp.WHITE_SPACE).complement()
-                               : new Ctype(ASCII.SPACE).complement();
+            if (create) {
+                predicate = has(UNICODE_CHARACTER_CLASS) ?
+                            CharPredicates.WHITE_SPACE : CharPredicates.ASCII_SPACE;
+                predicate = predicate.negate();
+                if (!inclass)
+                    root = newCharProperty(predicate);
+            }
             return -1;
         case 'T':
         case 'U':
             break;
         case 'V':
-            if (create) root = new VertWS().complement();
+            if (create) {
+                predicate = VertWS.negate();
+                if (!inclass)
+                    root = newCharProperty(predicate);
+            }
             return -1;
         case 'W':
-            if (create) root = has(UNICODE_CHARACTER_CLASS)
-                               ? new Utype(UnicodeProp.WORD).complement()
-                               : new Ctype(ASCII.WORD).complement();
+            if (create) {
+                predicate = has(UNICODE_CHARACTER_CLASS) ?
+                            CharPredicates.WORD : CharPredicates.ASCII_WORD;
+                predicate = predicate.negate();
+                if (!inclass)
+                    root = newCharProperty(predicate);
+            }
             return -1;
         case 'X':
             if (inclass) break;
@@ -2430,9 +2478,12 @@
         case 'c':
             return c();
         case 'd':
-            if (create) root = has(UNICODE_CHARACTER_CLASS)
-                               ? new Utype(UnicodeProp.DIGIT)
-                               : new Ctype(ASCII.DIGIT);
+            if (create) {
+                predicate = has(UNICODE_CHARACTER_CLASS) ?
+                            CharPredicates.DIGIT : CharPredicates.ASCII_DIGIT;
+                if (!inclass)
+                    root = newCharProperty(predicate);
+            }
             return -1;
         case 'e':
             return '\033';
@@ -2441,7 +2492,11 @@
         case 'g':
             break;
         case 'h':
-            if (create) root = new HorizWS();
+            if (create) {
+                predicate = HorizWS;
+                if (!inclass)
+                    root = newCharProperty(predicate);
+            }
             return -1;
         case 'i':
         case 'j':
@@ -2455,6 +2510,7 @@
             if (!namedGroups().containsKey(name))
                 throw error("(named capturing group <"+ name+"> does not exit");
             if (create) {
+                hasGroupRef = true;
                 if (has(CASE_INSENSITIVE))
                     root = new CIBackRef(namedGroups().get(name), has(UNICODE_CASE));
                 else
@@ -2473,9 +2529,12 @@
         case 'r':
             return '\r';
         case 's':
-            if (create) root = has(UNICODE_CHARACTER_CLASS)
-                               ? new Utype(UnicodeProp.WHITE_SPACE)
-                               : new Ctype(ASCII.SPACE);
+            if (create) {
+                predicate = has(UNICODE_CHARACTER_CLASS) ?
+                            CharPredicates.WHITE_SPACE : CharPredicates.ASCII_SPACE;
+                if (!inclass)
+                    root = newCharProperty(predicate);
+            }
             return -1;
         case 't':
             return '\t';
@@ -2492,12 +2551,19 @@
             // compatibility concern '\013'/0x0B is returned if isrange.
             if (isrange)
                 return '\013';
-            if (create) root = new VertWS();
+            if (create) {
+                predicate = VertWS;
+                if (!inclass)
+                    root = newCharProperty(predicate);
+            }
             return -1;
         case 'w':
-            if (create) root = has(UNICODE_CHARACTER_CLASS)
-                               ? new Utype(UnicodeProp.WORD)
-                               : new Ctype(ASCII.WORD);
+            if (create) {
+                predicate = has(UNICODE_CHARACTER_CLASS) ?
+                            CharPredicates.WORD : CharPredicates.ASCII_WORD;
+                if (!inclass)
+                    root = newCharProperty(predicate);
+            }
             return -1;
         case 'x':
             return x();
@@ -2520,63 +2586,66 @@
      * is true except for the case of [abc&&def] where def is a separate
      * right hand node with "understood" brackets.
      */
-    private CharProperty clazz(boolean consume) {
-        CharProperty prev = null;
-        CharProperty node = null;
+    private CharPredicate clazz(boolean consume) {
+        CharPredicate prev = null;
+        CharPredicate curr = null;
         BitClass bits = new BitClass();
-        boolean include = true;
-        boolean firstInClass = true;
+        BmpCharPredicate bitsP = ch -> ch < 256 && bits.bits[ch];
+
+        boolean isNeg = false;
+        boolean hasBits = false;
         int ch = next();
+
+        // Negates if first char in a class, otherwise literal
+        if (ch == '^' && temp[cursor-1] == '[') {
+            ch = next();
+            isNeg = true;
+        }
         for (;;) {
             switch (ch) {
-                case '^':
-                    // Negates if first char in a class, otherwise literal
-                    if (firstInClass) {
-                        if (temp[cursor-1] != '[')
-                            break;
-                        ch = next();
-                        include = !include;
-                        continue;
-                    } else {
-                        // ^ not first in class, treat as literal
-                        break;
-                    }
                 case '[':
-                    firstInClass = false;
-                    node = clazz(true);
+                    curr = clazz(true);
                     if (prev == null)
-                        prev = node;
+                        prev = curr;
                     else
-                        prev = union(prev, node);
+                        prev = prev.union(curr);
                     ch = peek();
                     continue;
                 case '&':
-                    firstInClass = false;
                     ch = next();
                     if (ch == '&') {
                         ch = next();
-                        CharProperty rightNode = null;
+                        CharPredicate right = null;
                         while (ch != ']' && ch != '&') {
                             if (ch == '[') {
-                                if (rightNode == null)
-                                    rightNode = clazz(true);
+                                if (right == null)
+                                    right = clazz(true);
                                 else
-                                    rightNode = union(rightNode, clazz(true));
+                                    right = right.union(clazz(true));
                             } else { // abc&&def
                                 unread();
-                                rightNode = clazz(false);
+                                right = clazz(false);
                             }
                             ch = peek();
                         }
-                        if (rightNode != null)
-                            node = rightNode;
+                        if (hasBits) {
+                            // bits used, union has high precedence
+                            if (prev == null) {
+                                prev = curr = bitsP;
+                            } else {
+                                prev = prev.union(bitsP);
+                            }
+                            hasBits = false;
+                        }
+                        if (right != null)
+                            curr = right;
                         if (prev == null) {
-                            if (rightNode == null)
+                            if (right == null)
                                 throw error("Bad class syntax");
                             else
-                                prev = rightNode;
+                                prev = right;
                         } else {
-                            prev = intersection(prev, node);
+                            prev = prev.and(curr);
                         }
                     } else {
                         // treat as a literal &
@@ -2585,43 +2654,39 @@
                     }
                     continue;
                 case 0:
-                    firstInClass = false;
                     if (cursor >= patternLength)
                         throw error("Unclosed character class");
                     break;
                 case ']':
-                    firstInClass = false;
-                    if (prev != null) {
+                    if (prev != null || hasBits) {
                         if (consume)
                             next();
+                        if (prev == null)
+                            prev = bitsP;
+                        else if (hasBits)
+                            prev = prev.union(bitsP);
+                        if (isNeg)
+                            return prev.negate();
                         return prev;
                     }
                     break;
                 default:
-                    firstInClass = false;
                     break;
             }
-            node = range(bits);
-            if (include) {
-                if (prev == null) {
-                    prev = node;
-                } else {
-                    if (prev != node)
-                        prev = union(prev, node);
-                }
+            curr = range(bits);
+            if (curr == null) {    // the bits used
+                hasBits = true;
             } else {
-                if (prev == null) {
-                    prev = node.complement();
-                } else {
-                    if (prev != node)
-                        prev = setDifference(prev, node);
-                }
+                if (prev == null)
+                    prev = curr;
+                else if (prev != curr)
+                    prev = prev.union(curr);
             }
             ch = peek();
         }
     }
 
-    private CharProperty bitsOrSingle(BitClass bits, int ch) {
+    private CharPredicate bitsOrSingle(BitClass bits, int ch) {
         /* Bits can only handle codepoints in [u+0000-u+00ff] range.
            Use "single" node instead of bits when dealing with unicode
            case folding for codepoints listed below.
@@ -2643,19 +2708,46 @@
         if (ch < 256 &&
             !(has(CASE_INSENSITIVE) && has(UNICODE_CASE) &&
               (ch == 0xff || ch == 0xb5 ||
-               ch == 0x49 || ch == 0x69 ||  //I and i
-               ch == 0x53 || ch == 0x73 ||  //S and s
-               ch == 0x4b || ch == 0x6b ||  //K and k
-               ch == 0xc5 || ch == 0xe5)))  //A+ring
-            return bits.add(ch, flags());
-        return newSingle(ch);
+               ch == 0x49 || ch == 0x69 ||    //I and i
+               ch == 0x53 || ch == 0x73 ||    //S and s
+               ch == 0x4b || ch == 0x6b ||    //K and k
+               ch == 0xc5 || ch == 0xe5))) {  //A+ring
+            bits.add(ch, flags());
+            return null;
+        }
+        return single(ch);
+    }
+
+    /**
+     *  Returns a suitably optimized, single character predicate
+     */
+    private CharPredicate single(final int ch) {
+        if (has(CASE_INSENSITIVE)) {
+            int lower, upper;
+            if (has(UNICODE_CASE)) {
+                upper = Character.toUpperCase(ch);
+                lower = Character.toLowerCase(upper);
+                // Unicode case insensitive matches
+                if (upper != lower)
+                    return SingleU(lower);
+            } else if (ASCII.isAscii(ch)) {
+                lower = ASCII.toLower(ch);
+                upper = ASCII.toUpper(ch);
+                // Case insensitive matches a given BMP character
+                if (lower != upper)
+                    return SingleI(lower, upper);
+            }
+        }
+        if (isSupplementary(ch))
+            return SingleS(ch);
+        return Single(ch);  // Match a given BMP character
     }
 
     /**
      * Parse a single character or a character range in a character class
      * and return its representative node.
      */
-    private CharProperty range(BitClass bits) {
+    private CharPredicate range(BitClass bits) {
         int ch = peek();
         if (ch == '\\') {
             ch = nextEscaped();
@@ -2674,7 +2766,7 @@
                 unread();
                 ch = escape(true, true, isrange);
                 if (ch == -1)
-                    return (CharProperty) root;
+                    return predicate;
             }
         } else {
             next();
@@ -2696,10 +2788,13 @@
                     if (m < ch) {
                         throw error("Illegal character range");
                     }
-                    if (has(CASE_INSENSITIVE))
-                        return caseInsensitiveRangeFor(ch, m);
-                    else
-                        return rangeFor(ch, m);
+                    if (has(CASE_INSENSITIVE)) {
+                        if (has(UNICODE_CASE))
+                            return CIRangeU(ch, m);
+                        return CIRange(ch, m);
+                    } else {
+                        return Range(ch, m);
+                    }
                 }
             }
             return bitsOrSingle(bits, ch);
@@ -2710,12 +2805,10 @@
     /**
      * Parses a Unicode character family and returns its representative node.
      */
-    private CharProperty family(boolean singleLetter,
-                                boolean maybeComplement)
-    {
+    private CharPredicate family(boolean singleLetter, boolean isComplement) {
         next();
         String name;
-        CharProperty node = null;
+        CharPredicate p = null;
 
         if (singleLetter) {
             int c = temp[cursor];
@@ -2747,88 +2840,62 @@
             switch (name) {
                 case "sc":
                 case "script":
-                    node = unicodeScriptPropertyFor(value);
+                    p = CharPredicates.forUnicodeScript(value);
                     break;
                 case "blk":
                 case "block":
-                    node = unicodeBlockPropertyFor(value);
+                    p = CharPredicates.forUnicodeBlock(value);
                     break;
                 case "gc":
                 case "general_category":
-                    node = charPropertyNodeFor(value);
+                    p = CharPredicates.forProperty(value);
                     break;
                 default:
-                    throw error("Unknown Unicode property {name=<" + name + ">, "
-                                + "value=<" + value + ">}");
+                    break;
             }
+            if (p == null)
+                throw error("Unknown Unicode property {name=<" + name + ">, "
+                             + "value=<" + value + ">}");
+
         } else {
             if (name.startsWith("In")) {
-                // \p{inBlockName}
-                node = unicodeBlockPropertyFor(name.substring(2));
+                // \p{InBlockName}
+                p = CharPredicates.forUnicodeBlock(name.substring(2));
             } else if (name.startsWith("Is")) {
-                // \p{isGeneralCategory} and \p{isScriptName}
+                // \p{IsGeneralCategory} and \p{IsScriptName}
                 name = name.substring(2);
-                UnicodeProp uprop = UnicodeProp.forName(name);
-                if (uprop != null)
-                    node = new Utype(uprop);
-                if (node == null)
-                    node = CharPropertyNames.charPropertyFor(name);
-                if (node == null)
-                    node = unicodeScriptPropertyFor(name);
+                p = CharPredicates.forUnicodeProperty(name);
+                if (p == null)
+                    p = CharPredicates.forProperty(name);
+                if (p == null)
+                    p = CharPredicates.forUnicodeScript(name);
             } else {
                 if (has(UNICODE_CHARACTER_CLASS)) {
-                    UnicodeProp uprop = UnicodeProp.forPOSIXName(name);
-                    if (uprop != null)
-                        node = new Utype(uprop);
+                    p = CharPredicates.forPOSIXName(name);
                 }
-                if (node == null)
-                    node = charPropertyNodeFor(name);
+                if (p == null)
+                    p = CharPredicates.forProperty(name);
             }
-        }
-        if (maybeComplement) {
-            if (node instanceof Category || node instanceof Block)
-                hasSupplementary = true;
-            node = node.complement();
-        }
-        return node;
+            if (p == null)
+                throw error("Unknown character property name {In/Is" + name + "}");
+        }
+        if (isComplement) {
+            // it might be too expensive to detect if a complement of
+            // CharProperty can match "certain" supplementary. So just
+            // go with StartS.
+            hasSupplementary = true;
+            p = p.negate();
+        }
+        return p;
     }
 
-
-    /**
-     * Returns a CharProperty matching all characters belong to
-     * a UnicodeScript.
-     */
-    private CharProperty unicodeScriptPropertyFor(String name) {
-        final Character.UnicodeScript script;
-        try {
-            script = Character.UnicodeScript.forName(name);
-        } catch (IllegalArgumentException iae) {
-            throw error("Unknown character script name {" + name + "}");
-        }
-        return new Script(script);
-    }
-
-    /**
-     * Returns a CharProperty matching all characters in a UnicodeBlock.
-     */
-    private CharProperty unicodeBlockPropertyFor(String name) {
-        final Character.UnicodeBlock block;
-        try {
-            block = Character.UnicodeBlock.forName(name);
-        } catch (IllegalArgumentException iae) {
-            throw error("Unknown character block name {" + name + "}");
-        }
-        return new Block(block);
-    }
-
-    /**
-     * Returns a CharProperty matching all characters in a named property.
-     */
-    private CharProperty charPropertyNodeFor(String name) {
-        CharProperty p = CharPropertyNames.charPropertyFor(name);
+    private CharProperty newCharProperty(CharPredicate p) {
         if (p == null)
-            throw error("Unknown character property name {" + name + "}");
-        return p;
+            return null;
+        if (p instanceof BmpCharPredicate)
+            return new BmpCharProperty((BmpCharPredicate)p);
+        else
+            return new CharProperty(p);
     }
 
     /**
@@ -2859,6 +2926,7 @@
         Node head = null;
         Node tail = null;
         int save = flags;
+        int saveTCNCount = topClosureNodes.size();
         root = null;
         int ch = next();
         if (ch == '?') {
@@ -2884,7 +2952,7 @@
                 head = createGroup(true);
                 tail = root;
                 head.next = expr(tail);
-                head = tail = new Ques(head, INDEPENDENT);
+                head = tail = new Ques(head, Qtype.INDEPENDENT);
                 break;
             case '<':   // (?<xxx)  look behind
                 ch = read();
@@ -2928,6 +2996,9 @@
                 } else {
                     throw error("Unknown look-behind group");
                 }
+                // clear all top-closure-nodes inside lookbehind
+                if (saveTCNCount < topClosureNodes.size())
+                    topClosureNodes.subList(saveTCNCount, topClosureNodes.size()).clear();
                 break;
             case '$':
             case '@':
@@ -2968,15 +3039,20 @@
             return node;    // Dual return
         }
 
+        // have group closure, clear all inner closure nodes from the
+        // top list (no backtracking stopper optimization for inner
+        if (saveTCNCount < topClosureNodes.size())
+            topClosureNodes.subList(saveTCNCount, topClosureNodes.size()).clear();
+
         if (node instanceof Ques) {
             Ques ques = (Ques) node;
-            if (ques.type == POSSESSIVE) {
+            if (ques.type == Qtype.POSSESSIVE) {
                 root = node;
                 return node;
             }
             tail.next = new BranchConn();
             tail = tail.next;
-            if (ques.type == GREEDY) {
+            if (ques.type == Qtype.GREEDY) {
                 head = new Branch(head, null, tail);
             } else { // Reluctant quantifier
                 head = new Branch(null, head, tail);
@@ -2985,7 +3061,7 @@
             return head;
         } else if (node instanceof Curly) {
             Curly curly = (Curly) node;
-            if (curly.type == POSSESSIVE) {
+            if (curly.type == Qtype.POSSESSIVE) {
                 root = node;
                 return node;
             }
@@ -3002,10 +3078,14 @@
             } else { // Non-deterministic
                 int temp = ((GroupHead) head).localIndex;
                 Loop loop;
-                if (curly.type == GREEDY)
+                if (curly.type == Qtype.GREEDY) {
                     loop = new Loop(this.localCount, temp);
-                else  // Reluctant Curly
+                    // add the max_reps greedy to the top-closure-node list
+                    if (curly.cmax == MAX_REPS)
+                        topClosureNodes.add(loop);
+                } else {  // Reluctant Curly
                     loop = new LazyLoop(this.localCount, temp);
+                }
                 Prolog prolog = new Prolog(loop);
                 this.localCount += 1;
                 loop.cmin = curly.cmin;
@@ -3031,6 +3111,10 @@
             groupIndex = capturingGroupCount++;
         GroupHead head = new GroupHead(localIndex);
         root = new GroupTail(localIndex, groupIndex);
+
+        // for debug/print only, head.match does NOT need the "tail" info
+        head.tail = (GroupTail)root;
+
         if (!anonymous && groupIndex < 10)
             groupNodes[groupIndex] = head;
         return head;
@@ -3119,13 +3203,26 @@
 
     static final int MAX_REPS   = 0x7FFFFFFF;
 
-    static final int GREEDY     = 0;
-
-    static final int LAZY       = 1;
-
-    static final int POSSESSIVE = 2;
-
-    static final int INDEPENDENT = 3;
+    static enum Qtype {
+        GREEDY, LAZY, POSSESSIVE, INDEPENDENT
+    }
+
+    private Node curly(Node prev, int cmin) {
+        int ch = next();
+        if (ch == '?') {
+            next();
+            return new Curly(prev, cmin, MAX_REPS, Qtype.LAZY);
+        } else if (ch == '+') {
+            next();
+            return new Curly(prev, cmin, MAX_REPS, Qtype.POSSESSIVE);
+        }
+        if (prev instanceof BmpCharProperty) {
+            return new BmpCharPropertyGreedy((BmpCharProperty)prev, cmin);
+        } else if (prev instanceof CharProperty) {
+            return new CharPropertyGreedy((CharProperty)prev, cmin);
+        }
+        return new Curly(prev, cmin, MAX_REPS, Qtype.GREEDY);
+    }
 
     /**
      * Processes repetition. If the next character peeked is a quantifier
@@ -3140,32 +3237,16 @@
             ch = next();
             if (ch == '?') {
                 next();
-                return new Ques(prev, LAZY);
-            } else if (ch == '+') {
-                next();
-                return new Ques(prev, POSSESSIVE);
-            }
-            return new Ques(prev, GREEDY);
-        case '*':
-            ch = next();
-            if (ch == '?') {
-                next();
-                return new Curly(prev, 0, MAX_REPS, LAZY);
+                return new Ques(prev, Qtype.LAZY);
             } else if (ch == '+') {
                 next();
-                return new Curly(prev, 0, MAX_REPS, POSSESSIVE);
+                return new Ques(prev, Qtype.POSSESSIVE);
             }
-            return new Curly(prev, 0, MAX_REPS, GREEDY);
+            return new Ques(prev, Qtype.GREEDY);
+        case '*':
+            return curly(prev, 0);
         case '+':
-            ch = next();
-            if (ch == '?') {
-                next();
-                return new Curly(prev, 1, MAX_REPS, LAZY);
-            } else if (ch == '+') {
-                next();
-                return new Curly(prev, 1, MAX_REPS, POSSESSIVE);
-            }
-            return new Curly(prev, 1, MAX_REPS, GREEDY);
+            return curly(prev, 1);
         case '{':
             ch = temp[cursor+1];
             if (ASCII.isDigit(ch)) {
@@ -3194,12 +3275,12 @@
                 ch = peek();
                 if (ch == '?') {
                     next();
-                    curly = new Curly(prev, cmin, cmax, LAZY);
+                    curly = new Curly(prev, cmin, cmax, Qtype.LAZY);
                 } else if (ch == '+') {
                     next();
-                    curly = new Curly(prev, cmin, cmax, POSSESSIVE);
+                    curly = new Curly(prev, cmin, cmax, Qtype.POSSESSIVE);
                 } else {
-                    curly = new Curly(prev, cmin, cmax, GREEDY);
+                    curly = new Curly(prev, cmin, cmax, Qtype.GREEDY);
                 }
                 return curly;
             } else {
@@ -3376,10 +3457,15 @@
      *  never matches values above Latin-1, and a complemented BitClass always
      *  matches values above Latin-1.
      */
-    private static final class BitClass extends BmpCharProperty {
+    static final class BitClass extends BmpCharProperty {
         final boolean[] bits;
-        BitClass() { bits = new boolean[256]; }
-        private BitClass(boolean[] bits) { this.bits = bits; }
+        BitClass() {
+            this(new boolean[256]);
+        }
+        private BitClass(boolean[] bits) {
+            super( ch -> ch < 256 && bits[ch]);
+            this.bits = bits;
+        }
         BitClass add(int c, int flags) {
             assert c >= 0 && c <= 255;
             if ((flags & CASE_INSENSITIVE) != 0) {
@@ -3394,32 +3480,6 @@
             bits[c] = true;
             return this;
         }
-        boolean isSatisfiedBy(int ch) {
-            return ch < 256 && bits[ch];
-        }
-    }
-
-    /**
-     *  Returns a suitably optimized, single character matcher.
-     */
-    private CharProperty newSingle(final int ch) {
-        if (has(CASE_INSENSITIVE)) {
-            int lower, upper;
-            if (has(UNICODE_CASE)) {
-                upper = Character.toUpperCase(ch);
-                lower = Character.toLowerCase(upper);
-                if (upper != lower)
-                    return new SingleU(lower);
-            } else if (ASCII.isAscii(ch)) {
-                lower = ASCII.toLower(ch);
-                upper = ASCII.toUpper(ch);
-                if (lower != upper)
-                    return new SingleI(lower, upper);
-            }
-        }
-        if (isSupplementary(ch))
-            return new SingleS(ch);    // Match a given Unicode character
-        return new Single(ch);         // Match a given BMP character
     }
 
     /**
@@ -3827,18 +3887,17 @@
      * Abstract node class to match one character satisfying some
      * boolean property.
      */
-    private abstract static class CharProperty extends Node {
-        abstract boolean isSatisfiedBy(int ch);
-        CharProperty complement() {
-            return new CharProperty() {
-                    boolean isSatisfiedBy(int ch) {
-                        return ! CharProperty.this.isSatisfiedBy(ch);}};
+    static class CharProperty extends Node {
+        CharPredicate predicate;
+
+        CharProperty (CharPredicate predicate) {
+            this.predicate = predicate;
         }
         boolean match(Matcher matcher, int i, CharSequence seq) {
             if (i < matcher.to) {
                 int ch = Character.codePointAt(seq, i);
-                return isSatisfiedBy(ch)
-                    && next.match(matcher, i+Character.charCount(ch), seq);
+                return predicate.is(ch) &&
+                       next.match(matcher, i + Character.charCount(ch), seq);
             } else {
                 matcher.hitEnd = true;
                 return false;
@@ -3855,11 +3914,14 @@
      * Optimized version of CharProperty that works only for
      * properties never satisfied by Supplementary characters.
      */
-    private abstract static class BmpCharProperty extends CharProperty {
+    private static class BmpCharProperty extends CharProperty {
+        BmpCharProperty (BmpCharPredicate predicate) {
+            super(predicate);
+        }
         boolean match(Matcher matcher, int i, CharSequence seq) {
             if (i < matcher.to) {
-                return isSatisfiedBy(seq.charAt(i))
-                    && next.match(matcher, i+1, seq);
+                return predicate.is(seq.charAt(i)) &&
+                       next.match(matcher, i + 1, seq);
             } else {
                 matcher.hitEnd = true;
                 return false;
@@ -3867,135 +3929,53 @@
         }
     }
 
-    /**
-     * Node class that matches a Supplementary Unicode character
-     */
-    static final class SingleS extends CharProperty {
-        final int c;
-        SingleS(int c) { this.c = c; }
-        boolean isSatisfiedBy(int ch) {
-            return ch == c;
-        }
-    }
-
-    /**
-     * Optimization -- matches a given BMP character
-     */
-    static final class Single extends BmpCharProperty {
-        final int c;
-        Single(int c) { this.c = c; }
-        boolean isSatisfiedBy(int ch) {
-            return ch == c;
-        }
-    }
-
-    /**
-     * Case insensitive matches a given BMP character
-     */
-    static final class SingleI extends BmpCharProperty {
-        final int lower;
-        final int upper;
-        SingleI(int lower, int upper) {
-            this.lower = lower;
-            this.upper = upper;
-        }
-        boolean isSatisfiedBy(int ch) {
-            return ch == lower || ch == upper;
-        }
-    }
-
-    /**
-     * Unicode case insensitive matches a given Unicode character
-     */
-    static final class SingleU extends CharProperty {
-        final int lower;
-        SingleU(int lower) {
-            this.lower = lower;
-        }
-        boolean isSatisfiedBy(int ch) {
-            return lower == ch ||
-                lower == Character.toLowerCase(Character.toUpperCase(ch));
-        }
-    }
-
-    /**
-     * Node class that matches a Unicode block.
-     */
-    static final class Block extends CharProperty {
-        final Character.UnicodeBlock block;
-        Block(Character.UnicodeBlock block) {
-            this.block = block;
-        }
-        boolean isSatisfiedBy(int ch) {
-            return block == Character.UnicodeBlock.of(ch);
-        }
-    }
-
-    /**
-     * Node class that matches a Unicode script
-     */
-    static final class Script extends CharProperty {
-        final Character.UnicodeScript script;
-        Script(Character.UnicodeScript script) {
-            this.script = script;
-        }
-        boolean isSatisfiedBy(int ch) {
-            return script == Character.UnicodeScript.of(ch);
-        }
-    }
-
-    /**
-     * Node class that matches a Unicode category.
-     */
-    static final class Category extends CharProperty {
-        final int typeMask;
-        Category(int typeMask) { this.typeMask = typeMask; }
-        boolean isSatisfiedBy(int ch) {
-            return (typeMask & (1 << Character.getType(ch))) != 0;
-        }
-    }
-
-    /**
-     * Node class that matches a Unicode "type"
-     */
-    static final class Utype extends CharProperty {
-        final UnicodeProp uprop;
-        Utype(UnicodeProp uprop) { this.uprop = uprop; }
-        boolean isSatisfiedBy(int ch) {
-            return uprop.is(ch);
-        }
-    }
-
-    /**
-     * Node class that matches a POSIX type.
-     */
-    static final class Ctype extends BmpCharProperty {
-        final int ctype;
-        Ctype(int ctype) { this.ctype = ctype; }
-        boolean isSatisfiedBy(int ch) {
-            return ch < 128 && ASCII.isType(ch, ctype);
-        }
-    }
-
-    /**
-     * Node class that matches a Perl vertical whitespace
-     */
-    static final class VertWS extends BmpCharProperty {
-        boolean isSatisfiedBy(int cp) {
-            return (cp >= 0x0A && cp <= 0x0D) ||
-                   cp == 0x85 || cp == 0x2028 || cp == 0x2029;
-        }
-    }
-
-    /**
-     * Node class that matches a Perl horizontal whitespace
-     */
-    static final class HorizWS extends BmpCharProperty {
-        boolean isSatisfiedBy(int cp) {
-            return cp == 0x09 || cp == 0x20 || cp == 0xa0 ||
-                   cp == 0x1680 || cp == 0x180e ||
-                   cp >= 0x2000 && cp <= 0x200a ||
-                   cp == 0x202f || cp == 0x205f || cp == 0x3000;
+    private static class NFCCharProperty extends Node {
+        CharPredicate predicate;
+        NFCCharProperty (CharPredicate predicate) {
+            this.predicate = predicate;
+        }
+
+        boolean match(Matcher matcher, int i, CharSequence seq) {
+            if (i < matcher.to) {
+                int ch0 = Character.codePointAt(seq, i);
+                int n = Character.charCount(ch0);
+                int j = i + n;
+                while (j < matcher.to) {
+                    int ch1 = Character.codePointAt(seq, j);
+                    if (Grapheme.isBoundary(ch0, ch1))
+                        break;
+                    ch0 = ch1;
+                    j += Character.charCount(ch1);
+                }
+                if (i + n == j) {    // single, assume nfc cp
+                    if (predicate.is(ch0))
+                        return next.match(matcher, j, seq);
+                } else {
+                    while (i + n < j) {
+                        String nfc = Normalizer.normalize(
+                            seq.toString().substring(i, j), Normalizer.Form.NFC);
+                        if (nfc.codePointCount(0, nfc.length()) == 1) {
+                            if (predicate.is(nfc.codePointAt(0)) &&
+                                next.match(matcher, j, seq)) {
+                                return true;
+                            }
+                        }
+
+                        ch0 = Character.codePointBefore(seq, j);
+                        j -= Character.charCount(ch0);
+                    }
+                }
+                if (j < matcher.to)
+                    return false;
+            }
+            matcher.hitEnd = true;
+            return false;
+        }
+
+        boolean study(TreeInfo info) {
+            info.minLength++;
+            info.deterministic = false;
+            return next.study(info);
         }
     }
 
@@ -4217,81 +4197,13 @@
         }
     }
 
-    private static boolean inRange(int lower, int ch, int upper) {
-        return lower <= ch && ch <= upper;
-    }
-
-    /**
-     * Returns node for matching characters within an explicit value range.
-     */
-    private static CharProperty rangeFor(final int lower,
-                                         final int upper) {
-        return new CharProperty() {
-                boolean isSatisfiedBy(int ch) {
-                    return inRange(lower, ch, upper);}};
-    }
-
-    /**
-     * Returns node for matching characters within an explicit value
-     * range in a case insensitive manner.
-     */
-    private CharProperty caseInsensitiveRangeFor(final int lower,
-                                                 final int upper) {
-        if (has(UNICODE_CASE))
-            return new CharProperty() {
-                boolean isSatisfiedBy(int ch) {
-                    if (inRange(lower, ch, upper))
-                        return true;
-                    int up = Character.toUpperCase(ch);
-                    return inRange(lower, up, upper) ||
-                           inRange(lower, Character.toLowerCase(up), upper);}};
-        return new CharProperty() {
-            boolean isSatisfiedBy(int ch) {
-                return inRange(lower, ch, upper) ||
-                    ASCII.isAscii(ch) &&
-                        (inRange(lower, ASCII.toUpper(ch), upper) ||
-                         inRange(lower, ASCII.toLower(ch), upper));
-            }};
-    }
-
-    /**
-     * Implements the Unicode category ALL and the dot metacharacter when
-     * in dotall mode.
-     */
-    static final class All extends CharProperty {
-        boolean isSatisfiedBy(int ch) {
-            return true;
-        }
-    }
-
-    /**
-     * Node class for the dot metacharacter when dotall is not enabled.
-     */
-    static final class Dot extends CharProperty {
-        boolean isSatisfiedBy(int ch) {
-            return (ch != '\n' && ch != '\r'
-                    && (ch|1) != '\u2029'
-                    && ch != '\u0085');
-        }
-    }
-
-    /**
-     * Node class for the dot metacharacter when dotall is not enabled
-     * but UNIX_LINES is enabled.
-     */
-    static final class UnixDot extends CharProperty {
-        boolean isSatisfiedBy(int ch) {
-            return ch != '\n';
-        }
-    }
-
     /**
      * The 0 or 1 quantifier. This one class implements all three types.
      */
     static final class Ques extends Node {
         Node atom;
-        int type;
-        Ques(Node node, int type) {
+        Qtype type;
+        Ques(Node node, Qtype type) {
             this.atom = node;
             this.type = type;
         }
@@ -4311,7 +4223,7 @@
             }
         }
         boolean study(TreeInfo info) {
-            if (type != INDEPENDENT) {
+            if (type != Qtype.INDEPENDENT) {
                 int minL = info.minLength;
                 atom.study(info);
                 info.minLength = minL;
@@ -4325,17 +4237,90 @@
     }
 
     /**
+     * Handles the greedy style repetition with the minimum either be
+     * 0 or 1 and the maximum be MAX_REPS, for * and + quantifier.
+     */
+    static class CharPropertyGreedy extends Node {
+        final CharPredicate predicate;
+        final int cmin;
+
+        CharPropertyGreedy(CharProperty cp, int cmin) {
+            this.predicate = cp.predicate;
+            this.cmin = cmin;
+        }
+        boolean match(Matcher matcher, int i,  CharSequence seq) {
+            int n = 0;
+            int to = matcher.to;
+            // greedy, all the way down
+            while (i < to) {
+                int ch = Character.codePointAt(seq, i);
+                if (!predicate.is(ch))
+                   break;
+                i += Character.charCount(ch);
+                n++;
+            }
+            if (i >= to) {
+                matcher.hitEnd = true;
+            }
+            while (n >= cmin) {
+                if (next.match(matcher, i, seq))
+                    return true;
+                if (n == cmin)
+                    return false;
+                 // backing off if match fails
+                int ch = Character.codePointBefore(seq, i);
+                i -= Character.charCount(ch);
+                n--;
+            }
+            return false;
+        }
+
+        boolean study(TreeInfo info) {
+            info.minLength += cmin;
+            if (info.maxValid) {
+                info.maxLength += MAX_REPS;
+            }
+            info.deterministic = false;
+            return next.study(info);
+        }
+    }
+
+    static final class BmpCharPropertyGreedy extends CharPropertyGreedy {
+
+        BmpCharPropertyGreedy(BmpCharProperty bcp, int cmin) {
+            super(bcp, cmin);
+        }
+
+        boolean match(Matcher matcher, int i,  CharSequence seq) {
+            int n = 0;
+            int to = matcher.to;
+            while (i < to && predicate.is(seq.charAt(i))) {
+                i++; n++;
+            }
+            if (i >= to) {
+                matcher.hitEnd = true;
+            }
+            while (n >= cmin) {
+                if (next.match(matcher, i, seq))
+                    return true;
+                i--; n--;  // backing off if match fails
+            }
+            return false;
+        }
+    }
+
+    /**
      * Handles the curly-brace style repetition with a specified minimum and
      * maximum occurrences. The * quantifier is handled as a special case.
      * This class handles the three types.
      */
     static final class Curly extends Node {
         Node atom;
-        int type;
+        Qtype type;
         int cmin;
         int cmax;
 
-        Curly(Node node, int cmin, int cmax, int type) {
+        Curly(Node node, int cmin, int cmax, Qtype type) {
             this.atom = node;
             this.type = type;
             this.cmin = cmin;
@@ -4350,9 +4335,9 @@
                 }
                 return false;
             }
-            if (type == GREEDY)
+            if (type == Qtype.GREEDY)
                 return match0(matcher, i, j, seq);
-            else if (type == LAZY)
+            else if (type == Qtype.LAZY)
                 return match1(matcher, i, j, seq);
             else
                 return match2(matcher, i, j, seq);
@@ -4474,14 +4459,14 @@
      */
     static final class GroupCurly extends Node {
         Node atom;
-        int type;
+        Qtype type;
         int cmin;
         int cmax;
         int localIndex;
         int groupIndex;
         boolean capture;
 
-        GroupCurly(Node node, int cmin, int cmax, int type, int local,
+        GroupCurly(Node node, int cmin, int cmax, Qtype type, int local,
                    int group, boolean capture) {
             this.atom = node;
             this.type = type;
@@ -4521,9 +4506,9 @@
                 }
             }
             if (ret) {
-                if (type == GREEDY) {
+                if (type == Qtype.GREEDY) {
                     ret = match0(matcher, i, cmin, seq);
-                } else if (type == LAZY) {
+                } else if (type == Qtype.LAZY) {
                     ret = match1(matcher, i, cmin, seq);
                 } else {
                     ret = match2(matcher, i, cmin, seq);
@@ -4769,6 +4754,7 @@
      */
     static final class GroupHead extends Node {
         int localIndex;
+        GroupTail tail;    // for debug/print only, match does not need to know
         GroupHead(int localCount) {
             localIndex = localCount;
         }
@@ -4876,9 +4862,11 @@
         int countIndex; // local count index in matcher locals
         int beginIndex; // group beginning index
         int cmin, cmax;
+        int posIndex;
         Loop(int countIndex, int beginIndex) {
             this.countIndex = countIndex;
             this.beginIndex = beginIndex;
+            this.posIndex = -1;
         }
         boolean match(Matcher matcher, int i, CharSequence seq) {
             // Avoid infinite loop in zero-length case.
@@ -4901,14 +4889,25 @@
                 // This block is for after we have the minimum
                 // iterations required for the loop to match
                 if (count < cmax) {
+                    // Let's check if we have already tried and failed
+                    // at this starting position "i" in the past.
+                    // If yes, then just return false wihtout trying
+                    // again, to stop the exponential backtracking.
+                    if (posIndex != -1 &&
+                        matcher.localsPos[posIndex].contains(i)) {
+                        return next.match(matcher, i, seq);
+                    }
                     matcher.locals[countIndex] = count + 1;
                     boolean b = body.match(matcher, i, seq);
                     // If match failed we must backtrack, so
                     // the loop count should NOT be incremented
-                    if (!b)
-                        matcher.locals[countIndex] = count;
-                    else
+                    if (b)
                         return true;
+                    matcher.locals[countIndex] = count;
+                    // save the failed position
+                    if (posIndex != -1) {
+                        matcher.localsPos[posIndex].add(i);
+                    }
                 }
             }
             return next.match(matcher, i, seq);
@@ -4916,6 +4915,9 @@
         boolean matchInit(Matcher matcher, int i, CharSequence seq) {
             int save = matcher.locals[countIndex];
             boolean ret = false;
+            if (posIndex != -1 && matcher.localsPos[posIndex] == null) {
+                matcher.localsPos[posIndex] = new IntHashSet();
+            }
             if (0 < cmin) {
                 matcher.locals[countIndex] = 1;
                 ret = body.match(matcher, i, seq);
@@ -5362,36 +5364,6 @@
     }
 
     /**
-     * Returns the set union of two CharProperty nodes.
-     */
-    private static CharProperty union(final CharProperty lhs,
-                                      final CharProperty rhs) {
-        return new CharProperty() {
-                boolean isSatisfiedBy(int ch) {
-                    return lhs.isSatisfiedBy(ch) || rhs.isSatisfiedBy(ch);}};
-    }
-
-    /**
-     * Returns the set intersection of two CharProperty nodes.
-     */
-    private static CharProperty intersection(final CharProperty lhs,
-                                             final CharProperty rhs) {
-        return new CharProperty() {
-                boolean isSatisfiedBy(int ch) {
-                    return lhs.isSatisfiedBy(ch) && rhs.isSatisfiedBy(ch);}};
-    }
-
-    /**
-     * Returns the set difference of two CharProperty nodes.
-     */
-    private static CharProperty setDifference(final CharProperty lhs,
-                                              final CharProperty rhs) {
-        return new CharProperty() {
-                boolean isSatisfiedBy(int ch) {
-                    return ! rhs.isSatisfiedBy(ch) && lhs.isSatisfiedBy(ch);}};
-    }
-
-    /**
      * Handles word boundaries. Includes a field to allow this one class to
      * deal with the different types of word boundaries we can match. The word
      * characters include underscores, letters, and digits. Non spacing marks
@@ -5411,7 +5383,7 @@
         }
 
         boolean isWord(int ch) {
-            return useUWORD ? UnicodeProp.WORD.is(ch)
+            return useUWORD ? CharPredicates.WORD.is(ch)
                             : (ch == '_' || Character.isLetterOrDigit(ch));
         }
 
@@ -5657,214 +5629,154 @@
         }
     }
 
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
+    @FunctionalInterface
+    static interface CharPredicate {
+        boolean is(int ch);
+
+        default CharPredicate and(CharPredicate p) {
+            return ch -> is(ch) && p.is(ch);
+        }
+        default CharPredicate union(CharPredicate p) {
+            return ch -> is(ch) || p.is(ch);
+        }
+        default CharPredicate union(CharPredicate p1,
+                                    CharPredicate p2 ) {
+            return ch -> is(ch) || p1.is(ch) || p2.is(ch);
+        }
+        default CharPredicate negate() {
+            return ch -> !is(ch);
+        }
+    }
+
+    static interface BmpCharPredicate extends CharPredicate {
+
+        default CharPredicate and(CharPredicate p) {
+            if(p instanceof BmpCharPredicate)
+                return (BmpCharPredicate)(ch -> is(ch) && p.is(ch));
+            return ch -> is(ch) && p.is(ch);
+        }
+        default CharPredicate union(CharPredicate p) {
+            if (p instanceof BmpCharPredicate)
+                return (BmpCharPredicate)(ch -> is(ch) || p.is(ch));
+            return ch -> is(ch) || p.is(ch);
+        }
+        static CharPredicate union(CharPredicate... predicates) {
+            CharPredicate cp = ch -> {
+                for (CharPredicate p : predicates) {
+                    if (!p.is(ch))
+                        return false;
+                }
+                return true;
+            };
+            for (CharPredicate p : predicates) {
+                if (! (p instanceof BmpCharPredicate))
+                    return cp;
+            }
+            return (BmpCharPredicate)cp;
+        }
+    }
+
+    /**
+     * matches a Perl vertical whitespace
+     */
+    static BmpCharPredicate VertWS = cp ->
+        (cp >= 0x0A && cp <= 0x0D) || cp == 0x85 || cp == 0x2028 || cp == 0x2029;
+
+    /**
+     * matches a Perl horizontal whitespace
+     */
+    static BmpCharPredicate HorizWS = cp ->
+        cp == 0x09 || cp == 0x20 || cp == 0xa0 || cp == 0x1680 ||
+        cp == 0x180e || cp >= 0x2000 && cp <= 0x200a ||  cp == 0x202f ||
+        cp == 0x205f || cp == 0x3000;
+
+    /**
+     *  for the Unicode category ALL and the dot metacharacter when
+     *  in dotall mode.
+     */
+    static CharPredicate ALL = ch -> true;
+
+    /**
+     * for the dot metacharacter when dotall is not enabled.
+     */
+    static CharPredicate DOT = ch -> (ch != '\n' && ch != '\r'
+                                          && (ch|1) != '\u2029'
+                                          && ch != '\u0085');
+    /**
+     *  the dot metacharacter when dotall is not enabled but UNIX_LINES is enabled.
+     */
+    static CharPredicate UNIXDOT = ch ->  ch != '\n';
+
+    /**
+     * Indicate that matches a Supplementary Unicode character
+     */
+    static CharPredicate SingleS(int c) {
+        return ch -> ch == c;
+    }
+
+    /**
+     * A bmp/optimized predicate of single
+     */
+    static BmpCharPredicate Single(int c) {
+        return ch -> ch == c;
+    }
+
+    /**
+     * Case insensitive matches a given BMP character
+     */
+    static BmpCharPredicate SingleI(int lower, int upper) {
+        return ch -> ch == lower || ch == upper;
+    }
+
+    /**
+     * Unicode case insensitive matches a given Unicode character
+     */
+    static CharPredicate SingleU(int lower) {
+        return ch -> lower == ch ||
+                     lower == Character.toLowerCase(Character.toUpperCase(ch));
+    }
+
+    private static boolean inRange(int lower, int ch, int upper) {
+        return lower <= ch && ch <= upper;
+    }
+
+    /**
+     * Charactrs within a explicit value range
+     */
+    static CharPredicate Range(int lower, int upper) {
+        if (upper < Character.MIN_HIGH_SURROGATE ||
+            lower > Character.MAX_HIGH_SURROGATE &&
+            upper < Character.MIN_SUPPLEMENTARY_CODE_POINT)
+            return (BmpCharPredicate)(ch -> inRange(lower, ch, upper));
+        return ch -> inRange(lower, ch, upper);
+    }
+
+   /**
+    * Charactrs within a explicit value range in a case insensitive manner.
+    */
+    static CharPredicate CIRange(int lower, int upper) {
+        return ch -> inRange(lower, ch, upper) ||
+                     ASCII.isAscii(ch) &&
+                     (inRange(lower, ASCII.toUpper(ch), upper) ||
+                      inRange(lower, ASCII.toLower(ch), upper));
+    }
+
+    static CharPredicate CIRangeU(int lower, int upper) {
+        return ch -> {
+            if (inRange(lower, ch, upper))
+                return true;
+            int up = Character.toUpperCase(ch);
+            return inRange(lower, up, upper) ||
+                   inRange(lower, Character.toLowerCase(up), upper);
+        };
+    }
 
     /**
      *  This must be the very first initializer.
      */
-    static Node accept = new Node();
-
-    static Node lastAccept = new LastNode();
-
-    private static class CharPropertyNames {
-
-        static CharProperty charPropertyFor(String name) {
-            CharPropertyFactory m = map.get(name);
-            return m == null ? null : m.make();
-        }
-
-        private abstract static class CharPropertyFactory {
-            abstract CharProperty make();
-        }
-
-        private static void defCategory(String name,
-                                        final int typeMask) {
-            map.put(name, new CharPropertyFactory() {
-                    CharProperty make() { return new Category(typeMask);}});
-        }
-
-        private static void defRange(String name,
-                                     final int lower, final int upper) {
-            map.put(name, new CharPropertyFactory() {
-                    CharProperty make() { return rangeFor(lower, upper);}});
-        }
-
-        private static void defCtype(String name,
-                                     final int ctype) {
-            map.put(name, new CharPropertyFactory() {
-                    CharProperty make() { return new Ctype(ctype);}});
-        }
-
-        private abstract static class CloneableProperty
-            extends CharProperty implements Cloneable
-        {
-            public CloneableProperty clone() {
-                try {
-                    return (CloneableProperty) super.clone();
-                } catch (CloneNotSupportedException e) {
-                    throw new AssertionError(e);
-                }
-            }
-        }
-
-        private static void defClone(String name,
-                                     final CloneableProperty p) {
-            map.put(name, new CharPropertyFactory() {
-                    CharProperty make() { return p.clone();}});
-        }
-
-        private static final HashMap<String, CharPropertyFactory> map
-            = new HashMap<>();
-
-        static {
-            // Unicode character property aliases, defined in
-            // http://www.unicode.org/Public/UNIDATA/PropertyValueAliases.txt
-            defCategory("Cn", 1<<Character.UNASSIGNED);
-            defCategory("Lu", 1<<Character.UPPERCASE_LETTER);
-            defCategory("Ll", 1<<Character.LOWERCASE_LETTER);
-            defCategory("Lt", 1<<Character.TITLECASE_LETTER);
-            defCategory("Lm", 1<<Character.MODIFIER_LETTER);
-            defCategory("Lo", 1<<Character.OTHER_LETTER);
-            defCategory("Mn", 1<<Character.NON_SPACING_MARK);
-            defCategory("Me", 1<<Character.ENCLOSING_MARK);
-            defCategory("Mc", 1<<Character.COMBINING_SPACING_MARK);
-            defCategory("Nd", 1<<Character.DECIMAL_DIGIT_NUMBER);
-            defCategory("Nl", 1<<Character.LETTER_NUMBER);
-            defCategory("No", 1<<Character.OTHER_NUMBER);
-            defCategory("Zs", 1<<Character.SPACE_SEPARATOR);
-            defCategory("Zl", 1<<Character.LINE_SEPARATOR);
-            defCategory("Zp", 1<<Character.PARAGRAPH_SEPARATOR);
-            defCategory("Cc", 1<<Character.CONTROL);
-            defCategory("Cf", 1<<Character.FORMAT);
-            defCategory("Co", 1<<Character.PRIVATE_USE);
-            defCategory("Cs", 1<<Character.SURROGATE);
-            defCategory("Pd", 1<<Character.DASH_PUNCTUATION);
-            defCategory("Ps", 1<<Character.START_PUNCTUATION);
-            defCategory("Pe", 1<<Character.END_PUNCTUATION);
-            defCategory("Pc", 1<<Character.CONNECTOR_PUNCTUATION);
-            defCategory("Po", 1<<Character.OTHER_PUNCTUATION);
-            defCategory("Sm", 1<<Character.MATH_SYMBOL);
-            defCategory("Sc", 1<<Character.CURRENCY_SYMBOL);
-            defCategory("Sk", 1<<Character.MODIFIER_SYMBOL);
-            defCategory("So", 1<<Character.OTHER_SYMBOL);
-            defCategory("Pi", 1<<Character.INITIAL_QUOTE_PUNCTUATION);
-            defCategory("Pf", 1<<Character.FINAL_QUOTE_PUNCTUATION);
-            defCategory("L", ((1<<Character.UPPERCASE_LETTER) |
-                              (1<<Character.LOWERCASE_LETTER) |
-                              (1<<Character.TITLECASE_LETTER) |
-                              (1<<Character.MODIFIER_LETTER)  |
-                              (1<<Character.OTHER_LETTER)));
-            defCategory("M", ((1<<Character.NON_SPACING_MARK) |
-                              (1<<Character.ENCLOSING_MARK)   |
-                              (1<<Character.COMBINING_SPACING_MARK)));
-            defCategory("N", ((1<<Character.DECIMAL_DIGIT_NUMBER) |
-                              (1<<Character.LETTER_NUMBER)        |
-                              (1<<Character.OTHER_NUMBER)));
-            defCategory("Z", ((1<<Character.SPACE_SEPARATOR) |
-                              (1<<Character.LINE_SEPARATOR)  |
-                              (1<<Character.PARAGRAPH_SEPARATOR)));
-            defCategory("C", ((1<<Character.CONTROL)     |
-                              (1<<Character.FORMAT)      |
-                              (1<<Character.PRIVATE_USE) |
-                              (1<<Character.SURROGATE))); // Other
-            defCategory("P", ((1<<Character.DASH_PUNCTUATION)      |
-                              (1<<Character.START_PUNCTUATION)     |
-                              (1<<Character.END_PUNCTUATION)       |
-                              (1<<Character.CONNECTOR_PUNCTUATION) |
-                              (1<<Character.OTHER_PUNCTUATION)     |
-                              (1<<Character.INITIAL_QUOTE_PUNCTUATION) |
-                              (1<<Character.FINAL_QUOTE_PUNCTUATION)));
-            defCategory("S", ((1<<Character.MATH_SYMBOL)     |
-                              (1<<Character.CURRENCY_SYMBOL) |
-                              (1<<Character.MODIFIER_SYMBOL) |
-                              (1<<Character.OTHER_SYMBOL)));
-            defCategory("LC", ((1<<Character.UPPERCASE_LETTER) |
-                               (1<<Character.LOWERCASE_LETTER) |
-                               (1<<Character.TITLECASE_LETTER)));
-            defCategory("LD", ((1<<Character.UPPERCASE_LETTER) |
-                               (1<<Character.LOWERCASE_LETTER) |
-                               (1<<Character.TITLECASE_LETTER) |
-                               (1<<Character.MODIFIER_LETTER)  |
-                               (1<<Character.OTHER_LETTER)     |
-                               (1<<Character.DECIMAL_DIGIT_NUMBER)));
-            defRange("L1", 0x00, 0xFF); // Latin-1
-            map.put("all", new CharPropertyFactory() {
-                    CharProperty make() { return new All(); }});
-
-            // Posix regular expression character classes, defined in
-            // http://www.unix.org/onlinepubs/009695399/basedefs/xbd_chap09.html
-            defRange("ASCII", 0x00, 0x7F);   // ASCII
-            defCtype("Alnum", ASCII.ALNUM);  // Alphanumeric characters
-            defCtype("Alpha", ASCII.ALPHA);  // Alphabetic characters
-            defCtype("Blank", ASCII.BLANK);  // Space and tab characters
-            defCtype("Cntrl", ASCII.CNTRL);  // Control characters
-            defRange("Digit", '0', '9');     // Numeric characters
-            defCtype("Graph", ASCII.GRAPH);  // printable and visible
-            defRange("Lower", 'a', 'z');     // Lower-case alphabetic
-            defRange("Print", 0x20, 0x7E);   // Printable characters
-            defCtype("Punct", ASCII.PUNCT);  // Punctuation characters
-            defCtype("Space", ASCII.SPACE);  // Space characters
-            defRange("Upper", 'A', 'Z');     // Upper-case alphabetic
-            defCtype("XDigit",ASCII.XDIGIT); // hexadecimal digits
-
-            // Java character properties, defined by methods in Character.java
-            defClone("javaLowerCase", new CloneableProperty() {
-                boolean isSatisfiedBy(int ch) {
-                    return Character.isLowerCase(ch);}});
-            defClone("javaUpperCase", new CloneableProperty() {
-                boolean isSatisfiedBy(int ch) {
-                    return Character.isUpperCase(ch);}});
-            defClone("javaAlphabetic", new CloneableProperty() {
-                boolean isSatisfiedBy(int ch) {
-                    return Character.isAlphabetic(ch);}});
-            defClone("javaIdeographic", new CloneableProperty() {
-                boolean isSatisfiedBy(int ch) {
-                    return Character.isIdeographic(ch);}});
-            defClone("javaTitleCase", new CloneableProperty() {
-                boolean isSatisfiedBy(int ch) {
-                    return Character.isTitleCase(ch);}});
-            defClone("javaDigit", new CloneableProperty() {
-                boolean isSatisfiedBy(int ch) {
-                    return Character.isDigit(ch);}});
-            defClone("javaDefined", new CloneableProperty() {
-                boolean isSatisfiedBy(int ch) {
-                    return Character.isDefined(ch);}});
-            defClone("javaLetter", new CloneableProperty() {
-                boolean isSatisfiedBy(int ch) {
-                    return Character.isLetter(ch);}});
-            defClone("javaLetterOrDigit", new CloneableProperty() {
-                boolean isSatisfiedBy(int ch) {
-                    return Character.isLetterOrDigit(ch);}});
-            defClone("javaJavaIdentifierStart", new CloneableProperty() {
-                boolean isSatisfiedBy(int ch) {
-                    return Character.isJavaIdentifierStart(ch);}});
-            defClone("javaJavaIdentifierPart", new CloneableProperty() {
-                boolean isSatisfiedBy(int ch) {
-                    return Character.isJavaIdentifierPart(ch);}});
-            defClone("javaUnicodeIdentifierStart", new CloneableProperty() {
-                boolean isSatisfiedBy(int ch) {
-                    return Character.isUnicodeIdentifierStart(ch);}});
-            defClone("javaUnicodeIdentifierPart", new CloneableProperty() {
-                boolean isSatisfiedBy(int ch) {
-                    return Character.isUnicodeIdentifierPart(ch);}});
-            defClone("javaIdentifierIgnorable", new CloneableProperty() {
-                boolean isSatisfiedBy(int ch) {
-                    return Character.isIdentifierIgnorable(ch);}});
-            defClone("javaSpaceChar", new CloneableProperty() {
-                boolean isSatisfiedBy(int ch) {
-                    return Character.isSpaceChar(ch);}});
-            defClone("javaWhitespace", new CloneableProperty() {
-                boolean isSatisfiedBy(int ch) {
-                    return Character.isWhitespace(ch);}});
-            defClone("javaISOControl", new CloneableProperty() {
-                boolean isSatisfiedBy(int ch) {
-                    return Character.isISOControl(ch);}});
-            defClone("javaMirrored", new CloneableProperty() {
-                boolean isSatisfiedBy(int ch) {
-                    return Character.isMirrored(ch);}});
-        }
-    }
+    static final Node accept = new Node();
+
+    static final Node lastAccept = new LastNode();
 
     /**
      * Creates a predicate which can be used to match a string.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/util/regex/PrintPattern.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,220 @@
+/*
+ * 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 java.util.regex;
+
+import java.util.HashMap;
+import java.util.regex.Pattern.CharPredicate;
+import java.util.regex.CharPredicates;
+import static java.util.regex.ASCII.*;
+
+/**
+ * A utility class to print out the pattern node tree.
+ */
+
+class PrintPattern {
+
+    private static HashMap<Pattern.Node, Integer> ids = new HashMap<>();
+
+    private static void print(Pattern.Node node, String text, int depth) {
+        if (!ids.containsKey(node))
+            ids.put(node, ids.size());
+        print("%6d:%" + (depth==0? "": depth<<1) + "s<%s>", ids.get(node), "", text);
+        if (ids.containsKey(node.next))
+            print(" (=>%d)", ids.get(node.next));
+        print("%n");
+    }
+
+    private static void print(String s, int depth) {
+        print("       %" + (depth==0?"":depth<<1) + "s<%s>%n", "", s);
+    }
+
+    private static void print(String fmt, Object ... args) {
+        System.err.printf(fmt, args);
+    }
+
+    private static String toStringCPS(int[] cps) {
+        StringBuilder sb = new StringBuilder(cps.length);
+        for (int cp : cps)
+            sb.append(toStringCP(cp));
+        return sb.toString();
+    }
+
+    private static String toStringCP(int cp) {
+        return (isPrint(cp) ? "" + (char)cp
+                            : "\\u" + Integer.toString(cp, 16));
+    }
+
+    private static String toStringRange(int min, int max) {
+       if (max == Pattern.MAX_REPS) {
+           if (min == 0)
+               return " * ";
+           else if (min == 1)
+               return " + ";
+           return "{" + min + ", max}";
+       }
+       return "{" + min + ", " +  max + "}";
+    }
+
+    private static String toStringCtype(int type) {
+        switch(type) {
+        case UPPER:  return "ASCII.UPPER";
+        case LOWER:  return "ASCII.LOWER";
+        case DIGIT:  return "ASCII.DIGIT";
+        case SPACE:  return "ASCII.SPACE";
+        case PUNCT:  return "ASCII.PUNCT";
+        case CNTRL:  return "ASCII.CNTRL";
+        case BLANK:  return "ASCII.BLANK";
+        case UNDER:  return "ASCII.UNDER";
+        case ASCII:  return "ASCII.ASCII";
+        case ALPHA:  return "ASCII.ALPHA";
+        case ALNUM:  return "ASCII.ALNUM";
+        case GRAPH:  return "ASCII.GRAPH";
+        case WORD:   return "ASCII.WORD";
+        case XDIGIT: return "ASCII.XDIGIT";
+        default: return "ASCII ?";
+        }
+    }
+
+    private static String toString(Pattern.Node node) {
+        String name = node.getClass().getName();
+        return name.substring(name.lastIndexOf('$') + 1);
+    }
+
+    static HashMap<CharPredicate, String> pmap;
+    static {
+        pmap = new HashMap<>();
+        pmap.put(Pattern.ALL, "All");
+        pmap.put(Pattern.DOT, "Dot");
+        pmap.put(Pattern.UNIXDOT, "UnixDot");
+        pmap.put(Pattern.VertWS, "VertWS");
+        pmap.put(Pattern.HorizWS, "HorizWS");
+
+        pmap.put(CharPredicates.ASCII_DIGIT, "ASCII.DIGIT");
+        pmap.put(CharPredicates.ASCII_WORD,  "ASCII.WORD");
+        pmap.put(CharPredicates.ASCII_SPACE, "ASCII.SPACE");
+    }
+
+    static void walk(Pattern.Node node, int depth) {
+        depth++;
+        while(node != null) {
+            String name = toString(node);
+            String str;
+            if (node instanceof Pattern.Prolog) {
+                print(node, name, depth);
+                // print the loop here
+                Pattern.Loop loop = ((Pattern.Prolog)node).loop;
+                name = toString(loop);
+                str = name + " " + toStringRange(loop.cmin, loop.cmax);
+                print(loop, str, depth);
+                walk(loop.body, depth);
+                print("/" + name, depth);
+                node = loop;
+            } else if (node instanceof Pattern.Loop) {
+                return;  // stop here, body.next -> loop
+            } else if (node instanceof Pattern.Curly) {
+                Pattern.Curly c = (Pattern.Curly)node;
+                str = "Curly " + c.type + " " + toStringRange(c.cmin, c.cmax);
+                print(node, str, depth);
+                walk(c.atom, depth);
+                print("/Curly", depth);
+            } else if (node instanceof Pattern.GroupCurly) {
+                Pattern.GroupCurly gc = (Pattern.GroupCurly)node;
+                str = "GroupCurly " + gc.groupIndex / 2 +
+                      ", " + gc.type + " " + toStringRange(gc.cmin, gc.cmax);
+                print(node, str, depth);
+                walk(gc.atom, depth);
+                print("/GroupCurly", depth);
+            } else if (node instanceof Pattern.GroupHead) {
+                Pattern.GroupHead head = (Pattern.GroupHead)node;
+                Pattern.GroupTail tail = head.tail;
+                print(head, "Group.head " + (tail.groupIndex / 2), depth);
+                walk(head.next, depth);
+                print(tail, "/Group.tail " + (tail.groupIndex / 2), depth);
+                node = tail;
+            } else if (node instanceof Pattern.GroupTail) {
+                return;  // stopper
+            } else if (node instanceof Pattern.Ques) {
+                print(node, "Ques " + ((Pattern.Ques)node).type, depth);
+                walk(((Pattern.Ques)node).atom, depth);
+                print("/Ques", depth);
+            } else if (node instanceof Pattern.Branch) {
+                Pattern.Branch b = (Pattern.Branch)node;
+                print(b, name, depth);
+                int i = 0;
+                while (true) {
+                    if (b.atoms[i] != null) {
+                        walk(b.atoms[i], depth);
+                    } else {
+                        print("  (accepted)", depth);
+                    }
+                    if (++i == b.size)
+                        break;
+                    print("-branch.separator-", depth);
+                }
+                node = b.conn;
+                print(node, "/Branch", depth);
+            } else if (node instanceof Pattern.BranchConn) {
+                return;
+            } else if (node instanceof Pattern.CharProperty) {
+                str = pmap.get(((Pattern.CharProperty)node).predicate);
+                if (str == null)
+                    str = toString(node);
+                else
+                    str = "Single \"" + str + "\"";
+                print(node, str, depth);
+            } else if (node instanceof Pattern.SliceNode) {
+                str = name + "  \"" +
+                      toStringCPS(((Pattern.SliceNode)node).buffer) + "\"";
+                print(node, str, depth);
+            } else if (node instanceof Pattern.CharPropertyGreedy) {
+                Pattern.CharPropertyGreedy gcp = (Pattern.CharPropertyGreedy)node;
+                String pstr = pmap.get(gcp.predicate);
+                if (pstr == null)
+                    pstr = gcp.predicate.toString();
+                else
+                    pstr = "Single \"" + pstr + "\"";
+                str = name + " " + pstr + ((gcp.cmin == 0) ? "*" : "+");
+                print(node, str, depth);
+            } else if (node instanceof Pattern.BackRef) {
+                str = "GroupBackRef " + ((Pattern.BackRef)node).groupIndex / 2;
+                print(node, str, depth);
+            } else if (node instanceof Pattern.LastNode) {
+                print(node, "END", depth);
+            } else if (node == Pattern.accept) {
+                return;
+            } else {
+                print(node, name, depth);
+            }
+            node = node.next;
+        }
+    }
+
+    public static void main(String[] args) {
+        Pattern p = Pattern.compile(args[0]);
+        System.out.println("   Pattern: " + p);
+        walk(p.root, 0);
+    }
+}
--- a/jdk/src/java.base/share/classes/java/util/regex/UnicodeProp.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,246 +0,0 @@
-/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.util.regex;
-
-import java.util.HashMap;
-import java.util.Locale;
-
-enum UnicodeProp {
-
-    ALPHABETIC {
-        public boolean is(int ch) {
-            return Character.isAlphabetic(ch);
-        }
-    },
-
-    LETTER {
-        public boolean is(int ch) {
-            return Character.isLetter(ch);
-        }
-    },
-
-    IDEOGRAPHIC {
-        public boolean is(int ch) {
-            return Character.isIdeographic(ch);
-        }
-    },
-
-    LOWERCASE {
-        public boolean is(int ch) {
-            return Character.isLowerCase(ch);
-        }
-    },
-
-    UPPERCASE {
-        public boolean is(int ch) {
-            return Character.isUpperCase(ch);
-        }
-    },
-
-    TITLECASE {
-        public boolean is(int ch) {
-            return Character.isTitleCase(ch);
-        }
-    },
-
-    WHITE_SPACE {
-        // \p{Whitespace}
-        public boolean is(int ch) {
-            return ((((1 << Character.SPACE_SEPARATOR) |
-                      (1 << Character.LINE_SEPARATOR) |
-                      (1 << Character.PARAGRAPH_SEPARATOR)) >> Character.getType(ch)) & 1)
-                   != 0 || (ch >= 0x9 && ch <= 0xd) || (ch == 0x85);
-        }
-    },
-
-    CONTROL {
-        // \p{gc=Control}
-        public boolean is(int ch) {
-            return Character.getType(ch) == Character.CONTROL;
-        }
-    },
-
-    PUNCTUATION {
-        // \p{gc=Punctuation}
-        public boolean is(int ch) {
-            return ((((1 << Character.CONNECTOR_PUNCTUATION) |
-                      (1 << Character.DASH_PUNCTUATION) |
-                      (1 << Character.START_PUNCTUATION) |
-                      (1 << Character.END_PUNCTUATION) |
-                      (1 << Character.OTHER_PUNCTUATION) |
-                      (1 << Character.INITIAL_QUOTE_PUNCTUATION) |
-                      (1 << Character.FINAL_QUOTE_PUNCTUATION)) >> Character.getType(ch)) & 1)
-                   != 0;
-        }
-    },
-
-    HEX_DIGIT {
-        // \p{gc=Decimal_Number}
-        // \p{Hex_Digit}    -> PropList.txt: Hex_Digit
-        public boolean is(int ch) {
-            return DIGIT.is(ch) ||
-                   (ch >= 0x0030 && ch <= 0x0039) ||
-                   (ch >= 0x0041 && ch <= 0x0046) ||
-                   (ch >= 0x0061 && ch <= 0x0066) ||
-                   (ch >= 0xFF10 && ch <= 0xFF19) ||
-                   (ch >= 0xFF21 && ch <= 0xFF26) ||
-                   (ch >= 0xFF41 && ch <= 0xFF46);
-        }
-    },
-
-    ASSIGNED {
-        public boolean is(int ch) {
-            return Character.getType(ch) != Character.UNASSIGNED;
-        }
-    },
-
-    NONCHARACTER_CODE_POINT {
-        // PropList.txt:Noncharacter_Code_Point
-        public boolean is(int ch) {
-            return (ch & 0xfffe) == 0xfffe || (ch >= 0xfdd0 && ch <= 0xfdef);
-        }
-    },
-
-    DIGIT {
-        // \p{gc=Decimal_Number}
-        public boolean is(int ch) {
-            return Character.isDigit(ch);
-        }
-    },
-
-    ALNUM {
-        // \p{alpha}
-        // \p{digit}
-        public boolean is(int ch) {
-            return ALPHABETIC.is(ch) || DIGIT.is(ch);
-        }
-    },
-
-    BLANK {
-        // \p{Whitespace} --
-        // [\N{LF} \N{VT} \N{FF} \N{CR} \N{NEL}  -> 0xa, 0xb, 0xc, 0xd, 0x85
-        //  \p{gc=Line_Separator}
-        //  \p{gc=Paragraph_Separator}]
-        public boolean is(int ch) {
-            return Character.getType(ch) == Character.SPACE_SEPARATOR ||
-                   ch == 0x9; // \N{HT}
-        }
-    },
-
-    GRAPH {
-        // [^
-        //  \p{space}
-        //  \p{gc=Control}
-        //  \p{gc=Surrogate}
-        //  \p{gc=Unassigned}]
-        public boolean is(int ch) {
-            return ((((1 << Character.SPACE_SEPARATOR) |
-                      (1 << Character.LINE_SEPARATOR) |
-                      (1 << Character.PARAGRAPH_SEPARATOR) |
-                      (1 << Character.CONTROL) |
-                      (1 << Character.SURROGATE) |
-                      (1 << Character.UNASSIGNED)) >> Character.getType(ch)) & 1)
-                   == 0;
-        }
-    },
-
-    PRINT {
-        // \p{graph}
-        // \p{blank}
-        // -- \p{cntrl}
-        public boolean is(int ch) {
-            return (GRAPH.is(ch) || BLANK.is(ch)) && !CONTROL.is(ch);
-        }
-    },
-
-    WORD {
-        //  \p{alpha}
-        //  \p{gc=Mark}
-        //  \p{digit}
-        //  \p{gc=Connector_Punctuation}
-        //  \p{Join_Control}    200C..200D
-
-        public boolean is(int ch) {
-            return ALPHABETIC.is(ch) ||
-                   ((((1 << Character.NON_SPACING_MARK) |
-                      (1 << Character.ENCLOSING_MARK) |
-                      (1 << Character.COMBINING_SPACING_MARK) |
-                      (1 << Character.DECIMAL_DIGIT_NUMBER) |
-                      (1 << Character.CONNECTOR_PUNCTUATION)) >> Character.getType(ch)) & 1)
-                   != 0 ||
-                   JOIN_CONTROL.is(ch);
-        }
-    },
-
-    JOIN_CONTROL {
-        //  200C..200D    PropList.txt:Join_Control
-        public boolean is(int ch) {
-           return (ch == 0x200C || ch == 0x200D);
-        }
-    };
-
-    private static final HashMap<String, String> posix = new HashMap<>();
-    private static final HashMap<String, String> aliases = new HashMap<>();
-    static {
-        posix.put("ALPHA", "ALPHABETIC");
-        posix.put("LOWER", "LOWERCASE");
-        posix.put("UPPER", "UPPERCASE");
-        posix.put("SPACE", "WHITE_SPACE");
-        posix.put("PUNCT", "PUNCTUATION");
-        posix.put("XDIGIT","HEX_DIGIT");
-        posix.put("ALNUM", "ALNUM");
-        posix.put("CNTRL", "CONTROL");
-        posix.put("DIGIT", "DIGIT");
-        posix.put("BLANK", "BLANK");
-        posix.put("GRAPH", "GRAPH");
-        posix.put("PRINT", "PRINT");
-
-        aliases.put("WHITESPACE", "WHITE_SPACE");
-        aliases.put("HEXDIGIT","HEX_DIGIT");
-        aliases.put("NONCHARACTERCODEPOINT", "NONCHARACTER_CODE_POINT");
-        aliases.put("JOINCONTROL", "JOIN_CONTROL");
-    }
-
-    public static UnicodeProp forName(String propName) {
-        propName = propName.toUpperCase(Locale.ENGLISH);
-        String alias = aliases.get(propName);
-        if (alias != null)
-            propName = alias;
-        try {
-            return valueOf (propName);
-        } catch (IllegalArgumentException x) {}
-        return null;
-    }
-
-    public static UnicodeProp forPOSIXName(String propName) {
-        propName = posix.get(propName.toUpperCase(Locale.ENGLISH));
-        if (propName == null)
-            return null;
-        return valueOf (propName);
-    }
-
-    public abstract boolean is(int ch);
-}
--- a/jdk/src/java.base/share/classes/javax/security/auth/callback/UnsupportedCallbackException.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/javax/security/auth/callback/UnsupportedCallbackException.java	Thu May 12 11:03:07 2016 -0700
@@ -40,7 +40,7 @@
     private Callback callback;
 
     /**
-     * Constructs a {@code UnsupportedCallbackException}
+     * Constructs an {@code UnsupportedCallbackException}
      * with no detail message.
      *
      * @param callback the unrecognized {@code Callback}.
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java	Thu May 12 11:03:07 2016 -0700
@@ -35,4 +35,9 @@
      * Returns the name for the given MemberName
      */
     String getName(Object mname);
+
+    /**
+     * Returns {@code true} if the given MemberName is a native method
+     */
+    boolean isNative(Object mname);
 }
--- a/jdk/src/java.base/share/classes/sun/net/ftp/FtpClient.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/sun/net/ftp/FtpClient.java	Thu May 12 11:03:07 2016 -0700
@@ -784,7 +784,7 @@
      *
      * @param path the pathname of the directory to list or {@code null}
      *        for the current working directoty.
-     * @return a {@code Iterator} of files or {@code null} if the
+     * @return an {@code Iterator} of files or {@code null} if the
      *         command failed.
      * @throws IOException if an error occurred during the transmission
      * @see #setDirParser(FtpDirParser)
--- a/jdk/src/java.base/share/classes/sun/security/provider/AbstractDrbg.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/sun/security/provider/AbstractDrbg.java	Thu May 12 11:03:07 2016 -0700
@@ -51,12 +51,9 @@
  * configuration is eagerly called to set up parameters, and instantiation
  * is lazily called only when nextBytes or reseed is called.
  * <p>
- * Synchronized keyword should be added to all externally callable engine
- * methods including {@link #engineReseed}, {@link #engineSetSeed}, and
- * {@link #engineNextBytes} (but not {@link #engineGenerateSeed}).
- * Internal methods like {@link #configure} and {@link #instantiateAlgorithm}
- * are not synchronized. They will either be called in a constructor or
- * in another synchronized method.
+ * SecureRandom methods like reseed and nextBytes are not thread-safe.
+ * An implementation is required to protect shared access to instantiate states
+ * (instantiated, nonce) and DRBG states (v, c, key, reseedCounter).
  */
 public abstract class AbstractDrbg extends SecureRandomSpi {
 
@@ -78,8 +75,10 @@
      * Reseed counter of a DRBG instance. A mechanism should increment it
      * after each random bits generation and reset it in reseed. A mechanism
      * does <em>not</em> need to compare it to {@link #reseedInterval}.
+     *
+     * Volatile, will be used in a double checked locking.
      */
-    protected transient int reseedCounter = 0;
+    protected transient volatile int reseedCounter = 0;
 
     // Mech features. If not same as below, must be redefined in constructor.
 
@@ -268,10 +267,9 @@
      * {@code DEFAULT_STRENGTH} is 128) for HashDRBG:
      * <pre>
      * requested             effective
-     * (SHA-1, -1)           (SHA-1,128)
-     * (SHA-1, 112)          (SHA-1,112)
-     * (SHA-1, 192)          IAE
+     * (SHA-224, 256)        IAE
      * (SHA-256, -1)         (SHA-256,128)
+     * (SHA-256, 112)        (SHA-256,112)
      * (SHA-256, 128)        (SHA-256,128)
      * (SHA-3, -1)           IAE
      * (null, -1)            (SHA-256,128)
@@ -383,9 +381,14 @@
             instantiateIfNecessary(null);
 
             // Step 7: Auto reseed
+            // Double checked locking, safe because reseedCounter is volatile
             if (reseedCounter > reseedInterval || pr) {
-                reseedAlgorithm(getEntropyInput(pr), ai);
-                ai = null;
+                synchronized (this) {
+                    if (reseedCounter > reseedInterval || pr) {
+                        reseedAlgorithm(getEntropyInput(pr), ai);
+                        ai = null;
+                    }
+                }
             }
 
             // Step 8, 10: Generate_algorithm
@@ -615,8 +618,7 @@
      * @throws IllegalArgumentException if {@code params} is
      *         inappropriate for this SecureRandom.
      */
-    protected final synchronized void configure(
-            SecureRandomParameters params) {
+    protected final void configure(SecureRandomParameters params) {
         if (debug != null) {
             debug.println(this, "configure " + this + " with " + params);
         }
--- a/jdk/src/java.base/share/classes/sun/security/provider/AbstractHashDrbg.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/sun/security/provider/AbstractHashDrbg.java	Thu May 12 11:03:07 2016 -0700
@@ -39,8 +39,6 @@
 
     private static int alg2strength(String algorithm) {
         switch (algorithm.toUpperCase(Locale.ROOT)) {
-            case "SHA-1":
-                return 128;
             case "SHA-224":
             case "SHA-512/224":
                 return 192;
@@ -82,10 +80,6 @@
             this.securityStrength = tryStrength;
         }
         switch (algorithm.toUpperCase(Locale.ROOT)) {
-            case "SHA-1":
-                this.seedLen = 440 / 8;
-                this.outLen = 160 / 8;
-                break;
             case "SHA-224":
             case "SHA-512/224":
                 this.seedLen = 440 / 8;
--- a/jdk/src/java.base/share/classes/sun/security/provider/CtrDrbg.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/sun/security/provider/CtrDrbg.java	Thu May 12 11:03:07 2016 -0700
@@ -27,7 +27,6 @@
 
 import javax.crypto.Cipher;
 import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
 import javax.crypto.spec.SecretKeySpec;
 import java.io.IOException;
 import java.security.*;
@@ -68,11 +67,6 @@
 
     private static int alg2strength(String algorithm) {
         switch (algorithm.toUpperCase(Locale.ROOT)) {
-            case "TDEA":
-            case "3KEYTDEA":
-            case "3 KEY TDEA":
-            case "DESEDE":
-                return 112;
             case "AES-128":
                 return 128;
             case "AES-192":
@@ -120,16 +114,6 @@
             this.securityStrength = tryStrength;
         }
         switch (algorithm.toUpperCase(Locale.ROOT)) {
-            case "TDEA":
-            case "3KEYTDEA":
-            case "3 KEY TDEA":
-            case "DESEDE":
-                algorithm = "DESede";
-                this.keyAlg = "DESede";
-                this.cipherAlg = "DESede/ECB/NoPadding";
-                this.blockLen = 64 / 8;
-                this.keyLen = 168 / 8;
-                break;
             case "AES-128":
             case "AES-192":
             case "AES-256":
@@ -224,7 +208,7 @@
                 // Step 2.1. Increment
                 addOne(v, ctrLen);
                 // Step 2.2. Block_Encrypt
-                cipher.init(Cipher.ENCRYPT_MODE, getKey(keyAlg, k));
+                cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(k, keyAlg));
                 // Step 2.3. Encrypt into right position, no need to cat
                 cipher.doFinal(v, 0, blockLen, temp, i * blockLen);
             }
@@ -316,7 +300,7 @@
 
         for (int i = 0; i * blockLen < seedLen; i++) {
             try {
-                cipher.init(Cipher.ENCRYPT_MODE, getKey(keyAlg, k));
+                cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(k, keyAlg));
                 int tailLen = temp.length - blockLen*i;
                 if (tailLen > blockLen) {
                     tailLen = blockLen;
@@ -340,7 +324,7 @@
                 inputBlock[j] ^= chain[j];
             }
             try {
-                cipher.init(Cipher.ENCRYPT_MODE, getKey(keyAlg, k));
+                cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(k, keyAlg));
                 chain = cipher.doFinal(inputBlock);
             } catch (GeneralSecurityException e) {
                 throw new InternalError(e);
@@ -350,7 +334,7 @@
     }
 
     @Override
-    protected void reseedAlgorithm(
+    protected synchronized void reseedAlgorithm(
             byte[] ei,
             byte[] additionalInput) {
         if (usedf) {
@@ -456,7 +440,7 @@
             addOne(v, ctrLen);
             try {
                 // Step 4.2. Encrypt
-                cipher.init(Cipher.ENCRYPT_MODE, getKey(keyAlg, k));
+                cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(k, keyAlg));
                 byte[] out = cipher.doFinal(v);
 
                 // Step 4.3 and 5. Cat bytes and leftmost
@@ -479,43 +463,6 @@
         // Step 8. Return
     }
 
-    private static void des7to8(
-            byte[] key56, int off56, byte[] key64, int off64) {
-        key64[off64 + 0] = (byte)
-                (key56[off56 + 0] & 0xFE); // << 0
-        key64[off64 + 1] = (byte)
-                ((key56[off56 + 0] << 7) | ((key56[off56 + 1] & 0xFF) >>> 1));
-        key64[off64 + 2] = (byte)
-                ((key56[off56 + 1] << 6) | ((key56[off56 + 2] & 0xFF) >>> 2));
-        key64[off64 + 3] = (byte)
-                ((key56[off56 + 2] << 5) | ((key56[off56 + 3] & 0xFF) >>> 3));
-        key64[off64 + 4] = (byte)
-                ((key56[off56 + 3] << 4) | ((key56[off56 + 4] & 0xFF) >>> 4));
-        key64[off64 + 5] = (byte)
-                ((key56[off56 + 4] << 3) | ((key56[off56 + 5] & 0xFF) >>> 5));
-        key64[off64 + 6] = (byte)
-                ((key56[off56 + 5] << 2) | ((key56[off56 + 6] & 0xFF) >>> 6));
-        key64[off64 + 7] = (byte)
-                (key56[off56 + 6] << 1);
-
-        for (int i = 0; i < 8; i++) {
-            // if even # bits, make uneven, XOR with 1 (uneven & 1)
-            // for uneven # bits, make even, XOR with 0 (even & 1)
-            key64[off64 + i] ^= Integer.bitCount(key64[off64 + i] ^ 1) & 1;
-        }
-    }
-
-    private static SecretKey getKey(String keyAlg, byte[] k) {
-        if (keyAlg.equals("DESede")) {
-            byte[] k2 = new byte[24];
-            des7to8(k, 0, k2, 0);
-            des7to8(k, 7, k2, 8);
-            des7to8(k, 14, k2, 16);
-            k = k2;
-        }
-        return new SecretKeySpec(k, keyAlg);
-    }
-
     private void readObject(java.io.ObjectInputStream s)
             throws IOException, ClassNotFoundException {
         s.defaultReadObject ();
--- a/jdk/src/java.base/share/classes/sun/security/provider/HashDrbg.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/sun/security/provider/HashDrbg.java	Thu May 12 11:03:07 2016 -0700
@@ -115,7 +115,7 @@
 
     // This method is used by both instantiation and reseeding.
     @Override
-    protected final void hashReseedInternal(byte[] input) {
+    protected final synchronized void hashReseedInternal(byte[] input) {
 
         // 800-90Ar1 10.1.1.2: Instantiate Process.
         // 800-90Ar1 10.1.1.3: Reseed Process.
--- a/jdk/src/java.base/share/classes/sun/security/provider/HmacDrbg.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/sun/security/provider/HmacDrbg.java	Thu May 12 11:03:07 2016 -0700
@@ -115,7 +115,7 @@
 
     // This method is used by both instantiation and reseeding.
     @Override
-    protected final void hashReseedInternal(byte[] input) {
+    protected final synchronized void hashReseedInternal(byte[] input) {
 
         // 800-90Ar1 10.1.2.3: Instantiate Process.
         // 800-90Ar1 10.1.2.4: Reseed Process.
--- a/jdk/src/java.base/share/classes/sun/security/provider/SecureRandom.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/sun/security/provider/SecureRandom.java	Thu May 12 11:03:07 2016 -0700
@@ -156,6 +156,7 @@
             }
         }
         state = digest.digest(seed);
+        remCount = 0;
     }
 
     private static void updateState(byte[] state, byte[] output) {
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSPNonceExtension.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSPNonceExtension.java	Thu May 12 11:03:07 2016 -0700
@@ -51,7 +51,7 @@
     private byte[] nonceData = null;
 
     /**
-     * Create a {@code OCSPNonceExtension} by providing the nonce length.
+     * Create an {@code OCSPNonceExtension} by providing the nonce length.
      * The criticality is set to false, and the OID for the extension will
      * be the value defined by "id-pkix-ocsp-nonce" from RFC 6960.
      *
@@ -66,7 +66,7 @@
     }
 
     /**
-     * Create a {@code OCSPNonceExtension} by providing the nonce length and
+     * Create an {@code OCSPNonceExtension} by providing the nonce length and
      * criticality setting.  The OID for the extension will
      * be the value defined by "id-pkix-ocsp-nonce" from RFC 6960.
      *
@@ -96,7 +96,7 @@
     }
 
     /**
-     * Create a {@code OCSPNonceExtension} by providing a nonce value.
+     * Create an {@code OCSPNonceExtension} by providing a nonce value.
      * The criticality is set to false, and the OID for the extension will
      * be the value defined by "id-pkix-ocsp-nonce" from RFC 6960.
      *
@@ -114,7 +114,7 @@
     }
 
     /**
-     * Create a {@code OCSPNonceExtension} by providing a nonce value and
+     * Create an {@code OCSPNonceExtension} by providing a nonce value and
      * criticality setting.  The OID for the extension will
      * be the value defined by "id-pkix-ocsp-nonce" from RFC 6960.
      *
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketInputRecord.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketInputRecord.java	Thu May 12 11:03:07 2016 -0700
@@ -123,7 +123,7 @@
                  */
                 //
                 // Short header is using here.  We reverse the code here
-                // in case it it used in the future.
+                // in case it is used in the future.
                 //
                 // int mask = (isShort ? 0x7F : 0x3F);
                 // len = ((byteZero & mask) << 8) +
--- a/jdk/src/java.base/share/conf/security/java.security	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/share/conf/security/java.security	Thu May 12 11:03:07 2016 -0700
@@ -206,16 +206,15 @@
 #     "Hash_DRBG" | "HMAC_DRBG" | "CTR_DRBG"
 #
 #   // The DRBG algorithm name. The "SHA-***" names are for Hash_DRBG and
-#   // HMAC_DRBG, default "SHA-256". "3KeyTDEA" and "AES-***" names are for
-#   // CTR_DRBG, default "AES-128" when using the limited cryptographic
-#   // or "AES-256" when using the unlimited.
+#   // HMAC_DRBG, default "SHA-256". The "AES-***" names are for CTR_DRBG,
+#   // default "AES-128" when using the limited cryptographic or "AES-256"
+#   // when using the unlimited.
 #   algorithm_name:
-#     "SHA-1" | "SHA-224" | "SHA-512/224" | "SHA-256" |
+#     "SHA-224" | "SHA-512/224" | "SHA-256" |
 #     "SHA-512/256" | "SHA-384" | "SHA-512" |
-#     "3KeyTDEA" | "AES-128" | "AES-192" | "AES-256"
+#     "AES-128" | "AES-192" | "AES-256"
 #
-#   // Security strength requested. Default "128", or "112"
-#   // if mech_name is CTR_DRBG and algorithm_name is "3KeyTDEA"
+#   // Security strength requested. Default "128"
 #   strength:
 #     "112" | "128" | "192" | "256"
 #
@@ -234,7 +233,7 @@
 #     "use_df" | "no_df"
 #
 # Examples,
-#   securerandom.drbg.config=Hash_DRBG,SHA-1,112,none
+#   securerandom.drbg.config=Hash_DRBG,SHA-224,112,none
 #   securerandom.drbg.config=CTR_DRBG,AES-256,192,pr_and_reseed,use_df
 #
 # The default value is an empty string, which is equivalent to
--- a/jdk/src/java.base/unix/classes/sun/security/provider/NativePRNG.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/unix/classes/sun/security/provider/NativePRNG.java	Thu May 12 11:03:07 2016 -0700
@@ -469,7 +469,8 @@
                     try {
                         seedOut.write(seed);
                     } catch (IOException e) {
-                        throw new ProviderException("setSeed() failed", e);
+                        // Ignored. On Mac OS X, /dev/urandom can be opened
+                        // for write, but actual write is not permitted.
                     }
                 }
                 getMixRandom().engineSetSeed(seed);
--- a/jdk/src/java.base/unix/native/libnet/NetworkInterface.c	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.base/unix/native/libnet/NetworkInterface.c	Thu May 12 11:03:07 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2014, 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
@@ -23,7 +23,6 @@
  * questions.
  */
 
-
 #include <errno.h>
 #include <strings.h>
 #if defined(_ALLBSD_SOURCE) && defined(__OpenBSD__)
@@ -38,14 +37,14 @@
 #include <net/if.h>
 #include <net/if_arp.h>
 
-#ifdef __solaris__
+#if defined(__solaris__)
 #include <sys/dlpi.h>
 #include <fcntl.h>
 #include <stropts.h>
 #include <sys/sockio.h>
 #endif
 
-#ifdef __linux__
+#if defined(__linux__)
 #include <sys/ioctl.h>
 #include <bits/ioctls.h>
 #include <sys/utsname.h>
@@ -59,10 +58,6 @@
 #include <sys/kinfo.h>
 #endif
 
-#ifdef __linux__
-#define _PATH_PROCNET_IFINET6           "/proc/net/if_inet6"
-#endif
-
 #if defined(_ALLBSD_SOURCE)
 #include <sys/param.h>
 #include <sys/ioctl.h>
@@ -80,6 +75,10 @@
 #include "jni_util.h"
 #include "net_util.h"
 
+#if defined(__linux__)
+#define _PATH_PROCNET_IFINET6 "/proc/net/if_inet6"
+#endif
+
 typedef struct _netaddr  {
     struct sockaddr *addr;
     struct sockaddr *brdcast;
@@ -135,29 +134,32 @@
 static netif  *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs);
 #endif
 
-static netif  *addif(JNIEnv *env, int sock, const char * if_name, netif *ifs, struct sockaddr* ifr_addrP, int family, short prefix);
+static netif  *addif(JNIEnv *env, int sock, const char *if_name, netif *ifs,
+                     struct sockaddr *ifr_addrP, int family, short prefix);
 static void    freeif(netif *ifs);
 
 static int     openSocket(JNIEnv *env, int proto);
 static int     openSocketWithFallback(JNIEnv *env, const char *ifname);
 
 
-static struct  sockaddr *getBroadcast(JNIEnv *env, int sock, const char *name, struct sockaddr *brdcast_store);
+static struct  sockaddr *getBroadcast(JNIEnv *env, int sock, const char *name,
+                                      struct sockaddr *brdcast_store);
 static short   getSubnet(JNIEnv *env, int sock, const char *ifname);
 static int     getIndex(int sock, const char *ifname);
 
 static int     getFlags(int sock, const char *ifname, int *flags);
-static int     getMacAddress(JNIEnv *env, int sock,  const char* ifname, const struct in_addr* addr, unsigned char *buf);
+static int     getMacAddress(JNIEnv *env, int sock,  const char *ifname,
+                             const struct in_addr *addr, unsigned char *buf);
 static int     getMTU(JNIEnv *env, int sock, const char *ifname);
 
 
-
-#ifdef __solaris__
-static netif *enumIPvXInterfaces(JNIEnv *env, int sock, netif *ifs, int family);
-static int    getMacFromDevice(JNIEnv *env, const char* ifname, unsigned char* retbuf);
+#if defined(__solaris__)
+static netif  *enumIPvXInterfaces(JNIEnv *env, int sock, netif *ifs, int family);
+static int     getMacFromDevice(JNIEnv *env, const char *ifname,
+                                unsigned char *retbuf);
 
 #ifndef SIOCGLIFHWADDR
-#define SIOCGLIFHWADDR  _IOWR('i', 192, struct lifreq)
+#define SIOCGLIFHWADDR _IOWR('i', 192, struct lifreq)
 #endif
 
 #endif
@@ -169,27 +171,33 @@
  * Method:    init
  * Signature: ()V
  */
-JNIEXPORT void JNICALL
-Java_java_net_NetworkInterface_init(JNIEnv *env, jclass cls) {
-    ni_class = (*env)->FindClass(env,"java/net/NetworkInterface");
+JNIEXPORT void JNICALL Java_java_net_NetworkInterface_init
+  (JNIEnv *env, jclass cls)
+{
+    ni_class = (*env)->FindClass(env, "java/net/NetworkInterface");
     CHECK_NULL(ni_class);
     ni_class = (*env)->NewGlobalRef(env, ni_class);
     CHECK_NULL(ni_class);
-    ni_nameID = (*env)->GetFieldID(env, ni_class,"name", "Ljava/lang/String;");
+    ni_nameID = (*env)->GetFieldID(env, ni_class, "name", "Ljava/lang/String;");
     CHECK_NULL(ni_nameID);
     ni_indexID = (*env)->GetFieldID(env, ni_class, "index", "I");
     CHECK_NULL(ni_indexID);
-    ni_addrsID = (*env)->GetFieldID(env, ni_class, "addrs", "[Ljava/net/InetAddress;");
+    ni_addrsID = (*env)->GetFieldID(env, ni_class, "addrs",
+                                    "[Ljava/net/InetAddress;");
     CHECK_NULL(ni_addrsID);
-    ni_bindsID = (*env)->GetFieldID(env, ni_class, "bindings", "[Ljava/net/InterfaceAddress;");
+    ni_bindsID = (*env)->GetFieldID(env, ni_class, "bindings",
+                                    "[Ljava/net/InterfaceAddress;");
     CHECK_NULL(ni_bindsID);
-    ni_descID = (*env)->GetFieldID(env, ni_class, "displayName", "Ljava/lang/String;");
+    ni_descID = (*env)->GetFieldID(env, ni_class, "displayName",
+                                   "Ljava/lang/String;");
     CHECK_NULL(ni_descID);
     ni_virutalID = (*env)->GetFieldID(env, ni_class, "virtual", "Z");
     CHECK_NULL(ni_virutalID);
-    ni_childsID = (*env)->GetFieldID(env, ni_class, "childs", "[Ljava/net/NetworkInterface;");
+    ni_childsID = (*env)->GetFieldID(env, ni_class, "childs",
+                                     "[Ljava/net/NetworkInterface;");
     CHECK_NULL(ni_childsID);
-    ni_parentID = (*env)->GetFieldID(env, ni_class, "parent", "Ljava/net/NetworkInterface;");
+    ni_parentID = (*env)->GetFieldID(env, ni_class, "parent",
+                                     "Ljava/net/NetworkInterface;");
     CHECK_NULL(ni_parentID);
     ni_ctrID = (*env)->GetMethodID(env, ni_class, "<init>", "()V");
     CHECK_NULL(ni_ctrID);
@@ -199,27 +207,28 @@
     CHECK_NULL(ni_ibcls);
     ni_ibctrID = (*env)->GetMethodID(env, ni_ibcls, "<init>", "()V");
     CHECK_NULL(ni_ibctrID);
-    ni_ibaddressID = (*env)->GetFieldID(env, ni_ibcls, "address", "Ljava/net/InetAddress;");
+    ni_ibaddressID = (*env)->GetFieldID(env, ni_ibcls, "address",
+                                        "Ljava/net/InetAddress;");
     CHECK_NULL(ni_ibaddressID);
-    ni_ib4broadcastID = (*env)->GetFieldID(env, ni_ibcls, "broadcast", "Ljava/net/Inet4Address;");
+    ni_ib4broadcastID = (*env)->GetFieldID(env, ni_ibcls, "broadcast",
+                                           "Ljava/net/Inet4Address;");
     CHECK_NULL(ni_ib4broadcastID);
     ni_ib4maskID = (*env)->GetFieldID(env, ni_ibcls, "maskLength", "S");
     CHECK_NULL(ni_ib4maskID);
-    ni_defaultIndexID = (*env)->GetStaticFieldID(env, ni_class, "defaultIndex", "I");
+    ni_defaultIndexID = (*env)->GetStaticFieldID(env, ni_class, "defaultIndex",
+                                                 "I");
     CHECK_NULL(ni_defaultIndexID);
-
     initInetAddressIDs(env);
 }
 
-
 /*
  * Class:     java_net_NetworkInterface
  * Method:    getByName0
  * Signature: (Ljava/lang/String;)Ljava/net/NetworkInterface;
  */
 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByName0
-    (JNIEnv *env, jclass cls, jstring name) {
-
+  (JNIEnv *env, jclass cls, jstring name)
+{
     netif *ifs, *curr;
     jboolean isCopy;
     const char* name_utf;
@@ -236,9 +245,8 @@
            JNU_ThrowOutOfMemoryError(env, NULL);
        return NULL;
     }
-    /*
-     * Search the list of interface based on name
-     */
+
+    // Search the list of interface based on name
     curr = ifs;
     while (curr != NULL) {
         if (strcmp(name_utf, curr->name) == 0) {
@@ -247,27 +255,26 @@
         curr = curr->next;
     }
 
-    /* if found create a NetworkInterface */
+    // if found create a NetworkInterface
     if (curr != NULL) {;
         obj = createNetworkInterface(env, curr);
     }
 
-    /* release the UTF string and interface list */
+    // release the UTF string and interface list
     (*env)->ReleaseStringUTFChars(env, name, name_utf);
     freeif(ifs);
 
     return obj;
 }
 
-
 /*
  * Class:     java_net_NetworkInterface
  * Method:    getByIndex0
  * Signature: (Ljava/lang/String;)Ljava/net/NetworkInterface;
  */
 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByIndex0
-    (JNIEnv *env, jclass cls, jint index) {
-
+  (JNIEnv *env, jclass cls, jint index)
+{
     netif *ifs, *curr;
     jobject obj = NULL;
 
@@ -279,9 +286,7 @@
         return NULL;
     }
 
-    /*
-     * Search the list of interface based on index
-     */
+    // Search the list of interface based on index
     curr = ifs;
     while (curr != NULL) {
         if (index == curr->index) {
@@ -290,7 +295,7 @@
         curr = curr->next;
     }
 
-    /* if found create a NetworkInterface */
+    // if found create a NetworkInterface
     if (curr != NULL) {;
         obj = createNetworkInterface(env, curr);
     }
@@ -305,8 +310,8 @@
  * Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface;
  */
 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0
-    (JNIEnv *env, jclass cls, jobject iaObj) {
-
+  (JNIEnv *env, jclass cls, jobject iaObj)
+{
     netif *ifs, *curr;
 
 #ifdef AF_INET6
@@ -327,14 +332,13 @@
     while (curr != NULL) {
         netaddr *addrP = curr->addr;
 
-        /*
-         * Iterate through each address on the interface
-         */
+        // Iterate through each address on the interface
         while (addrP != NULL) {
 
             if (family == addrP->family) {
                 if (family == AF_INET) {
-                    int address1 = htonl(((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr);
+                    int address1 = htonl(
+                        ((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr);
                     int address2 = getInetAddress_addr(env, iaObj);
 
                     if (address1 == address2) {
@@ -345,7 +349,8 @@
 
 #ifdef AF_INET6
                 if (family == AF_INET6) {
-                    jbyte *bytes = (jbyte *)&(((struct sockaddr_in6*)addrP->addr)->sin6_addr);
+                    jbyte *bytes = (jbyte *)&(
+                        ((struct sockaddr_in6*)addrP->addr)->sin6_addr);
                     jbyte caddr[16];
                     int i;
                     getInet6Address_ipaddress(env, iaObj, (char *)caddr);
@@ -362,7 +367,6 @@
                     }
                 }
 #endif
-
             }
 
             if (match) {
@@ -377,7 +381,7 @@
         curr = curr->next;
     }
 
-    /* if found create a NetworkInterface */
+    // if found create a NetworkInterface
     if (match) {;
         obj = createNetworkInterface(env, curr);
     }
@@ -386,15 +390,14 @@
     return obj;
 }
 
-
 /*
  * Class:     java_net_NetworkInterface
  * Method:    getAll
  * Signature: ()[Ljava/net/NetworkInterface;
  */
 JNIEXPORT jobjectArray JNICALL Java_java_net_NetworkInterface_getAll
-    (JNIEnv *env, jclass cls) {
-
+  (JNIEnv *env, jclass cls)
+{
     netif *ifs, *curr;
     jobjectArray netIFArr;
     jint arr_index, ifCount;
@@ -404,7 +407,7 @@
         return NULL;
     }
 
-    /* count the interface */
+    // count the interface
     ifCount = 0;
     curr = ifs;
     while (curr != NULL) {
@@ -412,17 +415,15 @@
         curr = curr->next;
     }
 
-    /* allocate a NetworkInterface array */
+    // allocate a NetworkInterface array
     netIFArr = (*env)->NewObjectArray(env, ifCount, cls, NULL);
     if (netIFArr == NULL) {
         freeif(ifs);
         return NULL;
     }
 
-    /*
-     * Iterate through the interfaces, create a NetworkInterface instance
-     * for each array element and populate the object.
-     */
+    // Iterate through the interfaces, create a NetworkInterface instance
+    // for each array element and populate the object.
     curr = ifs;
     arr_index = 0;
     while (curr != NULL) {
@@ -434,7 +435,7 @@
             return NULL;
         }
 
-        /* put the NetworkInterface into the array */
+        // put the NetworkInterface into the array
         (*env)->SetObjectArrayElement(env, netIFArr, arr_index++, netifObj);
 
         curr = curr->next;
@@ -444,13 +445,14 @@
     return netIFArr;
 }
 
-
 /*
  * Class:     java_net_NetworkInterface
  * Method:    isUp0
  * Signature: (Ljava/lang/String;I)Z
  */
-JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isUp0(JNIEnv *env, jclass cls, jstring name, jint index) {
+JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isUp0
+  (JNIEnv *env, jclass cls, jstring name, jint index)
+{
     int ret = getFlags0(env, name);
     return ((ret & IFF_UP) && (ret & IFF_RUNNING)) ? JNI_TRUE :  JNI_FALSE;
 }
@@ -460,7 +462,9 @@
  * Method:    isP2P0
  * Signature: (Ljava/lang/String;I)Z
  */
-JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isP2P0(JNIEnv *env, jclass cls, jstring name, jint index) {
+JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isP2P0
+  (JNIEnv *env, jclass cls, jstring name, jint index)
+{
     int ret = getFlags0(env, name);
     return (ret & IFF_POINTOPOINT) ? JNI_TRUE :  JNI_FALSE;
 }
@@ -470,7 +474,9 @@
  * Method:    isLoopback0
  * Signature: (Ljava/lang/String;I)Z
  */
-JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isLoopback0(JNIEnv *env, jclass cls, jstring name, jint index) {
+JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isLoopback0
+  (JNIEnv *env, jclass cls, jstring name, jint index)
+{
     int ret = getFlags0(env, name);
     return (ret & IFF_LOOPBACK) ? JNI_TRUE :  JNI_FALSE;
 }
@@ -480,7 +486,9 @@
  * Method:    supportsMulticast0
  * Signature: (Ljava/lang/String;I)Z
  */
-JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_supportsMulticast0(JNIEnv *env, jclass cls, jstring name, jint index) {
+JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_supportsMulticast0
+  (JNIEnv *env, jclass cls, jstring name, jint index)
+{
     int ret = getFlags0(env, name);
     return (ret & IFF_MULTICAST) ? JNI_TRUE :  JNI_FALSE;
 }
@@ -490,7 +498,9 @@
  * Method:    getMacAddr0
  * Signature: ([bLjava/lang/String;I)[b
  */
-JNIEXPORT jbyteArray JNICALL Java_java_net_NetworkInterface_getMacAddr0(JNIEnv *env, jclass class, jbyteArray addrArray, jstring name, jint index) {
+JNIEXPORT jbyteArray JNICALL Java_java_net_NetworkInterface_getMacAddr0
+  (JNIEnv *env, jclass cls, jbyteArray addrArray, jstring name, jint index)
+{
     jint addr;
     jbyte caddr[4];
     struct in_addr iaddr;
@@ -507,12 +517,11 @@
            JNU_ThrowOutOfMemoryError(env, NULL);
        return NULL;
     }
-    if ((sock =openSocketWithFallback(env, name_utf)) < 0) {
+    if ((sock = openSocketWithFallback(env, name_utf)) < 0) {
        (*env)->ReleaseStringUTFChars(env, name, name_utf);
        return JNI_FALSE;
     }
 
-
     if (!IS_NULL(addrArray)) {
        (*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr);
        addr = ((caddr[0]<<24) & 0xff000000);
@@ -522,7 +531,7 @@
        iaddr.s_addr = htonl(addr);
        len = getMacAddress(env, sock, name_utf, &iaddr, mac);
     } else {
-       len = getMacAddress(env, sock, name_utf,NULL, mac);
+       len = getMacAddress(env, sock, name_utf, NULL, mac);
     }
     if (len > 0) {
        ret = (*env)->NewByteArray(env, len);
@@ -530,10 +539,10 @@
           /* we may have memory to free at the end of this */
           goto fexit;
        }
-       (*env)->SetByteArrayRegion(env, ret, 0, len, (jbyte *) (mac));
+       (*env)->SetByteArrayRegion(env, ret, 0, len, (jbyte *)(mac));
     }
  fexit:
-   /* release the UTF string and interface list */
+   // release the UTF string and interface list
    (*env)->ReleaseStringUTFChars(env, name, name_utf);
 
    close(sock);
@@ -545,8 +554,9 @@
  * Method:      getMTU0
  * Signature:   ([bLjava/lang/String;I)I
  */
-
-JNIEXPORT jint JNICALL Java_java_net_NetworkInterface_getMTU0(JNIEnv *env, jclass class, jstring name, jint index) {
+JNIEXPORT jint JNICALL Java_java_net_NetworkInterface_getMTU0
+  (JNIEnv *env, jclass cls, jstring name, jint index)
+{
     jboolean isCopy;
     int ret = -1;
     int sock;
@@ -564,7 +574,7 @@
        return ret;
     }
 
-    if ((sock =openSocketWithFallback(env, name_utf)) < 0) {
+    if ((sock = openSocketWithFallback(env, name_utf)) < 0) {
        (*env)->ReleaseStringUTFChars(env, name, name_utf);
        return JNI_FALSE;
     }
@@ -608,19 +618,17 @@
     (*env)->ReleaseStringUTFChars(env, name, name_utf);
 
     if (ret < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL  SIOCGLIFFLAGS failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGLIFFLAGS failed");
         return -1;
     }
 
     return flags;
 }
 
-
-
-
 /*
- * Create a NetworkInterface object, populate the name and index, and
- * populate the InetAddress array based on the IP addresses for this
+ * Creates a NetworkInterface object, populates the name, the index, and
+ * populates the InetAddress array based on the IP addresses for this
  * interface.
  */
 jobject createNetworkInterface(JNIEnv *env, netif *ifs) {
@@ -636,9 +644,7 @@
     netif *childP;
     jobject tmp;
 
-    /*
-     * Create a NetworkInterface object and populate it
-     */
+    // Create a NetworkInterface object and populate it
     netifObj = (*env)->NewObject(env, ni_class, ni_ctrID);
     CHECK_NULL_RETURN(netifObj, NULL);
     name = (*env)->NewStringUTF(env, ifs->name);
@@ -646,11 +652,10 @@
     (*env)->SetObjectField(env, netifObj, ni_nameID, name);
     (*env)->SetObjectField(env, netifObj, ni_descID, name);
     (*env)->SetIntField(env, netifObj, ni_indexID, ifs->index);
-    (*env)->SetBooleanField(env, netifObj, ni_virutalID, ifs->virtual ? JNI_TRUE : JNI_FALSE);
+    (*env)->SetBooleanField(env, netifObj, ni_virutalID,
+                            ifs->virtual ? JNI_TRUE : JNI_FALSE);
 
-    /*
-     * Count the number of address on this interface
-     */
+    //Count the number of address on this interface
     addr_count = 0;
     addrP = ifs->addr;
     while (addrP != NULL) {
@@ -658,9 +663,7 @@
         addrP = addrP->next;
     }
 
-    /*
-     * Create the array of InetAddresses
-     */
+    // Create the array of InetAddresses
     addrArr = (*env)->NewObjectArray(env, addr_count,  ia_class, NULL);
     if (addrArr == NULL) {
         return NULL;
@@ -680,7 +683,8 @@
         if (addrP->family == AF_INET) {
             iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
             if (iaObj) {
-                 setInetAddress_addr(env, iaObj, htonl(((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr));
+                 setInetAddress_addr(env, iaObj, htonl(
+                     ((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr));
             } else {
                 return NULL;
             }
@@ -691,7 +695,8 @@
                     jobject ia2Obj = NULL;
                     ia2Obj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
                     if (ia2Obj) {
-                       setInetAddress_addr(env, ia2Obj, htonl(((struct sockaddr_in*)addrP->brdcast)->sin_addr.s_addr));
+                       setInetAddress_addr(env, ia2Obj, htonl(
+                           ((struct sockaddr_in*)addrP->brdcast)->sin_addr.s_addr));
                        (*env)->SetObjectField(env, ibObj, ni_ib4broadcastID, ia2Obj);
                     } else {
                         return NULL;
@@ -709,7 +714,8 @@
             int scope=0;
             iaObj = (*env)->NewObject(env, ia6_class, ia6_ctrID);
             if (iaObj) {
-                jboolean ret = setInet6Address_ipaddress(env, iaObj, (char *)&(((struct sockaddr_in6*)addrP->addr)->sin6_addr));
+                jboolean ret = setInet6Address_ipaddress(env, iaObj,
+                    (char *)&(((struct sockaddr_in6*)addrP->addr)->sin6_addr));
                 if (ret == JNI_FALSE) {
                     return NULL;
                 }
@@ -738,9 +744,7 @@
         addrP = addrP->next;
     }
 
-    /*
-     * See if there is any virtual interface attached to this one.
-     */
+    // See if there is any virtual interface attached to this one.
     child_count = 0;
     childP = ifs->childs;
     while (childP) {
@@ -753,10 +757,7 @@
         return NULL;
     }
 
-    /*
-     * Create the NetworkInterface instances for the sub-interfaces as
-     * well.
-     */
+    // Create the NetworkInterface instances for the sub-interfaces as well.
     child_index = 0;
     childP = ifs->childs;
     while(childP) {
@@ -772,7 +773,7 @@
     (*env)->SetObjectField(env, netifObj, ni_bindsID, bindArr);
     (*env)->SetObjectField(env, netifObj, ni_childsID, childArr);
 
-    /* return the NetworkInterface */
+    // return the NetworkInterface
     return netifObj;
 }
 
@@ -783,10 +784,7 @@
     netif *ifs;
     int sock;
 
-    /*
-     * Enumerate IPv4 addresses
-     */
-
+    // Enumerate IPv4 addresses
     sock = openSocket(env, AF_INET);
     if (sock < 0 && (*env)->ExceptionOccurred(env)) {
         return NULL;
@@ -799,19 +797,16 @@
         return NULL;
     }
 
-    /* return partial list if an exception occurs in the middle of process ???*/
+    // return partial list if an exception occurs in the middle of process ???
 
-    /*
-     * If IPv6 is available then enumerate IPv6 addresses.
-     */
+    // If IPv6 is available then enumerate IPv6 addresses.
 #ifdef AF_INET6
 
-        /* User can disable ipv6 explicitly by -Djava.net.preferIPv4Stack=true,
-         * so we have to call ipv6_available()
-         */
+        // User can disable ipv6 explicitly by -Djava.net.preferIPv4Stack=true,
+        // so we have to call ipv6_available()
         if (ipv6_available()) {
 
-           sock =  openSocket(env, AF_INET6);
+           sock = openSocket(env, AF_INET6);
            if (sock < 0 && (*env)->ExceptionOccurred(env)) {
                freeif(ifs);
                return NULL;
@@ -831,18 +826,18 @@
     return ifs;
 }
 
-#define CHECKED_MALLOC3(_pointer,_type,_size) \
-       do{ \
-        _pointer = (_type)malloc( _size ); \
+#define CHECKED_MALLOC3(_pointer, _type, _size) \
+    do { \
+        _pointer = (_type)malloc(_size); \
         if (_pointer == NULL) { \
             JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed"); \
             return ifs; /* return untouched list */ \
         } \
-       } while(0)
+    } while(0)
 
 
 /*
- * Free an interface list (including any attached addresses)
+ * Frees an interface list (including any attached addresses)
  */
 void freeif(netif *ifs) {
     netif *currif = ifs;
@@ -854,24 +849,21 @@
             netaddr *next = addrP->next;
             free(addrP);
             addrP = next;
-         }
+        }
 
-            /*
-            * Don't forget to free the sub-interfaces.
-            */
-          if (currif->childs != NULL) {
-                freeif(currif->childs);
-          }
+        // Don't forget to free the sub-interfaces.
+        if (currif->childs != NULL) {
+            freeif(currif->childs);
+        }
 
-          ifs = currif->next;
-          free(currif);
-          currif = ifs;
+        ifs = currif->next;
+        free(currif);
+        currif = ifs;
     }
 }
 
-netif *addif(JNIEnv *env, int sock, const char * if_name,
-             netif *ifs, struct sockaddr* ifr_addrP, int family,
-             short prefix)
+netif *addif(JNIEnv *env, int sock, const char *if_name, netif *ifs,
+             struct sockaddr *ifr_addrP, int family, short prefix)
 {
     netif *currif = ifs, *parent;
     netaddr *addrP;
@@ -884,37 +876,34 @@
     char name[IFNAMSIZ], vname[IFNAMSIZ];
 #endif
 
-    char  *name_colonP;
+    char *name_colonP;
     int mask;
     int isVirtual = 0;
     int addr_size;
     int flags = 0;
 
-    /*
-     * If the interface name is a logical interface then we
-     * remove the unit number so that we have the physical
-     * interface (eg: hme0:1 -> hme0). NetworkInterface
-     * currently doesn't have any concept of physical vs.
-     * logical interfaces.
-     */
+    // If the interface name is a logical interface then we remove the unit
+    // number so that we have the physical interface (eg: hme0:1 -> hme0).
+    // NetworkInterface currently doesn't have any concept of physical vs.
+    // logical interfaces.
     strncpy(name, if_name, ifnam_size);
     name[ifnam_size - 1] = '\0';
     *vname = 0;
 
-    /*
-     * Create and populate the netaddr node. If allocation fails
-     * return an un-updated list.
-     */
-    /*Allocate for addr and brdcast at once*/
+     // Create and populate the netaddr node. If allocation fails
+     // return an un-updated list.
+
+     // Allocate for addr and brdcast at once
 
 #ifdef AF_INET6
-    addr_size = (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
+    addr_size = (family == AF_INET) ? sizeof(struct sockaddr_in)
+                                    : sizeof(struct sockaddr_in6);
 #else
     addr_size = sizeof(struct sockaddr_in);
 #endif
 
-    CHECKED_MALLOC3(addrP, netaddr *, sizeof(netaddr)+2*addr_size);
-    addrP->addr = (struct sockaddr *)( (char *) addrP+sizeof(netaddr) );
+    CHECKED_MALLOC3(addrP, netaddr *, sizeof(netaddr) + 2 * addr_size);
+    addrP->addr = (struct sockaddr *)((char *)addrP + sizeof(netaddr));
     memcpy(addrP->addr, ifr_addrP, addr_size);
 
     addrP->family = family;
@@ -923,8 +912,9 @@
     addrP->next = 0;
     if (family == AF_INET) {
        // Deal with broadcast addr & subnet mask
-       struct sockaddr * brdcast_to = (struct sockaddr *) ((char *) addrP + sizeof(netaddr) + addr_size);
-       addrP->brdcast = getBroadcast(env, sock, name,  brdcast_to );
+       struct sockaddr *brdcast_to =
+              (struct sockaddr *) ((char *)addrP + sizeof(netaddr) + addr_size);
+       addrP->brdcast = getBroadcast(env, sock, name, brdcast_to);
        if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
            return ifs;
        }
@@ -935,36 +925,28 @@
        }
      }
 
-    /**
-     * Deal with virtual interface with colon notation e.g. eth0:1
-     */
+    // Deal with virtual interface with colon notation e.g. eth0:1
     name_colonP = strchr(name, ':');
     if (name_colonP != NULL) {
-      /**
-       * This is a virtual interface. If we are able to access the parent
-       * we need to create a new entry if it doesn't exist yet *and* update
-       * the 'parent' interface with the new records.
-       */
+        // This is a virtual interface. If we are able to access the parent
+        // we need to create a new entry if it doesn't exist yet *and* update
+        // the 'parent' interface with the new records.
         *name_colonP = 0;
         if (getFlags(sock, name, &flags) < 0 || flags < 0) {
-            // failed to access parent interface do not create parent.
-            // We are a virtual interface with no parent.
-            isVirtual = 1;
-            *name_colonP = ':';
-        }
-        else{
-           // Got access to parent, so create it if necessary.
-           // Save original name to vname and truncate name by ':'
-            memcpy(vname, name, sizeof(vname) );
-            vname[name_colonP - name] = ':';
+             // failed to access parent interface do not create parent.
+             // We are a virtual interface with no parent.
+             isVirtual = 1;
+             *name_colonP = ':';
+        } else {
+             // Got access to parent, so create it if necessary.
+             // Save original name to vname and truncate name by ':'
+             memcpy(vname, name, sizeof(vname) );
+             vname[name_colonP - name] = ':';
         }
     }
 
-    /*
-     * Check if this is a "new" interface. Use the interface
-     * name for matching because index isn't supported on
-     * Solaris 2.6 & 7.
-     */
+    // Check if this is a "new" interface. Use the interface name for
+    // matching because index isn't supported on Solaris 2.6 & 7.
     while (currif != NULL) {
         if (strcmp(name, currif->name) == 0) {
             break;
@@ -972,13 +954,10 @@
         currif = currif->next;
     }
 
-    /*
-     * If "new" then create an netif structure and
-     * insert it onto the list.
-     */
+    // If "new" then create an netif structure and insert it into the list.
     if (currif == NULL) {
          CHECKED_MALLOC3(currif, netif *, sizeof(netif) + ifnam_size);
-         currif->name = (char *) currif+sizeof(netif);
+         currif->name = (char *)currif + sizeof(netif);
          strncpy(currif->name, name, ifnam_size);
          currif->name[ifnam_size - 1] = '\0';
          currif->index = getIndex(sock, name);
@@ -989,17 +968,13 @@
          ifs = currif;
     }
 
-    /*
-     * Finally insert the address on the interface
-     */
+    // Finally insert the address on the interface
     addrP->next = currif->addr;
     currif->addr = addrP;
 
     parent = currif;
 
-    /**
-     * Let's deal with the virtual interface now.
-     */
+    // Deal with the virtual interface now.
     if (vname[0]) {
         netaddr *tmpaddr;
 
@@ -1014,27 +989,29 @@
 
         if (currif == NULL) {
             CHECKED_MALLOC3(currif, netif *, sizeof(netif) + ifnam_size);
-            currif->name = (char *) currif + sizeof(netif);
+            currif->name = (char *)currif + sizeof(netif);
             strncpy(currif->name, vname, ifnam_size);
             currif->name[ifnam_size - 1] = '\0';
             currif->index = getIndex(sock, vname);
             currif->addr = NULL;
-           /* Need to duplicate the addr entry? */
+            // Need to duplicate the addr entry?
             currif->virtual = 1;
             currif->childs = NULL;
             currif->next = parent->childs;
             parent->childs = currif;
         }
 
-        CHECKED_MALLOC3(tmpaddr, netaddr *, sizeof(netaddr)+2*addr_size);
+        CHECKED_MALLOC3(tmpaddr, netaddr *, sizeof(netaddr) + 2 * addr_size);
         memcpy(tmpaddr, addrP, sizeof(netaddr));
         if (addrP->addr != NULL) {
-            tmpaddr->addr = (struct sockaddr *) ( (char*)tmpaddr + sizeof(netaddr) ) ;
+            tmpaddr->addr = (struct sockaddr *)
+                ((char*)tmpaddr + sizeof(netaddr));
             memcpy(tmpaddr->addr, addrP->addr, addr_size);
         }
 
         if (addrP->brdcast != NULL) {
-            tmpaddr->brdcast = (struct sockaddr *) ((char *) tmpaddr + sizeof(netaddr)+addr_size);
+            tmpaddr->brdcast = (struct sockaddr *)
+                ((char *)tmpaddr + sizeof(netaddr) + addr_size);
             memcpy(tmpaddr->brdcast, addrP->brdcast, addr_size);
         }
 
@@ -1045,19 +1022,18 @@
     return ifs;
 }
 
-/* Open socket for further ioct calls
- * proto is AF_INET/AF_INET6
+/*
+ * Opens a socket for further ioct calls. proto is one of AF_INET or AF_INET6.
  */
-static int  openSocket(JNIEnv *env, int proto){
+static int openSocket(JNIEnv *env, int proto) {
     int sock;
 
     if ((sock = socket(proto, SOCK_DGRAM, 0)) < 0) {
-        /*
-         * If EPROTONOSUPPORT is returned it means we don't have
-         * support  for this proto so don't throw an exception.
-         */
+        // If EPROTONOSUPPORT is returned it means we don't have
+        // support for this proto so don't throw an exception.
         if (errno != EPROTONOSUPPORT) {
-            NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "Socket creation failed");
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                         "Socket creation failed");
         }
         return -1;
     }
@@ -1068,37 +1044,38 @@
 
 /** Linux, AIX **/
 #if defined(__linux__) || defined(_AIX)
-/* Open socket for further ioct calls, try v4 socket first and
- * if it falls return v6 socket
- */
 
 #ifdef AF_INET6
+/*
+ * Opens a socket for further ioct calls. Tries AF_INET socket first and
+ * if it falls return AF_INET6 socket.
+ */
 // unused arg ifname and struct if2
-static int openSocketWithFallback(JNIEnv *env, const char *ifname){
+static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
     int sock;
     struct ifreq if2;
 
-     if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-         if (errno == EPROTONOSUPPORT){
-              if ( (sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ){
-                 NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed");
-                 return -1;
-              }
-         }
-         else{ // errno is not NOSUPPORT
-             NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV4 Socket creation failed");
-             return -1;
-         }
-   }
+    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+        if (errno == EPROTONOSUPPORT) {
+            if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
+                NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                             "IPV6 Socket creation failed");
+                return -1;
+            }
+        } else { // errno is not NOSUPPORT
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                         "IPV4 Socket creation failed");
+            return -1;
+        }
+    }
 
-     /* Linux starting from 2.6.? kernel allows ioctl call with either IPv4 or IPv6 socket regardless of type
-        of address of an interface */
-
-       return sock;
+    // Linux starting from 2.6.? kernel allows ioctl call with either IPv4 or
+    // IPv6 socket regardless of type of address of an interface.
+    return sock;
 }
 
 #else
-static int openSocketWithFallback(JNIEnv *env, const char *ifname){
+static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
     return openSocket(env,AF_INET);
 }
 #endif
@@ -1111,52 +1088,48 @@
     unsigned i;
     int siocgifconfRequest = SIOCGIFCONF;
 
-
 #if defined(__linux__)
-    /* need to do a dummy SIOCGIFCONF to determine the buffer size.
-     * SIOCGIFCOUNT doesn't work
-     */
+    // need to do a dummy SIOCGIFCONF to determine the buffer size.
+    // SIOCGIFCOUNT doesn't work
     ifc.ifc_buf = NULL;
     if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
-        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGIFCONF failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGIFCONF failed");
         return ifs;
     }
 #elif defined(_AIX)
     ifc.ifc_buf = NULL;
     if (ioctl(sock, SIOCGSIZIFCONF, &(ifc.ifc_len)) < 0) {
-        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGSIZIFCONF failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGSIZIFCONF failed");
         return ifs;
     }
 #endif /* __linux__ */
 
-    CHECKED_MALLOC3(buf,char *, ifc.ifc_len);
+    CHECKED_MALLOC3(buf, char *, ifc.ifc_len);
 
     ifc.ifc_buf = buf;
 #if defined(_AIX)
     siocgifconfRequest = CSIOCGIFCONF;
 #endif
     if (ioctl(sock, siocgifconfRequest, (char *)&ifc) < 0) {
-        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGIFCONF failed");
-        (void) free(buf);
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGIFCONF failed");
+        free(buf);
         return ifs;
     }
 
-    /*
-     * Iterate through each interface
-     */
+    // Iterate through each interface
     ifreqP = ifc.ifc_req;
-    for (i=0; i<ifc.ifc_len/sizeof (struct ifreq); i++, ifreqP++) {
+    for (i = 0; i < ifc.ifc_len / sizeof(struct ifreq); i++, ifreqP++) {
 #if defined(_AIX)
         if (ifreqP->ifr_addr.sa_family != AF_INET) continue;
 #endif
-        /*
-         * Add to the list
-         */
-        ifs = addif(env, sock, ifreqP->ifr_name, ifs, (struct sockaddr *) & (ifreqP->ifr_addr), AF_INET, 0);
+        // Add to the list
+        ifs = addif(env, sock, ifreqP->ifr_name, ifs,
+                    (struct sockaddr *)&(ifreqP->ifr_addr), AF_INET, 0);
 
-        /*
-         * If an exception occurred then free the list
-         */
+        // If an exception occurred then free the list
         if ((*env)->ExceptionOccurred(env)) {
             free(buf);
             freeif(ifs);
@@ -1164,37 +1137,37 @@
         }
     }
 
-    /*
-     * Free socket and buffer
-     */
+    // Free socket and buffer
     free(buf);
     return ifs;
 }
 
 
+#if defined(AF_INET6) && defined(__linux__)
+
 /*
- * Enumerates and returns all IPv6 interfaces on Linux
+ * Enumerates and returns all IPv6 interfaces on Linux.
  */
-
-#if defined(AF_INET6) && defined(__linux__)
 static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) {
     FILE *f;
     char addr6[40], devname[21];
     char addr6p[8][5];
-    int plen, scope, dad_status, if_idx;
+    int prefix, scope, dad_status, if_idx;
     uint8_t ipv6addr[16];
 
     if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL) {
         while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %08x %02x %02x %02x %20s\n",
-                         addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4], addr6p[5], addr6p[6], addr6p[7],
-                         &if_idx, &plen, &scope, &dad_status, devname) != EOF) {
+                      addr6p[0], addr6p[1], addr6p[2], addr6p[3],
+                      addr6p[4], addr6p[5], addr6p[6], addr6p[7],
+                      &if_idx, &prefix, &scope, &dad_status, devname) != EOF) {
 
             struct netif *ifs_ptr = NULL;
             struct netif *last_ptr = NULL;
             struct sockaddr_in6 addr;
 
             sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
-                           addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
+                    addr6p[0], addr6p[1], addr6p[2], addr6p[3],
+                    addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
             inet_pton(AF_INET6, addr6, ipv6addr);
 
             memset(&addr, 0, sizeof(struct sockaddr_in6));
@@ -1202,12 +1175,10 @@
 
             addr.sin6_scope_id = if_idx;
 
-            ifs = addif(env, sock, devname, ifs, (struct sockaddr *)&addr, AF_INET6, plen);
-
+            ifs = addif(env, sock, devname, ifs, (struct sockaddr *)&addr,
+                        AF_INET6, (short)prefix);
 
-            /*
-             * If an exception occurred then return the list as is.
-             */
+            // If an exception occurred then return the list as is.
             if ((*env)->ExceptionOccurred(env)) {
                 fclose(f);
                 return ifs;
@@ -1220,11 +1191,11 @@
 #endif
 
 
+#if defined(AF_INET6) && defined(_AIX)
+
 /*
- * Enumerates and returns all IPv6 interfaces on AIX
+ * Enumerates and returns all IPv6 interfaces on AIX.
  */
-
-#if defined(AF_INET6) && defined(_AIX)
 static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) {
     struct ifconf ifc;
     struct ifreq *ifreqP;
@@ -1234,12 +1205,12 @@
     unsigned bufsize;
     char *cp, *cplimit;
 
-    /* use SIOCGSIZIFCONF to get size for  SIOCGIFCONF */
+    // use SIOCGSIZIFCONF to get size for  SIOCGIFCONF
 
     ifc.ifc_buf = NULL;
     if (ioctl(sock, SIOCGSIZIFCONF, &(ifc.ifc_len)) < 0) {
-        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException",
-                        "ioctl SIOCGSIZIFCONF failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                    "ioctl SIOCGSIZIFCONF failed");
         return ifs;
     }
     bufsize = ifc.ifc_len;
@@ -1252,29 +1223,27 @@
     ifc.ifc_len = bufsize;
     ifc.ifc_buf = buf;
     if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
-        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException",
-                       "ioctl CSIOCGIFCONF failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl CSIOCGIFCONF failed");
         free(buf);
         return ifs;
     }
 
-    /*
-     * Iterate through each interface
-     */
+    // Iterate through each interface
     ifreqP = ifc.ifc_req;
     cp = (char *)ifc.ifc_req;
     cplimit = cp + ifc.ifc_len;
 
-    for ( ; cp < cplimit; cp += (sizeof(ifreqP->ifr_name) + MAX((ifreqP->ifr_addr).sa_len, sizeof(ifreqP->ifr_addr)))) {
+    for (; cp < cplimit;
+        cp += (sizeof(ifreqP->ifr_name) +
+               MAX((ifreqP->ifr_addr).sa_len, sizeof(ifreqP->ifr_addr))))
+    {
         ifreqP = (struct ifreq *)cp;
         struct ifreq if2;
-
         memset((char *)&if2, 0, sizeof(if2));
-        strcpy(if2.ifr_name, ifreqP->ifr_name);
+        strncpy(if2.ifr_name, ifreqP->ifr_name, sizeof(if2.ifr_name) - 1);
 
-        /*
-         * Skip interface that aren't UP
-         */
+        // Skip interface that aren't UP
         if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) >= 0) {
             if (!(if2.ifr_flags & IFF_UP)) {
                 continue;
@@ -1289,16 +1258,11 @@
             s6->sin6_scope_id = if2.ifr_site6;
         }
 
-        /*
-         * Add to the list
-         */
+        // Add to the list
         ifs = addif(env, sock, ifreqP->ifr_name, ifs,
-                    (struct sockaddr *)&(ifreqP->ifr_addr),
-                    AF_INET6, 0);
+                    (struct sockaddr *)&(ifreqP->ifr_addr), AF_INET6, 0);
 
-        /*
-         * If an exception occurred then free the list
-         */
+        // If an exception occurred then free the list
         if ((*env)->ExceptionOccurred(env)) {
             free(buf);
             freeif(ifs);
@@ -1306,24 +1270,21 @@
         }
     }
 
-    /*
-     * Free socket and buffer
-     */
+    // Free socket and buffer
     free(buf);
     return ifs;
 }
 #endif
 
 
-static int getIndex(int sock, const char *name){
-     /*
-      * Try to get the interface index
-      */
+static int getIndex(int sock, const char *name) {
+     // Try to get the interface index
 #if defined(_AIX)
     return if_nametoindex(name);
 #else
     struct ifreq if2;
-    strcpy(if2.ifr_name, name);
+    memset((char *)&if2, 0, sizeof(if2));
+    strncpy(if2.ifr_name, name, sizeof(if2.ifr_name) - 1);
 
     if (ioctl(sock, SIOCGIFINDEX, (char *)&if2) < 0) {
         return -1;
@@ -1333,38 +1294,41 @@
 #endif
 }
 
-/**
+/*
  * Returns the IPv4 broadcast address of a named interface, if it exists.
  * Returns 0 if it doesn't have one.
  */
-static struct sockaddr *getBroadcast(JNIEnv *env, int sock, const char *ifname, struct sockaddr *brdcast_store) {
-  struct sockaddr *ret = NULL;
-  struct ifreq if2;
-
-  memset((char *) &if2, 0, sizeof(if2));
-  strcpy(if2.ifr_name, ifname);
-
-  /* Let's make sure the interface does have a broadcast address */
-  if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2)  < 0) {
-      NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL  SIOCGIFFLAGS failed");
-      return ret;
-  }
+static struct sockaddr *getBroadcast
+  (JNIEnv *env, int sock, const char *ifname, struct sockaddr *brdcast_store)
+{
+    struct sockaddr *ret = NULL;
+    struct ifreq if2;
+    memset((char *)&if2, 0, sizeof(if2));
+    strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1);
 
-  if (if2.ifr_flags & IFF_BROADCAST) {
-      /* It does, let's retrieve it*/
-      if (ioctl(sock, SIOCGIFBRDADDR, (char *)&if2) < 0) {
-          NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFBRDADDR failed");
-          return ret;
-      }
+    // Let's make sure the interface does have a broadcast address.
+    if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2)  < 0) {
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGIFFLAGS failed");
+        return ret;
+    }
 
-      ret = brdcast_store;
-      memcpy(ret, &if2.ifr_broadaddr, sizeof(struct sockaddr));
-  }
+    if (if2.ifr_flags & IFF_BROADCAST) {
+        // It does, let's retrieve it
+        if (ioctl(sock, SIOCGIFBRDADDR, (char *)&if2) < 0) {
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                         "ioctl SIOCGIFBRDADDR failed");
+            return ret;
+        }
 
-  return ret;
+        ret = brdcast_store;
+        memcpy(ret, &if2.ifr_broadaddr, sizeof(struct sockaddr));
+    }
+
+    return ret;
 }
 
-/**
+/*
  * Returns the IPv4 subnet prefix length (aka subnet mask) for the named
  * interface, if it has one, otherwise return -1.
  */
@@ -1372,12 +1336,12 @@
     unsigned int mask;
     short ret;
     struct ifreq if2;
-
-    memset((char *) &if2, 0, sizeof(if2));
-    strcpy(if2.ifr_name, ifname);
+    memset((char *)&if2, 0, sizeof(if2));
+    strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1);
 
     if (ioctl(sock, SIOCGIFNETMASK, (char *)&if2) < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFNETMASK failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGIFNETMASK failed");
         return -1;
     }
 
@@ -1391,12 +1355,15 @@
     return ret;
 }
 
-/**
- * Get the Hardware address (usually MAC address) for the named interface.
- * return puts the data in buf, and returns the length, in byte, of the
+/*
+ * Gets the Hardware address (usually MAC address) for the named interface.
+ * On return puts the data in buf, and returns the length, in byte, of the
  * MAC address. Returns -1 if there is no hardware address on that interface.
  */
-static int getMacAddress(JNIEnv *env, int sock, const char* ifname, const struct in_addr* addr, unsigned char *buf) {
+static int getMacAddress
+  (JNIEnv *env, int sock, const char* ifname, const struct in_addr* addr,
+   unsigned char *buf)
+{
 #if defined (_AIX)
     int size;
     struct kinfo_ndd *nddp;
@@ -1415,7 +1382,8 @@
     nddp = (struct kinfo_ndd *)malloc(size);
 
     if (!nddp) {
-        JNU_ThrowOutOfMemoryError(env, "Network interface getMacAddress native buffer allocation failed");
+        JNU_ThrowOutOfMemoryError(env,
+            "Network interface getMacAddress native buffer allocation failed");
         return -1;
     }
 
@@ -1436,22 +1404,20 @@
     }
 
     return -1;
-
 #elif defined(__linux__)
     static struct ifreq ifr;
     int i;
-
-    strcpy(ifr.ifr_name, ifname);
+    memset((char *)&ifr, 0, sizeof(ifr));
+    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1);
     if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFHWADDR failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGIFHWADDR failed");
         return -1;
     }
 
     memcpy(buf, &ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
 
-   /*
-    * All bytes to 0 means no hardware address.
-    */
+    // All bytes to 0 means no hardware address.
 
     for (i = 0; i < IFHWADDRLEN; i++) {
         if (buf[i] != 0)
@@ -1464,17 +1430,18 @@
 
 static int getMTU(JNIEnv *env, int sock,  const char *ifname) {
     struct ifreq if2;
-    memset((char *) &if2, 0, sizeof(if2));
+    memset((char *)&if2, 0, sizeof(if2));
 
     if (ifname != NULL) {
-        strcpy(if2.ifr_name, ifname);
+        strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1);
     } else {
         JNU_ThrowNullPointerException(env, "network interface name is NULL");
         return -1;
     }
 
     if (ioctl(sock, SIOCGIFMTU, (char *)&if2) < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFMTU failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGIFMTU failed");
         return -1;
     }
 
@@ -1483,11 +1450,10 @@
 
 static int getFlags(int sock, const char *ifname, int *flags) {
   struct ifreq if2;
+  memset((char *)&if2, 0, sizeof(if2));
+  strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1);
 
-  memset((char *) &if2, 0, sizeof(if2));
-  strcpy(if2.ifr_name, ifname);
-
-  if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0){
+  if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0) {
       return -1;
   }
 
@@ -1499,53 +1465,54 @@
   return 0;
 }
 
-#endif
+#endif  /* defined(__linux__) || defined(_AIX) */
 
 /** Solaris **/
-#ifdef __solaris__
-/* Open socket for further ioct calls, try v4 socket first and
- * if it falls return v6 socket
+#if defined(__solaris__)
+
+/*
+ * Opens a socket for further ioct calls. Tries AF_INET socket first and
+ * if it falls return AF_INET6 socket.
  */
-
 #ifdef AF_INET6
-static int openSocketWithFallback(JNIEnv *env, const char *ifname){
+static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
     int sock, alreadyV6 = 0;
     struct lifreq if2;
 
-     if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-         if (errno == EPROTONOSUPPORT){
-              if ( (sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ){
-                 NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed");
-                 return -1;
-              }
+    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+        if (errno == EPROTONOSUPPORT) {
+            if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
+                NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                             "IPV6 Socket creation failed");
+                return -1;
+            }
 
-              alreadyV6=1;
-         }
-         else{ // errno is not NOSUPPORT
-             NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV4 Socket creation failed");
-             return -1;
-         }
-   }
+            alreadyV6=1;
+        } else { // errno is not NOSUPPORT
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                         "IPV4 Socket creation failed");
+            return -1;
+        }
+    }
+
 
-     /**
-      * Solaris requires that we have an IPv6 socket to query an
-      * interface without an IPv4 address - check it here.
-      * POSIX 1 require the kernel to return ENOTTY if the call is
-      * inappropriate for a device e.g. the NETMASK for a device having IPv6
-      * only address but not all devices follow the standard so
-      * fall back on any error. It's not an ecologically friendly gesture
-      * but more reliable.
-      */
+    // Solaris requires that we have an IPv6 socket to query an  interface
+    // without an IPv4 address - check it here. POSIX 1 require the kernel to
+    // return ENOTTY if the call is inappropriate for a device e.g. the NETMASK
+    // for a device having IPv6 only address but not all devices follow the
+    // standard so fall back on any error. It's not an ecologically friendly
+    // gesture but more reliable.
 
-    if (! alreadyV6 ){
-        memset((char *) &if2, 0, sizeof(if2));
-        strcpy(if2.lifr_name, ifname);
+    if (!alreadyV6) {
+        memset((char *)&if2, 0, sizeof(if2));
+        strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1);
         if (ioctl(sock, SIOCGLIFNETMASK, (char *)&if2) < 0) {
-                close(sock);
-                if ( (sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ){
-                      NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed");
-                      return -1;
-                }
+            close(sock);
+            if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
+                NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                             "IPV6 Socket creation failed");
+                return -1;
+            }
         }
     }
 
@@ -1553,18 +1520,16 @@
 }
 
 #else
-static int openSocketWithFallback(JNIEnv *env, const char *ifname){
+static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
     return openSocket(env,AF_INET);
 }
 #endif
 
 /*
- * Enumerates and returns all IPv4 interfaces
- * (linux verision)
+ * Enumerates and returns all IPv4 interfaces.
  */
-
 static netif *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs) {
-     return enumIPvXInterfaces(env,sock, ifs, AF_INET);
+    return enumIPvXInterfaces(env,sock, ifs, AF_INET);
 }
 
 #ifdef AF_INET6
@@ -1574,8 +1539,8 @@
 #endif
 
 /*
-   Enumerates and returns all interfaces on Solaris
-   use the same code for IPv4 and IPv6
+ * Enumerates and returns all interfaces on Solaris.
+ * Uses the same code for IPv4 and IPv6.
  */
 static netif *enumIPvXInterfaces(JNIEnv *env, int sock, netif *ifs, int family) {
     struct lifconf ifc;
@@ -1585,19 +1550,16 @@
     struct lifnum numifs;
     unsigned bufsize;
 
-    /*
-     * Get the interface count
-     */
+    // Get the interface count
     numifs.lifn_family = family;
     numifs.lifn_flags = 0;
     if (ioctl(sock, SIOCGLIFNUM, (char *)&numifs) < 0) {
-        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGLIFNUM failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGLIFNUM failed");
         return ifs;
     }
 
-    /*
-     *  Enumerate the interface configurations
-     */
+    //  Enumerate the interface configurations
     bufsize = numifs.lifn_count * sizeof (struct lifreq);
     CHECKED_MALLOC3(buf, char *, bufsize);
 
@@ -1606,22 +1568,19 @@
     ifc.lifc_len = bufsize;
     ifc.lifc_buf = buf;
     if (ioctl(sock, SIOCGLIFCONF, (char *)&ifc) < 0) {
-        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGLIFCONF failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGLIFCONF failed");
         free(buf);
         return ifs;
     }
 
-    /*
-     * Iterate through each interface
-     */
+    // Iterate through each interface
     ifr = ifc.lifc_req;
     for (n=0; n<numifs.lifn_count; n++, ifr++) {
         int index = -1;
         struct lifreq if2;
 
-        /*
-        * Ignore either IPv4 or IPv6 addresses
-        */
+        // Ignore either IPv4 or IPv6 addresses
         if (ifr->lifr_addr.ss_family != family) {
             continue;
         }
@@ -1633,12 +1592,12 @@
         }
 #endif
 
-        /* add to the list */
-        ifs = addif(env, sock,ifr->lifr_name, ifs, (struct sockaddr *)&(ifr->lifr_addr),family, (short) ifr->lifr_addrlen);
+        // add to the list
+        ifs = addif(env, sock,ifr->lifr_name, ifs,
+                    (struct sockaddr *)&(ifr->lifr_addr), family,
+                    (short)ifr->lifr_addrlen);
 
-        /*
-        * If an exception occurred we return immediately
-        */
+        // If an exception occurred we return immediately
         if ((*env)->ExceptionOccurred(env)) {
             free(buf);
             return ifs;
@@ -1650,13 +1609,11 @@
     return ifs;
 }
 
-static int getIndex(int sock, const char *name){
-   /*
-    * Try to get the interface index
-    * (Not supported on Solaris 2.6 or 7)
-    */
+static int getIndex(int sock, const char *name) {
+    // Try to get the interface index.  (Not supported on Solaris 2.6 or 7)
     struct lifreq if2;
-    strcpy(if2.lifr_name, name);
+    memset((char *)&if2, 0, sizeof(if2));
+    strncpy(if2.lifr_name, name, sizeof(if2.lifr_name) - 1);
 
     if (ioctl(sock, SIOCGLIFINDEX, (char *)&if2) < 0) {
         return -1;
@@ -1665,27 +1622,30 @@
     return if2.lifr_index;
 }
 
-/**
+/*
  * Returns the IPv4 broadcast address of a named interface, if it exists.
  * Returns 0 if it doesn't have one.
  */
-static struct sockaddr *getBroadcast(JNIEnv *env, int sock, const char *ifname, struct sockaddr *brdcast_store) {
+static struct sockaddr *getBroadcast
+  (JNIEnv *env, int sock, const char *ifname, struct sockaddr *brdcast_store)
+{
     struct sockaddr *ret = NULL;
     struct lifreq if2;
-
-    memset((char *) &if2, 0, sizeof(if2));
-    strcpy(if2.lifr_name, ifname);
+    memset((char *)&if2, 0, sizeof(if2));
+    strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1);
 
-    /* Let's make sure the interface does have a broadcast address */
+    // Let's make sure the interface does have a broadcast address
     if (ioctl(sock, SIOCGLIFFLAGS, (char *)&if2)  < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL  SIOCGLIFFLAGS failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGLIFFLAGS failed");
         return ret;
     }
 
     if (if2.lifr_flags & IFF_BROADCAST) {
-        /* It does, let's retrieve it*/
+        // It does, let's retrieve it
         if (ioctl(sock, SIOCGLIFBRDADDR, (char *)&if2) < 0) {
-            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGLIFBRDADDR failed");
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                         "ioctl SIOCGLIFBRDADDR failed");
             return ret;
         }
 
@@ -1696,7 +1656,7 @@
     return ret;
 }
 
-/**
+/*
  * Returns the IPv4 subnet prefix length (aka subnet mask) for the named
  * interface, if it has one, otherwise return -1.
  */
@@ -1704,12 +1664,12 @@
     unsigned int mask;
     short ret;
     struct lifreq if2;
-
-    memset((char *) &if2, 0, sizeof(if2));
-    strcpy(if2.lifr_name, ifname);
+    memset((char *)&if2, 0, sizeof(if2));
+    strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1);
 
     if (ioctl(sock, SIOCGLIFNETMASK, (char *)&if2) < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGLIFNETMASK failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGLIFNETMASK failed");
         return -1;
     }
 
@@ -1725,15 +1685,16 @@
 }
 
 
-
 #define DEV_PREFIX  "/dev/"
 
-/**
+/*
  * Solaris specific DLPI code to get hardware address from a device.
  * Unfortunately, at least up to Solaris X, you have to have special
  * privileges (i.e. be root).
  */
-static int getMacFromDevice(JNIEnv *env, const char* ifname, unsigned char* retbuf) {
+static int getMacFromDevice
+  (JNIEnv *env, const char* ifname, unsigned char* retbuf)
+{
     char style1dev[MAXPATHLEN];
     int fd;
     dl_phys_addr_req_t dlpareq;
@@ -1742,17 +1703,12 @@
     char buf[128];
     int flags = 0;
 
-   /**
-    * Device is in /dev
-    * e.g.: /dev/bge0
-    */
+    // Device is in /dev.  e.g.: /dev/bge0
     strcpy(style1dev, DEV_PREFIX);
     strcat(style1dev, ifname);
     if ((fd = open(style1dev, O_RDWR)) < 0) {
-        /*
-         * Can't open it. We probably are missing the privilege.
-         * We'll have to try something else
-         */
+         // Can't open it. We probably are missing the privilege.
+         // We'll have to try something else
          return 0;
     }
 
@@ -1763,7 +1719,8 @@
     msg.len = DL_PHYS_ADDR_REQ_SIZE;
 
     if (putmsg(fd, &msg, NULL, 0) < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "putmsg failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "putmsg failed");
         return -1;
     }
 
@@ -1773,12 +1730,14 @@
     msg.len = 0;
     msg.maxlen = sizeof (buf);
     if (getmsg(fd, &msg, NULL, &flags) < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "getmsg failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "getmsg failed");
         return -1;
     }
 
     if (msg.len < DL_PHYS_ADDR_ACK_SIZE || dlpaack->dl_primitive != DL_PHYS_ADDR_ACK) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Couldn't obtain phys addr\n");
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "Couldn't obtain phys addr\n");
         return -1;
     }
 
@@ -1786,21 +1745,23 @@
     return dlpaack->dl_addr_length;
 }
 
-/**
- * Get the Hardware address (usually MAC address) for the named interface.
- * return puts the data in buf, and returns the length, in byte, of the
+/*
+ * Gets the Hardware address (usually MAC address) for the named interface.
+ * On return puts the data in buf, and returns the length, in byte, of the
  * MAC address. Returns -1 if there is no hardware address on that interface.
  */
-static int getMacAddress(JNIEnv *env, int sock, const char *ifname,  const struct in_addr* addr, unsigned char *buf) {
+static int getMacAddress
+  (JNIEnv *env, int sock, const char *ifname, const struct in_addr* addr,
+   unsigned char *buf)
+{
     struct arpreq arpreq;
     struct sockaddr_in* sin;
     struct sockaddr_in ipAddr;
     int len, i;
     struct lifreq lif;
 
-    /* First, try the new (S11) SIOCGLIFHWADDR ioctl(). If that fails
-     * try the old way.
-     */
+    // First, try the new (S11) SIOCGLIFHWADDR ioctl(). If that fails
+    // try the old way.
     memset(&lif, 0, sizeof(lif));
     strlcpy(lif.lifr_name, ifname, sizeof(lif.lifr_name));
 
@@ -1811,18 +1772,14 @@
         return sp->sdl_alen;
     }
 
-   /**
-    * On Solaris we have to use DLPI, but it will only work if we have
-    * privileged access (i.e. root). If that fails, we try a lookup
-    * in the ARP table, which requires an IPv4 address.
-    */
+    // On Solaris we have to use DLPI, but it will only work if we have
+    // privileged access (i.e. root). If that fails, we try a lookup
+    // in the ARP table, which requires an IPv4 address.
     if ((len = getMacFromDevice(env, ifname, buf))  == 0) {
-        /*DLPI failed - trying to do arp lookup*/
+        // DLPI failed - trying to do arp lookup
 
         if (addr == NULL) {
-            /**
-             * No IPv4 address for that interface, so can't do an ARP lookup.
-             */
+             // No IPv4 address for that interface, so can't do an ARP lookup.
              return -1;
          }
 
@@ -1843,10 +1800,7 @@
          memcpy(buf, &arpreq.arp_ha.sa_data[0], len );
     }
 
-    /*
-     * All bytes to 0 means no hardware address.
-     */
-
+    // All bytes to 0 means no hardware address.
     for (i = 0; i < len; i++) {
       if (buf[i] != 0)
          return len;
@@ -1857,56 +1811,58 @@
 
 static int getMTU(JNIEnv *env, int sock,  const char *ifname) {
     struct lifreq if2;
-
-    memset((char *) &if2, 0, sizeof(if2));
-    strcpy(if2.lifr_name, ifname);
+    memset((char *)&if2, 0, sizeof(if2));
+    strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1);
 
     if (ioctl(sock, SIOCGLIFMTU, (char *)&if2) < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGLIFMTU failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                    "ioctl SIOCGLIFMTU failed");
         return -1;
     }
 
-    return  if2.lifr_mtu;
+    return if2.lifr_mtu;
+}
+
+static int getFlags(int sock, const char *ifname, int *flags) {
+    struct lifreq if2;
+    memset((char *)&if2, 0, sizeof(if2));
+    strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1);
+
+    if (ioctl(sock, SIOCGLIFFLAGS, (char *)&if2) < 0) {
+         return -1;
+    }
+
+    *flags = if2.lifr_flags;
+    return 0;
 }
 
 
-static int getFlags(int sock, const char *ifname, int *flags) {
-     struct   lifreq lifr;
-     memset((caddr_t)&lifr, 0, sizeof(lifr));
-     strcpy((caddr_t)&(lifr.lifr_name), ifname);
-
-     if (ioctl(sock, SIOCGLIFFLAGS, (char *)&lifr) < 0) {
-         return -1;
-     }
-
-     *flags = lifr.lifr_flags;
-     return 0;
-}
-
-
-#endif
+#endif  /* __solaris__ */
 
 
 /** BSD **/
 #ifdef _ALLBSD_SOURCE
-/* Open socket for further ioct calls, try v4 socket first and
- * if it falls return v6 socket
+
+/*
+ * Opens a socket for further ioct calls. Tries AF_INET socket first and
+ * if it falls return AF_INET6 socket.
  */
-
 #ifdef AF_INET6
-static int openSocketWithFallback(JNIEnv *env, const char *ifname){
+static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
     int sock;
     struct ifreq if2;
 
      if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-         if (errno == EPROTONOSUPPORT){
-              if ( (sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ){
-                 NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed");
+         if (errno == EPROTONOSUPPORT) {
+              if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
+                 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                              "IPV6 Socket creation failed");
                  return -1;
               }
          }
          else{ // errno is not NOSUPPORT
-             NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV4 Socket creation failed");
+             NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                          "IPV4 Socket creation failed");
              return -1;
          }
    }
@@ -1915,39 +1871,33 @@
 }
 
 #else
-static int openSocketWithFallback(JNIEnv *env, const char *ifname){
+static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
     return openSocket(env,AF_INET);
 }
 #endif
 
 /*
- * Enumerates and returns all IPv4 interfaces
+ * Enumerates and returns all IPv4 interfaces.
  */
 static netif *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs) {
     struct ifaddrs *ifa, *origifa;
 
     if (getifaddrs(&origifa) != 0) {
-        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException",
-                         "getifaddrs() function failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "getifaddrs() function failed");
         return ifs;
     }
 
     for (ifa = origifa; ifa != NULL; ifa = ifa->ifa_next) {
 
-        /*
-         * Skip non-AF_INET entries.
-         */
+        // Skip non-AF_INET entries.
         if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_INET)
             continue;
 
-        /*
-         * Add to the list.
-         */
+        // Add to the list.
         ifs = addif(env, sock, ifa->ifa_name, ifs, ifa->ifa_addr, AF_INET, 0);
 
-        /*
-         * If an exception occurred then free the list.
-         */
+        // If an exception occurred then free the list.
         if ((*env)->ExceptionOccurred(env)) {
             freeifaddrs(origifa);
             freeif(ifs);
@@ -1955,33 +1905,25 @@
         }
     }
 
-    /*
-     * Free socket and buffer
-     */
+    // Free socket and buffer
     freeifaddrs(origifa);
     return ifs;
 }
 
-
-/*
- * Enumerates and returns all IPv6 interfaces on Linux
- */
-
 #ifdef AF_INET6
 /*
  * Determines the prefix on BSD for IPv6 interfaces.
  */
-static
-int prefix(void *val, int size) {
+static int prefix(void *val, int size) {
     u_char *name = (u_char *)val;
-    int byte, bit, plen = 0;
+    int byte, bit, prefix = 0;
 
-    for (byte = 0; byte < size; byte++, plen += 8)
+    for (byte = 0; byte < size; byte++, prefix += 8)
         if (name[byte] != 0xff)
             break;
     if (byte == size)
-        return (plen);
-    for (bit = 7; bit != 0; bit--, plen++)
+        return prefix;
+    for (bit = 7; bit != 0; bit--, prefix++)
         if (!(name[byte] & (1 << bit)))
             break;
     for (; bit != 0; bit--)
@@ -1991,11 +1933,11 @@
     for (; byte < size; byte++)
         if (name[byte])
             return (0);
-    return (plen);
+    return prefix;
 }
 
 /*
- * Enumerates and returns all IPv6 interfaces on BSD
+ * Enumerates and returns all IPv6 interfaces on BSD.
  */
 static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) {
     struct ifaddrs *ifa, *origifa;
@@ -2003,37 +1945,36 @@
     struct in6_ifreq ifr6;
 
     if (getifaddrs(&origifa) != 0) {
-        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException",
-                         "getifaddrs() function failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "getifaddrs() function failed");
         return ifs;
     }
 
     for (ifa = origifa; ifa != NULL; ifa = ifa->ifa_next) {
 
-        /*
-         * Skip non-AF_INET6 entries.
-         */
+        // Skip non-AF_INET6 entries.
         if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_INET6)
             continue;
 
         memset(&ifr6, 0, sizeof(ifr6));
         strlcpy(ifr6.ifr_name, ifa->ifa_name, sizeof(ifr6.ifr_name));
-        memcpy(&ifr6.ifr_addr, ifa->ifa_addr, MIN(sizeof(ifr6.ifr_addr), ifa->ifa_addr->sa_len));
+        memcpy(&ifr6.ifr_addr, ifa->ifa_addr,
+               MIN(sizeof(ifr6.ifr_addr), ifa->ifa_addr->sa_len));
 
         if (ioctl(sock, SIOCGIFNETMASK_IN6, (caddr_t)&ifr6) < 0) {
-            NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException",
-                             "ioctl SIOCGIFNETMASK_IN6 failed");
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                         "ioctl SIOCGIFNETMASK_IN6 failed");
             freeifaddrs(origifa);
             freeif(ifs);
             return NULL;
         }
 
-        /* Add to the list.  */
+        // Add to the list.
         sin6 = (struct sockaddr_in6 *)&ifr6.ifr_addr;
         ifs = addif(env, sock, ifa->ifa_name, ifs, ifa->ifa_addr, AF_INET6,
-                    prefix(&sin6->sin6_addr, sizeof(struct in6_addr)));
+            (short)prefix(&sin6->sin6_addr, sizeof(struct in6_addr)));
 
-        /* If an exception occurred then free the list.  */
+        // If an exception occurred then free the list.
         if ((*env)->ExceptionOccurred(env)) {
             freeifaddrs(origifa);
             freeif(ifs);
@@ -2041,22 +1982,19 @@
         }
     }
 
-    /*
-     * Free socket and ifaddrs buffer
-     */
+    // Free socket and ifaddrs buffer
     freeifaddrs(origifa);
     return ifs;
 }
 #endif
 
-static int getIndex(int sock, const char *name){
+static int getIndex(int sock, const char *name) {
 #ifdef __FreeBSD__
-     /*
-      * Try to get the interface index
-      * (Not supported on Solaris 2.6 or 7)
-      */
+    // Try to get the interface index
+    // (Not supported on Solaris 2.6 or 7)
     struct ifreq if2;
-    strcpy(if2.ifr_name, name);
+    memset((char *)&if2, 0, sizeof(if2));
+    strncpy(if2.ifr_name, name, sizeof(if2.ifr_name) - 1);
 
     if (ioctl(sock, SIOCGIFINDEX, (char *)&if2) < 0) {
         return -1;
@@ -2064,46 +2002,47 @@
 
     return if2.ifr_index;
 #else
-    /*
-     * Try to get the interface index using BSD specific if_nametoindex
-     */
+    // Try to get the interface index using BSD specific if_nametoindex
     int index = if_nametoindex(name);
     return (index == 0) ? -1 : index;
 #endif
 }
 
-/**
+/*
  * Returns the IPv4 broadcast address of a named interface, if it exists.
  * Returns 0 if it doesn't have one.
  */
-static struct sockaddr *getBroadcast(JNIEnv *env, int sock, const char *ifname, struct sockaddr *brdcast_store) {
-  struct sockaddr *ret = NULL;
-  struct ifreq if2;
-
-  memset((char *) &if2, 0, sizeof(if2));
-  strcpy(if2.ifr_name, ifname);
-
-  /* Let's make sure the interface does have a broadcast address */
-  if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0) {
-      NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFFLAGS failed");
-      return ret;
-  }
+static struct sockaddr *getBroadcast
+  (JNIEnv *env, int sock, const char *ifname, struct sockaddr *brdcast_store)
+{
+    struct sockaddr *ret = NULL;
+    struct ifreq if2;
+    memset((char *)&if2, 0, sizeof(if2));
+    strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1);
 
-  if (if2.ifr_flags & IFF_BROADCAST) {
-      /* It does, let's retrieve it*/
-      if (ioctl(sock, SIOCGIFBRDADDR, (char *)&if2) < 0) {
-          NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFBRDADDR failed");
-          return ret;
-      }
+    // Make sure the interface does have a broadcast address
+    if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0) {
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGIFFLAGS failed");
+        return ret;
+    }
 
-      ret = brdcast_store;
-      memcpy(ret, &if2.ifr_broadaddr, sizeof(struct sockaddr));
-  }
+    if (if2.ifr_flags & IFF_BROADCAST) {
+        // It does, let's retrieve it
+        if (ioctl(sock, SIOCGIFBRDADDR, (char *)&if2) < 0) {
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                         "ioctl SIOCGIFBRDADDR failed");
+            return ret;
+        }
 
-  return ret;
+        ret = brdcast_store;
+        memcpy(ret, &if2.ifr_broadaddr, sizeof(struct sockaddr));
+    }
+
+    return ret;
 }
 
-/**
+/*
  * Returns the IPv4 subnet prefix length (aka subnet mask) for the named
  * interface, if it has one, otherwise return -1.
  */
@@ -2111,12 +2050,12 @@
     unsigned int mask;
     short ret;
     struct ifreq if2;
-
-    memset((char *) &if2, 0, sizeof(if2));
-    strcpy(if2.ifr_name, ifname);
+    memset((char *)&if2, 0, sizeof(if2));
+    strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1);
 
     if (ioctl(sock, SIOCGIFNETMASK, (char *)&if2) < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFNETMASK failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGIFNETMASK failed");
         return -1;
     }
 
@@ -2130,25 +2069,28 @@
     return ret;
 }
 
-/**
- * Get the Hardware address (usually MAC address) for the named interface.
+/*
+ * Gets the Hardware address (usually MAC address) for the named interface.
  * return puts the data in buf, and returns the length, in byte, of the
  * MAC address. Returns -1 if there is no hardware address on that interface.
  */
-static int getMacAddress(JNIEnv *env, int sock, const char* ifname, const struct in_addr* addr, unsigned char *buf) {
+static int getMacAddress
+  (JNIEnv *env, int sock, const char* ifname, const struct in_addr* addr,
+   unsigned char *buf)
+{
     struct ifaddrs *ifa0, *ifa;
     struct sockaddr *saddr;
     int i;
 
-    /* Grab the interface list */
+    // Grab the interface list
     if (!getifaddrs(&ifa0)) {
-        /* Cycle through the interfaces */
+        // Cycle through the interfaces
         for (i = 0, ifa = ifa0; ifa != NULL; ifa = ifa->ifa_next, i++) {
             saddr = ifa->ifa_addr;
-            /* Link layer contains the MAC address */
+            // Link layer contains the MAC address
             if (saddr->sa_family == AF_LINK && !strcmp(ifname, ifa->ifa_name)) {
                 struct sockaddr_dl *sadl = (struct sockaddr_dl *) saddr;
-                /* Check the address is the correct length */
+                // Check the address is the correct length
                 if (sadl->sdl_alen == ETHER_ADDR_LEN) {
                     memcpy(buf, (sadl->sdl_data + sadl->sdl_nlen), ETHER_ADDR_LEN);
                     freeifaddrs(ifa0);
@@ -2164,12 +2106,12 @@
 
 static int getMTU(JNIEnv *env, int sock,  const char *ifname) {
     struct ifreq if2;
-
-    memset((char *) &if2, 0, sizeof(if2));
-    strcpy(if2.ifr_name, ifname);
+    memset((char *)&if2, 0, sizeof(if2));
+    strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1);
 
     if (ioctl(sock, SIOCGIFMTU, (char *)&if2) < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFMTU failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGIFMTU failed");
         return -1;
     }
 
@@ -2177,22 +2119,20 @@
 }
 
 static int getFlags(int sock, const char *ifname, int *flags) {
-  struct ifreq if2;
-  int ret = -1;
+    struct ifreq if2;
+    int ret = -1;
+    memset((char *)&if2, 0, sizeof(if2));
+    strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1);
 
-  memset((char *) &if2, 0, sizeof(if2));
-  strcpy(if2.ifr_name, ifname);
-
-  if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0){
-      return -1;
-  }
+    if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0) {
+        return -1;
+    }
 
-  if (sizeof(if2.ifr_flags) == sizeof(short)) {
-    *flags = (if2.ifr_flags & 0xffff);
-  } else {
-    *flags = if2.ifr_flags;
-  }
-  return 0;
+    if (sizeof(if2.ifr_flags) == sizeof(short)) {
+        *flags = (if2.ifr_flags & 0xffff);
+    } else {
+        *flags = if2.ifr_flags;
+    }
+    return 0;
 }
-
-#endif
+#endif /* __ALLBSD_SOURCE__ */
--- a/jdk/src/java.httpclient/share/classes/java/net/http/CharsetToolkit.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,159 +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
- */
-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/RawChannel.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/RawChannel.java	Thu May 12 11:03:07 2016 -0700
@@ -39,18 +39,22 @@
 
     private final HttpClientImpl client;
     private final HttpConnection connection;
-    private volatile boolean closed;
 
     private interface RawEvent {
 
-        /** must return the selector interest op flags OR'd. */
+        /**
+         * must return the selector interest op flags OR'd.
+         */
         int interestOps();
 
-        /** called when event occurs. */
+        /**
+         * called when event occurs.
+         */
         void handle();
     }
 
-    interface NonBlockingEvent extends RawEvent { }
+    interface NonBlockingEvent extends RawEvent {
+    }
 
     RawChannel(HttpClientImpl client, HttpConnection connection) {
         this.client = client;
@@ -127,12 +131,11 @@
 
     @Override
     public boolean isOpen() {
-        return !closed;
+        return connection.isOpen();
     }
 
     @Override
     public void close() throws IOException {
-        closed = true;
         connection.close();
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WS.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,390 @@
+/*
+ * 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 java.net.http;
+
+import java.io.IOException;
+import java.net.ProtocolException;
+import java.net.http.WSOpeningHandshake.Result;
+import java.nio.ByteBuffer;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+import java.util.stream.Stream;
+
+import static java.lang.System.Logger.Level.ERROR;
+import static java.lang.System.Logger.Level.WARNING;
+import static java.net.http.WSUtils.logger;
+import static java.util.Objects.requireNonNull;
+
+/*
+ * A WebSocket client.
+ *
+ * Consists of two independent parts; a transmitter responsible for sending
+ * messages, and a receiver which notifies the listener of incoming messages.
+ */
+final class WS implements WebSocket {
+
+    private final String subprotocol;
+    private final RawChannel channel;
+    private final WSTransmitter transmitter;
+    private final WSReceiver receiver;
+    private final Listener listener;
+    private final Object stateLock = new Object();
+    private volatile State state = State.CONNECTED;
+    private final CompletableFuture<Void> whenClosed = new CompletableFuture<>();
+
+    static CompletableFuture<WebSocket> newInstanceAsync(WSBuilder b) {
+        CompletableFuture<Result> result = new WSOpeningHandshake(b).performAsync();
+        Listener listener = b.getListener();
+        Executor executor = b.getClient().executorService();
+        return result.thenApply(r -> {
+            WS ws = new WS(listener, r.subprotocol, r.channel, executor);
+            ws.start();
+            return ws;
+        });
+    }
+
+    private WS(Listener listener, String subprotocol, RawChannel channel,
+               Executor executor) {
+        this.listener = wrapListener(listener);
+        this.channel = channel;
+        this.subprotocol = subprotocol;
+        Consumer<Throwable> errorHandler = error -> {
+            if (error == null) {
+                throw new InternalError();
+            }
+            // If the channel is closed, we need to update the state, to denote
+            // there's no point in trying to continue using WebSocket
+            if (!channel.isOpen()) {
+                synchronized (stateLock) {
+                    tryChangeState(State.ERROR);
+                }
+            }
+        };
+        transmitter = new WSTransmitter(executor, channel, errorHandler);
+        receiver = new WSReceiver(this.listener, this, executor, channel);
+    }
+
+    private void start() {
+        receiver.start();
+    }
+
+    @Override
+    public CompletableFuture<Void> sendText(ByteBuffer message, boolean isLast) {
+        throw new UnsupportedOperationException("Not implemented");
+    }
+
+    @Override
+    public CompletableFuture<Void> sendText(CharSequence message, boolean isLast) {
+        requireNonNull(message, "message");
+        synchronized (stateLock) {
+            checkState();
+            return transmitter.sendText(message, isLast);
+        }
+    }
+
+    @Override
+    public CompletableFuture<Void> sendText(Stream<? extends CharSequence> message) {
+        requireNonNull(message, "message");
+        synchronized (stateLock) {
+            checkState();
+            return transmitter.sendText(message);
+        }
+    }
+
+    @Override
+    public CompletableFuture<Void> sendBinary(ByteBuffer message, boolean isLast) {
+        requireNonNull(message, "message");
+        synchronized (stateLock) {
+            checkState();
+            return transmitter.sendBinary(message, isLast);
+        }
+    }
+
+    @Override
+    public CompletableFuture<Void> sendPing(ByteBuffer message) {
+        requireNonNull(message, "message");
+        synchronized (stateLock) {
+            checkState();
+            return transmitter.sendPing(message);
+        }
+    }
+
+    @Override
+    public CompletableFuture<Void> sendPong(ByteBuffer message) {
+        requireNonNull(message, "message");
+        synchronized (stateLock) {
+            checkState();
+            return transmitter.sendPong(message);
+        }
+    }
+
+    @Override
+    public CompletableFuture<Void> sendClose(CloseCode code, CharSequence reason) {
+        requireNonNull(code, "code");
+        requireNonNull(reason, "reason");
+        synchronized (stateLock) {
+            return doSendClose(() -> transmitter.sendClose(code, reason));
+        }
+    }
+
+    @Override
+    public CompletableFuture<Void> sendClose() {
+        synchronized (stateLock) {
+            return doSendClose(() -> transmitter.sendClose());
+        }
+    }
+
+    private CompletableFuture<Void> doSendClose(Supplier<CompletableFuture<Void>> s) {
+        checkState();
+        boolean closeChannel = false;
+        synchronized (stateLock) {
+            if (state == State.CLOSED_REMOTELY) {
+                closeChannel = tryChangeState(State.CLOSED);
+            } else {
+                tryChangeState(State.CLOSED_LOCALLY);
+            }
+        }
+        CompletableFuture<Void> sent = s.get();
+        if (closeChannel) {
+            sent.whenComplete((v, t) -> {
+                try {
+                    channel.close();
+                } catch (IOException e) {
+                    logger.log(ERROR, "Error transitioning to state " + State.CLOSED, e);
+                }
+            });
+        }
+        return sent;
+    }
+
+    @Override
+    public long request(long n) {
+        if (n < 0L) {
+            throw new IllegalArgumentException("The number must not be negative: " + n);
+        }
+        return receiver.request(n);
+    }
+
+    @Override
+    public String getSubprotocol() {
+        return subprotocol;
+    }
+
+    @Override
+    public boolean isClosed() {
+        return state.isTerminal();
+    }
+
+    @Override
+    public void abort() throws IOException {
+        synchronized (stateLock) {
+            tryChangeState(State.ABORTED);
+        }
+        channel.close();
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + "[" + state + "]";
+    }
+
+    private void checkState() {
+        if (state.isTerminal() || state == State.CLOSED_LOCALLY) {
+            throw new IllegalStateException("WebSocket is closed [" + state + "]");
+        }
+    }
+
+    /*
+     * Wraps the user's listener passed to the constructor into own listener to
+     * intercept transitions to terminal states (onClose and onError) and to act
+     * upon exceptions and values from the user's listener.
+     */
+    private Listener wrapListener(Listener listener) {
+        return new Listener() {
+
+            // Listener's method MUST be invoked in a happen-before order
+            private final Object visibilityLock = new Object();
+
+            @Override
+            public void onOpen(WebSocket webSocket) {
+                synchronized (visibilityLock) {
+                    listener.onOpen(webSocket);
+                }
+            }
+
+            @Override
+            public CompletionStage<?> onText(WebSocket webSocket, Text message,
+                                             MessagePart part) {
+                synchronized (visibilityLock) {
+                    return listener.onText(webSocket, message, part);
+                }
+            }
+
+            @Override
+            public CompletionStage<?> onBinary(WebSocket webSocket, ByteBuffer message,
+                                               MessagePart part) {
+                synchronized (visibilityLock) {
+                    return listener.onBinary(webSocket, message, part);
+                }
+            }
+
+            @Override
+            public CompletionStage<?> onPing(WebSocket webSocket, ByteBuffer message) {
+                synchronized (visibilityLock) {
+                    return listener.onPing(webSocket, message);
+                }
+            }
+
+            @Override
+            public CompletionStage<?> onPong(WebSocket webSocket, ByteBuffer message) {
+                synchronized (visibilityLock) {
+                    return listener.onPong(webSocket, message);
+                }
+            }
+
+            @Override
+            public void onClose(WebSocket webSocket, Optional<CloseCode> code, String reason) {
+                synchronized (stateLock) {
+                    if (state == State.CLOSED_REMOTELY || state.isTerminal()) {
+                        throw new InternalError("Unexpected onClose in state " + state);
+                    } else if (state == State.CLOSED_LOCALLY) {
+                        try {
+                            channel.close();
+                        } catch (IOException e) {
+                            logger.log(ERROR, "Error transitioning to state " + State.CLOSED, e);
+                        }
+                        tryChangeState(State.CLOSED);
+                    } else if (state == State.CONNECTED) {
+                        tryChangeState(State.CLOSED_REMOTELY);
+                    }
+                }
+                synchronized (visibilityLock) {
+                    listener.onClose(webSocket, code, reason);
+                }
+            }
+
+            @Override
+            public void onError(WebSocket webSocket, Throwable error) {
+                // An error doesn't necessarily mean the connection must be
+                // closed automatically
+                if (!channel.isOpen()) {
+                    synchronized (stateLock) {
+                        tryChangeState(State.ERROR);
+                    }
+                } else if (error instanceof ProtocolException
+                        && error.getCause() instanceof WSProtocolException) {
+                    WSProtocolException cause = (WSProtocolException) error.getCause();
+                    logger.log(WARNING, "Failing connection {0}, reason: ''{1}''",
+                            webSocket, cause.getMessage());
+                    CloseCode cc = cause.getCloseCode();
+                    transmitter.sendClose(cc, "").whenComplete((v, t) -> {
+                        synchronized (stateLock) {
+                            tryChangeState(State.ERROR);
+                        }
+                        try {
+                            channel.close();
+                        } catch (IOException e) {
+                            logger.log(ERROR, e);
+                        }
+                    });
+                }
+                synchronized (visibilityLock) {
+                    listener.onError(webSocket, error);
+                }
+            }
+        };
+    }
+
+    private boolean tryChangeState(State newState) {
+        assert Thread.holdsLock(stateLock);
+        if (state.isTerminal()) {
+            return false;
+        }
+        state = newState;
+        if (newState.isTerminal()) {
+            whenClosed.complete(null);
+        }
+        return true;
+    }
+
+    CompletionStage<Void> whenClosed() {
+        return whenClosed;
+    }
+
+    /*
+     * WebSocket connection internal state.
+     */
+    private enum State {
+
+        /*
+         * Initial WebSocket state. The WebSocket is connected (i.e. remains in
+         * this state) unless proven otherwise. For example, by reading or
+         * writing operations on the channel.
+         */
+        CONNECTED,
+
+        /*
+         * A Close message has been received by the client. No more messages
+         * will be received.
+         */
+        CLOSED_REMOTELY,
+
+        /*
+         * A Close message has been sent by the client. No more messages can be
+         * sent.
+         */
+        CLOSED_LOCALLY,
+
+        /*
+         * Close messages has been both sent and received (closing handshake)
+         * and TCP connection closed. Closed _cleanly_ in terms of RFC 6455.
+         */
+        CLOSED,
+
+        /*
+         * The connection has been aborted by the client. Closed not _cleanly_
+         * in terms of RFC 6455.
+         */
+        ABORTED,
+
+        /*
+         * The connection has been terminated due to a protocol or I/O error.
+         * Might happen during sending or receiving.
+         */
+        ERROR;
+
+        /*
+         * Returns `true` if this state is terminal. If WebSocket has transited
+         * to such a state, if remains in it forever.
+         */
+        boolean isTerminal() {
+            return this == CLOSED || this == ABORTED || this == ERROR;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WSBuilder.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,175 @@
+/*
+ * 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 java.net.http;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+
+import static java.lang.String.format;
+import static java.util.Objects.requireNonNull;
+
+final class WSBuilder implements WebSocket.Builder {
+
+    private static final Set<String> FORBIDDEN_HEADERS =
+            new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
+
+    static {
+        List<String> headers = List.of("Connection", "Upgrade",
+                "Sec-WebSocket-Accept", "Sec-WebSocket-Extensions",
+                "Sec-WebSocket-Key", "Sec-WebSocket-Protocol",
+                "Sec-WebSocket-Version");
+        FORBIDDEN_HEADERS.addAll(headers);
+    }
+
+    private final URI uri;
+    private final HttpClient client;
+    private final LinkedHashMap<String, List<String>> headers = new LinkedHashMap<>();
+    private final WebSocket.Listener listener;
+    private Collection<String> subprotocols = Collections.emptyList();
+    private long timeout;
+    private TimeUnit timeUnit;
+
+    WSBuilder(URI uri, HttpClient client, WebSocket.Listener listener) {
+        checkURI(requireNonNull(uri, "uri"));
+        requireNonNull(client, "client");
+        requireNonNull(listener, "listener");
+        this.uri = uri;
+        this.listener = listener;
+        this.client = client;
+    }
+
+    @Override
+    public WebSocket.Builder header(String name, String value) {
+        requireNonNull(name, "name");
+        requireNonNull(value, "value");
+        if (FORBIDDEN_HEADERS.contains(name)) {
+            throw new IllegalArgumentException(
+                    format("Header '%s' is used in the WebSocket Protocol", name));
+        }
+        List<String> values = headers.computeIfAbsent(name, n -> new LinkedList<>());
+        values.add(value);
+        return this;
+    }
+
+    @Override
+    public WebSocket.Builder subprotocols(String mostPreferred, String... lesserPreferred) {
+        requireNonNull(mostPreferred, "mostPreferred");
+        requireNonNull(lesserPreferred, "lesserPreferred");
+        this.subprotocols = checkSubprotocols(mostPreferred, lesserPreferred);
+        return this;
+    }
+
+    @Override
+    public WebSocket.Builder connectTimeout(long timeout, TimeUnit unit) {
+        if (timeout < 0) {
+            throw new IllegalArgumentException("Negative timeout: " + timeout);
+        }
+        requireNonNull(unit, "unit");
+        this.timeout = timeout;
+        this.timeUnit = unit;
+        return this;
+    }
+
+    @Override
+    public CompletableFuture<WebSocket> buildAsync() {
+        return WS.newInstanceAsync(this);
+    }
+
+    private static URI checkURI(URI uri) {
+        String s = uri.getScheme();
+        if (!("ws".equalsIgnoreCase(s) || "wss".equalsIgnoreCase(s))) {
+            throw new IllegalArgumentException
+                    ("URI scheme not ws or wss (RFC 6455 3.): " + s);
+        }
+        String fragment = uri.getFragment();
+        if (fragment != null) {
+            throw new IllegalArgumentException(format
+                    ("Fragment not allowed in a WebSocket URI (RFC 6455 3.): '%s'",
+                            fragment));
+        }
+        return uri;
+    }
+
+    URI getUri() { return uri; }
+
+    HttpClient getClient() { return client; }
+
+    Map<String, List<String>> getHeaders() {
+        LinkedHashMap<String, List<String>> copy = new LinkedHashMap<>(headers.size());
+        headers.forEach((name, values) -> copy.put(name, new LinkedList<>(values)));
+        return copy;
+    }
+
+    WebSocket.Listener getListener() { return listener; }
+
+    Collection<String> getSubprotocols() {
+        return new ArrayList<>(subprotocols);
+    }
+
+    long getTimeout() { return timeout; }
+
+    TimeUnit getTimeUnit() { return timeUnit; }
+
+    private static Collection<String> checkSubprotocols(String mostPreferred,
+                                                        String... lesserPreferred) {
+        checkSubprotocolSyntax(mostPreferred, "mostPreferred");
+        LinkedHashSet<String> sp = new LinkedHashSet<>(1 + lesserPreferred.length);
+        sp.add(mostPreferred);
+        for (int i = 0; i < lesserPreferred.length; i++) {
+            String p = lesserPreferred[i];
+            String location = format("lesserPreferred[%s]", i);
+            requireNonNull(p, location);
+            checkSubprotocolSyntax(p, location);
+            if (!sp.add(p)) {
+                throw new IllegalArgumentException(format(
+                        "Duplicate subprotocols (RFC 6455 4.1.): '%s'", p));
+            }
+        }
+        return sp;
+    }
+
+    private static void checkSubprotocolSyntax(String subprotocol, String location) {
+        if (subprotocol.isEmpty()) {
+            throw new IllegalArgumentException
+                    ("Subprotocol name is empty (RFC 6455 4.1.): " + location);
+        }
+        if (!subprotocol.chars().allMatch(c -> 0x21 <= c && c <= 0x7e)) {
+            throw new IllegalArgumentException
+                    ("Subprotocol name contains illegal characters (RFC 6455 4.1.): "
+                            + location);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WSCharsetToolkit.java	Thu May 12 11:03:07 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.  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 java.nio.charset.CodingErrorAction;
+import java.nio.charset.StandardCharsets;
+
+import static java.lang.System.Logger.Level.WARNING;
+import static java.net.http.WSUtils.EMPTY_BYTE_BUFFER;
+import static java.net.http.WSUtils.logger;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+/*
+ * A collection of tools for UTF-8 coding.
+ */
+final class WSCharsetToolkit {
+
+    private WSCharsetToolkit() { }
+
+    static final class Encoder {
+
+        private final CharsetEncoder encoder = UTF_8.newEncoder();
+
+        ByteBuffer encode(CharBuffer in) throws CharacterCodingException {
+            return encoder.encode(in);
+        }
+
+        // TODO:
+        // ByteBuffer[] encode(CharBuffer in) throws CharacterCodingException {
+        //     return encoder.encode(in);
+        // }
+    }
+
+    static CharBuffer decode(ByteBuffer in) throws CharacterCodingException {
+        return UTF_8.newDecoder().decode(in);
+    }
+
+    static final class Decoder {
+
+        private final CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
+
+        {
+            decoder.onMalformedInput(CodingErrorAction.REPORT);
+            decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
+        }
+
+        private ByteBuffer leftovers = EMPTY_BYTE_BUFFER;
+
+        WSShared<CharBuffer> decode(WSShared<ByteBuffer> in, boolean endOfInput)
+                throws CharacterCodingException {
+            ByteBuffer b;
+            int rem = leftovers.remaining();
+            if (rem != 0) {
+                // TODO: We won't need this wasteful allocation & copying when
+                // JDK-8155222 has been resolved
+                b = ByteBuffer.allocate(rem + in.remaining());
+                b.put(leftovers).put(in.buffer()).flip();
+            } else {
+                b = in.buffer();
+            }
+            CharBuffer out = CharBuffer.allocate(b.remaining());
+            CoderResult r = decoder.decode(b, out, endOfInput);
+            if (r.isError()) {
+                r.throwException();
+            }
+            if (b.hasRemaining()) {
+                leftovers = ByteBuffer.allocate(b.remaining()).put(b).flip();
+            } else {
+                leftovers = EMPTY_BYTE_BUFFER;
+            }
+            // Since it's UTF-8, the assumption is leftovers.remaining() < 4
+            // (i.e. small). Otherwise a shared buffer should be used
+            if (!(leftovers.remaining() < 4)) {
+                logger.log(WARNING,
+                        "The size of decoding leftovers is greater than expected: {0}",
+                        leftovers.remaining());
+            }
+            b.position(b.limit()); // As if we always read to the end
+            in.dispose();
+            // Decoder promises that in the case of endOfInput == true:
+            // "...any remaining undecoded input will be treated as being
+            // malformed"
+            assert !(endOfInput && leftovers.hasRemaining()) : endOfInput + ", " + leftovers;
+            if (endOfInput) {
+                r = decoder.flush(out);
+                decoder.reset();
+                if (r.isOverflow()) {
+                    // FIXME: for now I know flush() does nothing. But the
+                    // implementation of UTF8 decoder might change. And if now
+                    // flush() is a no-op, it is not guaranteed to remain so in
+                    // the future
+                    throw new InternalError("Not yet implemented");
+                }
+            }
+            out.flip();
+            return WSShared.wrap(out);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WSDisposable.java	Thu May 12 11:03:07 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  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  License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General  License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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;
+
+interface WSDisposable {
+
+    void dispose();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WSDisposableText.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,67 @@
+/*
+ * 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  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  License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General  License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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.nio.ByteBuffer;
+import java.nio.CharBuffer;
+
+final class WSDisposableText implements WebSocket.Text, WSDisposable {
+
+    private final WSShared<CharBuffer> text;
+
+    WSDisposableText(WSShared<CharBuffer> text) {
+        this.text = text;
+    }
+
+    @Override
+    public int length() {
+        return text.buffer().length();
+    }
+
+    @Override
+    public char charAt(int index) {
+        return text.buffer().charAt(index);
+    }
+
+    @Override
+    public CharSequence subSequence(int start, int end) {
+        return text.buffer().subSequence(start, end);
+    }
+
+    @Override
+    public ByteBuffer asByteBuffer() {
+        throw new UnsupportedOperationException("To be removed from the API");
+    }
+
+    @Override
+    public String toString() {
+        return text.buffer().toString();
+    }
+
+    @Override
+    public void dispose() {
+        text.dispose();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WSFrame.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,486 @@
+/*
+ * 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  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  License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General  License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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.nio.ByteBuffer;
+
+import static java.lang.String.format;
+import static java.net.http.WSFrame.Opcode.ofCode;
+import static java.net.http.WSUtils.dump;
+
+/*
+ * A collection of utilities for reading, writing, and masking frames.
+ */
+final class WSFrame {
+
+    private WSFrame() { }
+
+    static final int MAX_HEADER_SIZE_BYTES = 2 + 8 + 4;
+
+    enum Opcode {
+
+        CONTINUATION   (0x0),
+        TEXT           (0x1),
+        BINARY         (0x2),
+        NON_CONTROL_0x3(0x3),
+        NON_CONTROL_0x4(0x4),
+        NON_CONTROL_0x5(0x5),
+        NON_CONTROL_0x6(0x6),
+        NON_CONTROL_0x7(0x7),
+        CLOSE          (0x8),
+        PING           (0x9),
+        PONG           (0xA),
+        CONTROL_0xB    (0xB),
+        CONTROL_0xC    (0xC),
+        CONTROL_0xD    (0xD),
+        CONTROL_0xE    (0xE),
+        CONTROL_0xF    (0xF);
+
+        private static final Opcode[] opcodes;
+
+        static {
+            Opcode[] values = values();
+            opcodes = new Opcode[values.length];
+            for (Opcode c : values) {
+                assert opcodes[c.code] == null
+                        : WSUtils.dump(c, c.code, opcodes[c.code]);
+                opcodes[c.code] = c;
+            }
+        }
+
+        private final byte code;
+        private final char shiftedCode;
+        private final String description;
+
+        Opcode(int code) {
+            this.code = (byte) code;
+            this.shiftedCode = (char) (code << 8);
+            this.description = format("%x (%s)", code, name());
+        }
+
+        boolean isControl() {
+            return (code & 0x8) != 0;
+        }
+
+        static Opcode ofCode(int code) {
+            return opcodes[code & 0xF];
+        }
+
+        @Override
+        public String toString() {
+            return description;
+        }
+    }
+
+    /*
+     * A utility to mask payload data.
+     */
+    static final class Masker {
+
+        private final ByteBuffer acc = ByteBuffer.allocate(8);
+        private final int[] maskBytes = new int[4];
+        private int offset;
+        private long maskLong;
+
+        /*
+         * Sets up the mask.
+         */
+        Masker mask(int value) {
+            acc.clear().putInt(value).putInt(value).flip();
+            for (int i = 0; i < maskBytes.length; i++) {
+                maskBytes[i] = acc.get(i);
+            }
+            offset = 0;
+            maskLong = acc.getLong(0);
+            return this;
+        }
+
+        /*
+         * Reads as many bytes as possible from the given input buffer, writing
+         * the resulting masked bytes to the given output buffer.
+         *
+         * src.remaining() <= dst.remaining() // TODO: do we need this restriction?
+         * 'src' and 'dst' can be the same ByteBuffer
+         */
+        Masker applyMask(ByteBuffer src, ByteBuffer dst) {
+            if (src.remaining() > dst.remaining()) {
+                throw new IllegalArgumentException(dump(src, dst));
+            }
+            begin(src, dst);
+            loop(src, dst);
+            end(src, dst);
+            return this;
+        }
+
+        // Applying the remaining of the mask (strictly not more than 3 bytes)
+        // byte-wise
+        private void begin(ByteBuffer src, ByteBuffer dst) {
+            if (offset > 0) {
+                for (int i = src.position(), j = dst.position();
+                     offset < 4 && i <= src.limit() - 1 && j <= dst.limit() - 1;
+                     i++, j++, offset++) {
+                    dst.put(j, (byte) (src.get(i) ^ maskBytes[offset]));
+                    dst.position(j + 1);
+                    src.position(i + 1);
+                }
+                offset &= 3;
+            }
+        }
+
+        private void loop(ByteBuffer src, ByteBuffer dst) {
+            int i = src.position();
+            int j = dst.position();
+            final int srcLim = src.limit() - 8;
+            final int dstLim = dst.limit() - 8;
+            for (; i <= srcLim && j <= dstLim; i += 8, j += 8) {
+                dst.putLong(j, (src.getLong(i) ^ maskLong));
+            }
+            if (i > src.limit()) {
+                src.position(i - 8);
+            } else {
+                src.position(i);
+            }
+            if (j > dst.limit()) {
+                dst.position(j - 8);
+            } else {
+                dst.position(j);
+            }
+        }
+
+        // Applying the mask to the remaining bytes byte-wise (don't make any
+        // assumptions on how many, hopefully not more than 7 for 64bit arch)
+        private void end(ByteBuffer src, ByteBuffer dst) {
+            for (int i = src.position(), j = dst.position();
+                 i <= src.limit() - 1 && j <= dst.limit() - 1;
+                 i++, j++, offset = (offset + 1) & 3) { // offset cycle through 0..3
+                dst.put(j, (byte) (src.get(i) ^ maskBytes[offset]));
+                src.position(i + 1);
+                dst.position(j + 1);
+            }
+        }
+    }
+
+    /*
+     * A builder of frame headers, capable of writing to a given buffer.
+     *
+     * The builder does not enforce any protocol-level rules, it simply writes
+     * a header structure to the buffer. The order of calls to intermediate
+     * methods is not significant.
+     */
+    static final class HeaderBuilder {
+
+        private char firstChar;
+        private long payloadLen;
+        private int maskingKey;
+        private boolean mask;
+
+        HeaderBuilder fin(boolean value) {
+            if (value) {
+                firstChar |=  0b10000000_00000000;
+            } else {
+                firstChar &= ~0b10000000_00000000;
+            }
+            return this;
+        }
+
+        HeaderBuilder rsv1(boolean value) {
+            if (value) {
+                firstChar |=  0b01000000_00000000;
+            } else {
+                firstChar &= ~0b01000000_00000000;
+            }
+            return this;
+        }
+
+        HeaderBuilder rsv2(boolean value) {
+            if (value) {
+                firstChar |=  0b00100000_00000000;
+            } else {
+                firstChar &= ~0b00100000_00000000;
+            }
+            return this;
+        }
+
+        HeaderBuilder rsv3(boolean value) {
+            if (value) {
+                firstChar |=  0b00010000_00000000;
+            } else {
+                firstChar &= ~0b00010000_00000000;
+            }
+            return this;
+        }
+
+        HeaderBuilder opcode(Opcode value) {
+            firstChar = (char) ((firstChar & 0xF0FF) | value.shiftedCode);
+            return this;
+        }
+
+        HeaderBuilder payloadLen(long value) {
+            payloadLen = value;
+            firstChar &= 0b11111111_10000000; // Clear previous payload length leftovers
+            if (payloadLen < 126) {
+                firstChar |= payloadLen;
+            } else if (payloadLen < 65535) {
+                firstChar |= 126;
+            } else {
+                firstChar |= 127;
+            }
+            return this;
+        }
+
+        HeaderBuilder mask(int value) {
+            firstChar |= 0b00000000_10000000;
+            maskingKey = value;
+            mask = true;
+            return this;
+        }
+
+        HeaderBuilder noMask() {
+            firstChar &= ~0b00000000_10000000;
+            mask = false;
+            return this;
+        }
+
+        /*
+         * Writes the header to the given buffer.
+         *
+         * The buffer must have at least MAX_HEADER_SIZE_BYTES remaining. The
+         * buffer's position is incremented by the number of bytes written.
+         */
+        void build(ByteBuffer buffer) {
+            buffer.putChar(firstChar);
+            if (payloadLen >= 126) {
+                if (payloadLen < 65535) {
+                    buffer.putChar((char) payloadLen);
+                } else {
+                    buffer.putLong(payloadLen);
+                }
+            }
+            if (mask) {
+                buffer.putInt(maskingKey);
+            }
+        }
+    }
+
+    /*
+     * A consumer of frame parts.
+     *
+     * Guaranteed to be called in the following order by the Frame.Reader:
+     *
+     *     fin rsv1 rsv2 rsv3 opcode mask payloadLength maskingKey? payloadData+ endFrame
+     */
+    interface Consumer {
+
+        void fin(boolean value);
+
+        void rsv1(boolean value);
+
+        void rsv2(boolean value);
+
+        void rsv3(boolean value);
+
+        void opcode(Opcode value);
+
+        void mask(boolean value);
+
+        void payloadLen(long value);
+
+        void maskingKey(int value);
+
+        /*
+         * Called when a part of the payload is ready to be consumed.
+         *
+         * Though may not yield a complete payload in a single invocation, i.e.
+         *
+         *     data.remaining() < payloadLen
+         *
+         * the sum of `data.remaining()` passed to all invocations of this
+         * method will be equal to 'payloadLen', reported in
+         * `void payloadLen(long value)`
+         *
+         * No unmasking is done.
+         */
+        void payloadData(WSShared<ByteBuffer> data, boolean isLast);
+
+        void endFrame(); // TODO: remove (payloadData(isLast=true)) should be enough
+    }
+
+    /*
+     * A Reader of Frames.
+     *
+     * No protocol-level rules are enforced, only frame structure.
+     */
+    static final class Reader {
+
+        private static final int AWAITING_FIRST_BYTE  =  1;
+        private static final int AWAITING_SECOND_BYTE =  2;
+        private static final int READING_16_LENGTH    =  4;
+        private static final int READING_64_LENGTH    =  8;
+        private static final int READING_MASK         = 16;
+        private static final int READING_PAYLOAD      = 32;
+
+        // A private buffer used to simplify multi-byte integers reading
+        private final ByteBuffer accumulator = ByteBuffer.allocate(8);
+        private int state = AWAITING_FIRST_BYTE;
+        private boolean mask;
+        private long payloadLength;
+
+        /*
+         * Reads at most one frame from the given buffer invoking the consumer's
+         * methods corresponding to the frame elements found.
+         *
+         * As much of the frame's payload, if any, is read. The buffers position
+         * is updated to reflect the number of bytes read.
+         *
+         * Throws WSProtocolException if the frame is malformed.
+         */
+        void readFrame(WSShared<ByteBuffer> shared, Consumer consumer) {
+            ByteBuffer input = shared.buffer();
+            loop:
+            while (true) {
+                byte b;
+                switch (state) {
+                    case AWAITING_FIRST_BYTE:
+                        if (!input.hasRemaining()) {
+                            break loop;
+                        }
+                        b = input.get();
+                        consumer.fin( (b & 0b10000000) != 0);
+                        consumer.rsv1((b & 0b01000000) != 0);
+                        consumer.rsv2((b & 0b00100000) != 0);
+                        consumer.rsv3((b & 0b00010000) != 0);
+                        consumer.opcode(ofCode(b));
+                        state = AWAITING_SECOND_BYTE;
+                        continue loop;
+                    case AWAITING_SECOND_BYTE:
+                        if (!input.hasRemaining()) {
+                            break loop;
+                        }
+                        b = input.get();
+                        consumer.mask(mask = (b & 0b10000000) != 0);
+                        byte p1 = (byte) (b & 0b01111111);
+                        if (p1 < 126) {
+                            assert p1 >= 0 : p1;
+                            consumer.payloadLen(payloadLength = p1);
+                            state = mask ? READING_MASK : READING_PAYLOAD;
+                        } else if (p1 < 127) {
+                            state = READING_16_LENGTH;
+                        } else {
+                            state = READING_64_LENGTH;
+                        }
+                        continue loop;
+                    case READING_16_LENGTH:
+                        if (!input.hasRemaining()) {
+                            break loop;
+                        }
+                        b = input.get();
+                        if (accumulator.put(b).position() < 2) {
+                            continue loop;
+                        }
+                        payloadLength = accumulator.flip().getChar();
+                        if (payloadLength < 126) {
+                            throw notMinimalEncoding(payloadLength, 2);
+                        }
+                        consumer.payloadLen(payloadLength);
+                        accumulator.clear();
+                        state = mask ? READING_MASK : READING_PAYLOAD;
+                        continue loop;
+                    case READING_64_LENGTH:
+                        if (!input.hasRemaining()) {
+                            break loop;
+                        }
+                        b = input.get();
+                        if (accumulator.put(b).position() < 8) {
+                            continue loop;
+                        }
+                        payloadLength = accumulator.flip().getLong();
+                        if (payloadLength < 0) {
+                            throw negativePayload(payloadLength);
+                        } else if (payloadLength < 65535) {
+                            throw notMinimalEncoding(payloadLength, 8);
+                        }
+                        consumer.payloadLen(payloadLength);
+                        accumulator.clear();
+                        state = mask ? READING_MASK : READING_PAYLOAD;
+                        continue loop;
+                    case READING_MASK:
+                        if (!input.hasRemaining()) {
+                            break loop;
+                        }
+                        b = input.get();
+                        if (accumulator.put(b).position() != 4) {
+                            continue loop;
+                        }
+                        consumer.maskingKey(accumulator.flip().getInt());
+                        accumulator.clear();
+                        state = READING_PAYLOAD;
+                        continue loop;
+                    case READING_PAYLOAD:
+                        // This state does not require any bytes to be available
+                        // in the input buffer in order to proceed
+                        boolean fullyRead;
+                        int limit;
+                        if (payloadLength <= input.remaining()) {
+                            limit = input.position() + (int) payloadLength;
+                            payloadLength = 0;
+                            fullyRead = true;
+                        } else {
+                            limit = input.limit();
+                            payloadLength -= input.remaining();
+                            fullyRead = false;
+                        }
+                        // FIXME: consider a case where payloadLen != 0,
+                        // but input.remaining() == 0
+                        //
+                        // There shouldn't be an invocation of payloadData with
+                        // an empty buffer, as it would be an artifact of
+                        // reading
+                        consumer.payloadData(shared.share(input.position(), limit), fullyRead);
+                        // Update the position manually, since reading the
+                        // payload doesn't advance buffer's position
+                        input.position(limit);
+                        if (fullyRead) {
+                            consumer.endFrame();
+                            state = AWAITING_FIRST_BYTE;
+                        }
+                        break loop;
+                    default:
+                        throw new InternalError(String.valueOf(state));
+                }
+            }
+        }
+
+        private static WSProtocolException negativePayload(long payloadLength) {
+            return new WSProtocolException
+                    ("5.2.", format("Negative 64-bit payload length %s", payloadLength));
+        }
+
+        private static WSProtocolException notMinimalEncoding(long payloadLength, int numBytes) {
+            return new WSProtocolException
+                    ("5.2.", format("Payload length (%s) is not encoded with minimal number (%s) of bytes",
+                            payloadLength, numBytes));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WSFrameConsumer.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,289 @@
+/*
+ * 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 java.net.http;
+
+import java.net.http.WSFrame.Opcode;
+import java.net.http.WebSocket.MessagePart;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static java.lang.String.format;
+import static java.lang.System.Logger.Level.TRACE;
+import static java.net.http.WSUtils.dump;
+import static java.net.http.WSUtils.logger;
+import static java.net.http.WebSocket.CloseCode.NOT_CONSISTENT;
+import static java.net.http.WebSocket.CloseCode.of;
+import static java.util.Objects.requireNonNull;
+
+/*
+ * Consumes frame parts and notifies a message consumer, when there is
+ * sufficient data to produce a message, or part thereof.
+ *
+ * Data consumed but not yet translated is accumulated until it's sufficient to
+ * form a message.
+ */
+final class WSFrameConsumer implements WSFrame.Consumer {
+
+    private final AtomicInteger invocationOrder = new AtomicInteger();
+
+    private final WSMessageConsumer output;
+    private final WSCharsetToolkit.Decoder decoder = new WSCharsetToolkit.Decoder();
+    private boolean fin;
+    private Opcode opcode, originatingOpcode;
+    private MessagePart part = MessagePart.WHOLE;
+    private long payloadLen;
+    private WSShared<ByteBuffer> binaryData;
+
+    WSFrameConsumer(WSMessageConsumer output) {
+        this.output = requireNonNull(output);
+    }
+
+    @Override
+    public void fin(boolean value) {
+        assert invocationOrder.compareAndSet(0, 1) : dump(invocationOrder, value);
+        if (logger.isLoggable(TRACE)) {
+            // Checked for being loggable because of autoboxing of 'value'
+            logger.log(TRACE, "Reading fin: {0}", value);
+        }
+        fin = value;
+    }
+
+    @Override
+    public void rsv1(boolean value) {
+        assert invocationOrder.compareAndSet(1, 2) : dump(invocationOrder, value);
+        if (logger.isLoggable(TRACE)) {
+            logger.log(TRACE, "Reading rsv1: {0}", value);
+        }
+        if (value) {
+            throw new WSProtocolException("5.2.", "rsv1 bit is set unexpectedly");
+        }
+    }
+
+    @Override
+    public void rsv2(boolean value) {
+        assert invocationOrder.compareAndSet(2, 3) : dump(invocationOrder, value);
+        if (logger.isLoggable(TRACE)) {
+            logger.log(TRACE, "Reading rsv2: {0}", value);
+        }
+        if (value) {
+            throw new WSProtocolException("5.2.", "rsv2 bit is set unexpectedly");
+        }
+    }
+
+    @Override
+    public void rsv3(boolean value) {
+        assert invocationOrder.compareAndSet(3, 4) : dump(invocationOrder, value);
+        if (logger.isLoggable(TRACE)) {
+            logger.log(TRACE, "Reading rsv3: {0}", value);
+        }
+        if (value) {
+            throw new WSProtocolException("5.2.", "rsv3 bit is set unexpectedly");
+        }
+    }
+
+    @Override
+    public void opcode(Opcode v) {
+        assert invocationOrder.compareAndSet(4, 5) : dump(invocationOrder, v);
+        logger.log(TRACE, "Reading opcode: {0}", v);
+        if (v == Opcode.PING || v == Opcode.PONG || v == Opcode.CLOSE) {
+            if (!fin) {
+                throw new WSProtocolException("5.5.", "A fragmented control frame " + v);
+            }
+            opcode = v;
+        } else if (v == Opcode.TEXT || v == Opcode.BINARY) {
+            if (originatingOpcode != null) {
+                throw new WSProtocolException
+                        ("5.4.", format("An unexpected frame %s (fin=%s)", v, fin));
+            }
+            opcode = v;
+            if (!fin) {
+                originatingOpcode = v;
+            }
+        } else if (v == Opcode.CONTINUATION) {
+            if (originatingOpcode == null) {
+                throw new WSProtocolException
+                        ("5.4.", format("An unexpected frame %s (fin=%s)", v, fin));
+            }
+            opcode = v;
+        } else {
+            throw new WSProtocolException("5.2.", "An unknown opcode " + v);
+        }
+    }
+
+    @Override
+    public void mask(boolean value) {
+        assert invocationOrder.compareAndSet(5, 6) : dump(invocationOrder, value);
+        if (logger.isLoggable(TRACE)) {
+            logger.log(TRACE, "Reading mask: {0}", value);
+        }
+        if (value) {
+            throw new WSProtocolException
+                    ("5.1.", "Received a masked frame from the server");
+        }
+    }
+
+    @Override
+    public void payloadLen(long value) {
+        assert invocationOrder.compareAndSet(6, 7) : dump(invocationOrder, value);
+        if (logger.isLoggable(TRACE)) {
+            logger.log(TRACE, "Reading payloadLen: {0}", value);
+        }
+        if (opcode.isControl()) {
+            if (value > 125) {
+                throw new WSProtocolException
+                        ("5.5.", format("A control frame %s has a payload length of %s",
+                                opcode, value));
+            }
+            assert Opcode.CLOSE.isControl();
+            if (opcode == Opcode.CLOSE && value == 1) {
+                throw new WSProtocolException
+                        ("5.5.1.", "A Close frame's status code is only 1 byte long");
+            }
+        }
+        payloadLen = value;
+    }
+
+    @Override
+    public void maskingKey(int value) {
+        assert false : dump(invocationOrder, value);
+    }
+
+    @Override
+    public void payloadData(WSShared<ByteBuffer> data, boolean isLast) {
+        assert invocationOrder.compareAndSet(7, isLast ? 8 : 7)
+                : dump(invocationOrder, data, isLast);
+        if (logger.isLoggable(TRACE)) {
+            logger.log(TRACE, "Reading payloadData: data={0}, isLast={1}", data, isLast);
+        }
+        if (opcode.isControl()) {
+            if (binaryData != null) {
+                binaryData.put(data);
+                data.dispose();
+            } else if (!isLast) {
+                // The first chunk of the message
+                int remaining = data.remaining();
+                // It shouldn't be 125, otherwise the next chunk will be of size
+                // 0, which is not what Reader promises to deliver (eager
+                // reading)
+                assert remaining < 125 : dump(remaining);
+                WSShared<ByteBuffer> b = WSShared.wrap(ByteBuffer.allocate(125)).put(data);
+                data.dispose();
+                binaryData = b; // Will be disposed by the user
+            } else {
+                // The only chunk; will be disposed by the user
+                binaryData = data.position(data.limit()); // FIXME: remove this hack
+            }
+        } else {
+            part = determinePart(isLast);
+            boolean text = opcode == Opcode.TEXT || originatingOpcode == Opcode.TEXT;
+            if (!text) {
+                output.onBinary(part, data);
+            } else {
+                boolean binaryNonEmpty = data.hasRemaining();
+                WSShared<CharBuffer> textData;
+                try {
+                    textData = decoder.decode(data, part.isLast());
+                } catch (CharacterCodingException e) {
+                    throw new WSProtocolException
+                            ("5.6.", "Invalid UTF-8 sequence in frame " + opcode, NOT_CONSISTENT, e);
+                }
+                if (!(binaryNonEmpty && !textData.hasRemaining())) {
+                    // If there's a binary data, that result in no text, then we
+                    // don't deliver anything
+                    output.onText(part, new WSDisposableText(textData));
+                }
+            }
+        }
+    }
+
+    @Override
+    public void endFrame() {
+        assert invocationOrder.compareAndSet(8, 0) : dump(invocationOrder);
+        if (opcode.isControl()) {
+            binaryData.flip();
+        }
+        switch (opcode) {
+            case CLOSE:
+                WebSocket.CloseCode cc;
+                String reason;
+                if (payloadLen == 0) {
+                    cc = null;
+                    reason = "";
+                } else {
+                    ByteBuffer b = binaryData.buffer();
+                    int len = b.remaining();
+                    assert 2 <= len && len <= 125 : dump(len, payloadLen);
+                    try {
+                        cc = of(b.getChar());
+                        reason = WSCharsetToolkit.decode(b).toString();
+                    } catch (IllegalArgumentException e) {
+                        throw new WSProtocolException
+                                ("5.5.1", "Incorrect status code", e);
+                    } catch (CharacterCodingException e) {
+                        throw new WSProtocolException
+                                ("5.5.1", "Close reason is a malformed UTF-8 sequence", e);
+                    }
+                }
+                binaryData.dispose(); // Manual dispose
+                output.onClose(cc, reason);
+                break;
+            case PING:
+                output.onPing(binaryData);
+                binaryData = null;
+                break;
+            case PONG:
+                output.onPong(binaryData);
+                binaryData = null;
+                break;
+            default:
+                assert opcode == Opcode.TEXT || opcode == Opcode.BINARY
+                        || opcode == Opcode.CONTINUATION : dump(opcode);
+                if (fin) {
+                    // It is always the last chunk:
+                    // either TEXT(FIN=TRUE)/BINARY(FIN=TRUE) or CONT(FIN=TRUE)
+                    originatingOpcode = null;
+                }
+                break;
+        }
+        payloadLen = 0;
+        opcode = null;
+    }
+
+    private MessagePart determinePart(boolean isLast) {
+        boolean lastChunk = fin && isLast;
+        switch (part) {
+            case LAST:
+            case WHOLE:
+                return lastChunk ? MessagePart.WHOLE : MessagePart.FIRST;
+            case FIRST:
+            case PART:
+                return lastChunk ? MessagePart.LAST : MessagePart.PART;
+            default:
+                throw new InternalError(String.valueOf(part));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WSMessageConsumer.java	Thu May 12 11:03:07 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 java.net.http;
+
+import java.net.http.WebSocket.CloseCode;
+import java.net.http.WebSocket.MessagePart;
+import java.nio.ByteBuffer;
+
+interface WSMessageConsumer {
+
+    void onText(MessagePart part, WSDisposableText data);
+
+    void onBinary(MessagePart part, WSShared<ByteBuffer> data);
+
+    void onPing(WSShared<ByteBuffer> data);
+
+    void onPong(WSShared<ByteBuffer> data);
+
+    void onClose(CloseCode code, CharSequence reason);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WSMessageSender.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,189 @@
+/*
+ * 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  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  License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General  License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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.net.http.WSFrame.HeaderBuilder;
+import java.net.http.WSFrame.Masker;
+import java.net.http.WSOutgoingMessage.Binary;
+import java.net.http.WSOutgoingMessage.Close;
+import java.net.http.WSOutgoingMessage.Ping;
+import java.net.http.WSOutgoingMessage.Pong;
+import java.net.http.WSOutgoingMessage.StreamedText;
+import java.net.http.WSOutgoingMessage.Text;
+import java.net.http.WSOutgoingMessage.Visitor;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.security.SecureRandom;
+import java.util.function.Consumer;
+
+import static java.net.http.WSFrame.MAX_HEADER_SIZE_BYTES;
+import static java.net.http.WSFrame.Opcode.BINARY;
+import static java.net.http.WSFrame.Opcode.CLOSE;
+import static java.net.http.WSFrame.Opcode.CONTINUATION;
+import static java.net.http.WSFrame.Opcode.PING;
+import static java.net.http.WSFrame.Opcode.PONG;
+import static java.net.http.WSFrame.Opcode.TEXT;
+import static java.util.Objects.requireNonNull;
+
+/*
+ * A Sender of outgoing messages.  Given a message,
+ *
+ *     1) constructs the frame
+ *     2) initiates the channel write
+ *     3) notifies when the message has been sent
+ */
+final class WSMessageSender {
+
+    private final Visitor frameBuilderVisitor;
+    private final Consumer<Throwable> completionEventConsumer;
+    private final WSWriter writer;
+    private final ByteBuffer[] buffers = new ByteBuffer[2];
+
+    WSMessageSender(RawChannel channel, Consumer<Throwable> completionEventConsumer) {
+        // Single reusable buffer that holds a header
+        this.buffers[0] = ByteBuffer.allocateDirect(MAX_HEADER_SIZE_BYTES);
+        this.frameBuilderVisitor = new FrameBuilderVisitor();
+        this.completionEventConsumer = completionEventConsumer;
+        this.writer = new WSWriter(channel, this.completionEventConsumer);
+    }
+
+    /*
+     * Tries to send the given message fully. Invoked once per message.
+     */
+    boolean trySendFully(WSOutgoingMessage m) {
+        requireNonNull(m);
+        synchronized (this) {
+            try {
+                return sendNow(m);
+            } catch (Exception e) {
+                completionEventConsumer.accept(e);
+                return false;
+            }
+        }
+    }
+
+    private boolean sendNow(WSOutgoingMessage m) {
+        buffers[0].clear();
+        m.accept(frameBuilderVisitor);
+        buffers[0].flip();
+        return writer.tryWriteFully(buffers);
+    }
+
+    /*
+     * Builds and initiates a write of a frame, from a given message.
+     */
+    class FrameBuilderVisitor implements Visitor {
+
+        private final SecureRandom random = new SecureRandom();
+        private final WSCharsetToolkit.Encoder encoder = new WSCharsetToolkit.Encoder();
+        private final Masker masker = new Masker();
+        private final HeaderBuilder headerBuilder = new HeaderBuilder();
+        private boolean previousIsLast = true;
+
+        @Override
+        public void visit(Text message) {
+            try {
+                buffers[1] = encoder.encode(CharBuffer.wrap(message.characters));
+            } catch (CharacterCodingException e) {
+                completionEventConsumer.accept(e);
+                return;
+            }
+            int mask = random.nextInt();
+            maskAndRewind(buffers[1], mask);
+            headerBuilder
+                    .fin(message.isLast)
+                    .opcode(previousIsLast ? TEXT : CONTINUATION)
+                    .payloadLen(buffers[1].remaining())
+                    .mask(mask)
+                    .build(buffers[0]);
+            previousIsLast = message.isLast;
+        }
+
+        @Override
+        public void visit(StreamedText streamedText) {
+            throw new IllegalArgumentException("Not yet implemented");
+        }
+
+        @Override
+        public void visit(Binary message) {
+            buffers[1] = message.bytes;
+            int mask = random.nextInt();
+            maskAndRewind(buffers[1], mask);
+            headerBuilder
+                    .fin(message.isLast)
+                    .opcode(previousIsLast ? BINARY : CONTINUATION)
+                    .payloadLen(message.bytes.remaining())
+                    .mask(mask)
+                    .build(buffers[0]);
+            previousIsLast = message.isLast;
+        }
+
+        @Override
+        public void visit(Ping message) {
+            buffers[1] = message.bytes;
+            int mask = random.nextInt();
+            maskAndRewind(buffers[1], mask);
+            headerBuilder
+                    .fin(true)
+                    .opcode(PING)
+                    .payloadLen(message.bytes.remaining())
+                    .mask(mask)
+                    .build(buffers[0]);
+        }
+
+        @Override
+        public void visit(Pong message) {
+            buffers[1] = message.bytes;
+            int mask = random.nextInt();
+            maskAndRewind(buffers[1], mask);
+            headerBuilder
+                    .fin(true)
+                    .opcode(PONG)
+                    .payloadLen(message.bytes.remaining())
+                    .mask(mask)
+                    .build(buffers[0]);
+        }
+
+        @Override
+        public void visit(Close message) {
+            buffers[1] = message.bytes;
+            int mask = random.nextInt();
+            maskAndRewind(buffers[1], mask);
+            headerBuilder
+                    .fin(true)
+                    .opcode(CLOSE)
+                    .payloadLen(buffers[1].remaining())
+                    .mask(mask)
+                    .build(buffers[0]);
+        }
+
+        private void maskAndRewind(ByteBuffer b, int mask) {
+            int oldPos = b.position();
+            masker.mask(mask).applyMask(b, b);
+            b.position(oldPos);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WSOpeningHandshake.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,268 @@
+/*
+ * 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 java.net.http;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import static java.lang.String.format;
+import static java.lang.System.Logger.Level.TRACE;
+import static java.net.http.WSUtils.logger;
+import static java.net.http.WSUtils.webSocketSpecViolation;
+
+final class WSOpeningHandshake {
+
+    private static final String HEADER_CONNECTION = "Connection";
+    private static final String HEADER_UPGRADE = "Upgrade";
+    private static final String HEADER_ACCEPT = "Sec-WebSocket-Accept";
+    private static final String HEADER_EXTENSIONS = "Sec-WebSocket-Extensions";
+    private static final String HEADER_KEY = "Sec-WebSocket-Key";
+    private static final String HEADER_PROTOCOL = "Sec-WebSocket-Protocol";
+    private static final String HEADER_VERSION = "Sec-WebSocket-Version";
+    private static final String VALUE_VERSION = "13"; // WebSocket's lucky number
+
+    private static final SecureRandom srandom = new SecureRandom();
+
+    private final MessageDigest sha1;
+
+    {
+        try {
+            sha1 = MessageDigest.getInstance("SHA-1");
+        } catch (NoSuchAlgorithmException e) {
+            // Shouldn't happen:
+            // SHA-1 must be available in every Java platform implementation
+            throw new InternalError("Minimum platform requirements are not met", e);
+        }
+    }
+
+    private final HttpRequest request;
+    private final Collection<String> subprotocols;
+    private final String nonce;
+
+    WSOpeningHandshake(WSBuilder b) {
+        URI httpURI = createHttpUri(b.getUri());
+        HttpRequest.Builder requestBuilder = b.getClient().request(httpURI);
+        if (b.getTimeUnit() != null) {
+            requestBuilder.timeout(b.getTimeUnit(), b.getTimeout());
+        }
+        Collection<String> s = b.getSubprotocols();
+        if (!s.isEmpty()) {
+            String p = s.stream().collect(Collectors.joining(", "));
+            requestBuilder.header(HEADER_PROTOCOL, p);
+        }
+        requestBuilder.header(HEADER_VERSION, VALUE_VERSION);
+        this.nonce = createNonce();
+        requestBuilder.header(HEADER_KEY, this.nonce);
+        this.request = requestBuilder.GET();
+        HttpRequestImpl r = (HttpRequestImpl) this.request;
+        r.isWebSocket(true);
+        r.setSystemHeader(HEADER_UPGRADE, "websocket");
+        r.setSystemHeader(HEADER_CONNECTION, "Upgrade");
+        this.subprotocols = s;
+    }
+
+    private URI createHttpUri(URI webSocketUri) {
+        // FIXME: check permission for WebSocket URI and translate it into http/https permission
+        logger.log(TRACE, "->createHttpUri(''{0}'')", webSocketUri);
+        String httpScheme = webSocketUri.getScheme().equalsIgnoreCase("ws")
+                ? "http"
+                : "https";
+        try {
+            URI uri = new URI(httpScheme,
+                    webSocketUri.getUserInfo(),
+                    webSocketUri.getHost(),
+                    webSocketUri.getPort(),
+                    webSocketUri.getPath(),
+                    webSocketUri.getQuery(),
+                    null);
+            logger.log(TRACE, "<-createHttpUri: ''{0}''", uri);
+            return uri;
+        } catch (URISyntaxException e) {
+            // Shouldn't happen: URI invariant
+            throw new InternalError("Error translating WebSocket URI to HTTP URI", e);
+        }
+    }
+
+    CompletableFuture<Result> performAsync() {
+        // The whole dancing with thenCompose instead of thenApply is because
+        // WebSocketHandshakeException is a checked exception
+        return request.responseAsync()
+                .thenCompose(response -> {
+                    try {
+                        Result result = handleResponse(response);
+                        return CompletableFuture.completedFuture(result);
+                    } catch (WebSocketHandshakeException e) {
+                        return CompletableFuture.failedFuture(e);
+                    }
+                });
+    }
+
+    private Result handleResponse(HttpResponse response) throws WebSocketHandshakeException {
+        // By this point all redirects, authentications, etc. (if any) must have
+        // been done by the httpClient used by the WebSocket; so only 101 is
+        // expected
+        int statusCode = response.statusCode();
+        if (statusCode != 101) {
+            String m = webSocketSpecViolation("1.3.",
+                    "Unable to complete handshake; HTTP response status code "
+                            + statusCode
+            );
+            throw new WebSocketHandshakeException(m, response);
+        }
+        HttpHeaders h = response.headers();
+        checkHeader(h, response, HEADER_UPGRADE, v -> v.equalsIgnoreCase("websocket"));
+        checkHeader(h, response, HEADER_CONNECTION, v -> v.equalsIgnoreCase("Upgrade"));
+        checkVersion(response, h);
+        checkAccept(response, h);
+        checkExtensions(response, h);
+        String subprotocol = checkAndReturnSubprotocol(response, h);
+        RawChannel channel = ((HttpResponseImpl) response).rawChannel();
+        return new Result(subprotocol, channel);
+    }
+
+    private void checkExtensions(HttpResponse response, HttpHeaders headers)
+            throws WebSocketHandshakeException {
+        List<String> ext = headers.allValues(HEADER_EXTENSIONS);
+        if (!ext.isEmpty()) {
+            String m = webSocketSpecViolation("4.1.",
+                    "Server responded with extension(s) though none were requested "
+                            + Arrays.toString(ext.toArray())
+            );
+            throw new WebSocketHandshakeException(m, response);
+        }
+    }
+
+    private String checkAndReturnSubprotocol(HttpResponse response, HttpHeaders headers)
+            throws WebSocketHandshakeException {
+        assert response.statusCode() == 101 : response.statusCode();
+        List<String> sp = headers.allValues(HEADER_PROTOCOL);
+        int size = sp.size();
+        if (size == 0) {
+            // In this case the subprotocol requested (if any) by the client
+            // doesn't matter. If there is no such header in the response, then
+            // the server doesn't want to use any subprotocol
+            return null;
+        } else if (size > 1) {
+            // We don't know anything about toString implementation of this
+            // list, so let's create an array
+            String m = webSocketSpecViolation("4.1.",
+                    "Server responded with multiple subprotocols: "
+                            + Arrays.toString(sp.toArray())
+            );
+            throw new WebSocketHandshakeException(m, response);
+        } else {
+            String selectedSubprotocol = sp.get(0);
+            if (this.subprotocols.contains(selectedSubprotocol)) {
+                return selectedSubprotocol;
+            } else {
+                String m = webSocketSpecViolation("4.1.",
+                        format("Server responded with a subprotocol " +
+                                        "not among those requested: '%s'",
+                                selectedSubprotocol));
+                throw new WebSocketHandshakeException(m, response);
+            }
+        }
+    }
+
+    private void checkAccept(HttpResponse response, HttpHeaders headers)
+            throws WebSocketHandshakeException {
+        assert response.statusCode() == 101 : response.statusCode();
+        String x = nonce + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+        sha1.update(x.getBytes(StandardCharsets.ISO_8859_1));
+        String expected = Base64.getEncoder().encodeToString(sha1.digest());
+        checkHeader(headers, response, HEADER_ACCEPT, actual -> actual.trim().equals(expected));
+    }
+
+    private void checkVersion(HttpResponse response, HttpHeaders headers)
+            throws WebSocketHandshakeException {
+        assert response.statusCode() == 101 : response.statusCode();
+        List<String> versions = headers.allValues(HEADER_VERSION);
+        if (versions.isEmpty()) { // That's normal and expected
+            return;
+        }
+        String m = webSocketSpecViolation("4.4.",
+                "Server responded with version(s) "
+                        + Arrays.toString(versions.toArray()));
+        throw new WebSocketHandshakeException(m, response);
+    }
+
+    //
+    // Checks whether there's only one value for the header with the given name
+    // and the value satisfies the predicate.
+    //
+    private static void checkHeader(HttpHeaders headers,
+                                    HttpResponse response,
+                                    String headerName,
+                                    Predicate<? super String> valuePredicate)
+            throws WebSocketHandshakeException {
+        assert response.statusCode() == 101 : response.statusCode();
+        List<String> values = headers.allValues(headerName);
+        if (values.isEmpty()) {
+            String m = webSocketSpecViolation("4.1.",
+                    format("Server response field '%s' is missing", headerName)
+            );
+            throw new WebSocketHandshakeException(m, response);
+        } else if (values.size() > 1) {
+            String m = webSocketSpecViolation("4.1.",
+                    format("Server response field '%s' has multiple values", headerName)
+            );
+            throw new WebSocketHandshakeException(m, response);
+        }
+        if (!valuePredicate.test(values.get(0))) {
+            String m = webSocketSpecViolation("4.1.",
+                    format("Server response field '%s' is incorrect", headerName)
+            );
+            throw new WebSocketHandshakeException(m, response);
+        }
+    }
+
+    private static String createNonce() {
+        byte[] bytes = new byte[16];
+        srandom.nextBytes(bytes);
+        return Base64.getEncoder().encodeToString(bytes);
+    }
+
+    static final class Result {
+
+        final String subprotocol;
+        final RawChannel channel;
+
+        private Result(String subprotocol, RawChannel channel) {
+            this.subprotocol = subprotocol;
+            this.channel = channel;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WSOutgoingMessage.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,164 @@
+/*
+ * 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  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  License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General  License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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.nio.ByteBuffer;
+import java.util.stream.Stream;
+
+abstract class WSOutgoingMessage {
+
+    interface Visitor {
+        void visit(Text message);
+        void visit(StreamedText message);
+        void visit(Binary message);
+        void visit(Ping message);
+        void visit(Pong message);
+        void visit(Close message);
+    }
+
+    abstract void accept(Visitor visitor);
+
+    private WSOutgoingMessage() { }
+
+    static final class Text extends WSOutgoingMessage {
+
+        public final boolean isLast;
+        public final CharSequence characters;
+
+        Text(boolean isLast, CharSequence characters) {
+            this.isLast = isLast;
+            this.characters = characters;
+        }
+
+        @Override
+        void accept(Visitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public String toString() {
+            return WSUtils.toStringSimple(this) + "[isLast=" + isLast
+                    + ", characters=" + WSUtils.toString(characters) + "]";
+        }
+    }
+
+    static final class StreamedText extends WSOutgoingMessage {
+
+        public final Stream<? extends CharSequence> characters;
+
+        StreamedText(Stream<? extends CharSequence> characters) {
+            this.characters = characters;
+        }
+
+        @Override
+        void accept(Visitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public String toString() {
+            return WSUtils.toStringSimple(this) + "[characters=" + characters + "]";
+        }
+    }
+
+    static final class Binary extends WSOutgoingMessage {
+
+        public final boolean isLast;
+        public final ByteBuffer bytes;
+
+        Binary(boolean isLast, ByteBuffer bytes) {
+            this.isLast = isLast;
+            this.bytes = bytes;
+        }
+
+        @Override
+        void accept(Visitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public String toString() {
+            return WSUtils.toStringSimple(this) + "[isLast=" + isLast
+                    + ", bytes=" + WSUtils.toString(bytes) + "]";
+        }
+    }
+
+    static final class Ping extends WSOutgoingMessage {
+
+        public final ByteBuffer bytes;
+
+        Ping(ByteBuffer bytes) {
+            this.bytes = bytes;
+        }
+
+        @Override
+        void accept(Visitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public String toString() {
+            return WSUtils.toStringSimple(this) + "[" + WSUtils.toString(bytes) + "]";
+        }
+    }
+
+    static final class Pong extends WSOutgoingMessage {
+
+        public final ByteBuffer bytes;
+
+        Pong(ByteBuffer bytes) {
+            this.bytes = bytes;
+        }
+
+        @Override
+        void accept(Visitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public String toString() {
+            return WSUtils.toStringSimple(this) + "[" + WSUtils.toString(bytes) + "]";
+        }
+    }
+
+    static final class Close extends WSOutgoingMessage {
+
+        public final ByteBuffer bytes;
+
+        Close(ByteBuffer bytes) {
+            this.bytes = bytes;
+        }
+
+        @Override
+        void accept(Visitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public String toString() {
+            return WSUtils.toStringSimple(this) + "[" + WSUtils.toString(bytes) + "]";
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WSProtocolException.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,68 @@
+package java.net.http;
+
+import java.net.http.WebSocket.CloseCode;
+
+import static java.net.http.WebSocket.CloseCode.PROTOCOL_ERROR;
+import static java.util.Objects.requireNonNull;
+
+//
+// Special kind of exception closed from the outside world.
+//
+// Used as a "marker exception" for protocol issues in the incoming data, so the
+// implementation could close the connection and specify an appropriate status
+// code.
+//
+// A separate 'section' argument makes it more uncomfortable to be lazy and to
+// leave a relevant spec reference empty :-) As a bonus all messages have the
+// same style.
+//
+final class WSProtocolException extends RuntimeException {
+
+    private static final long serialVersionUID = 1L;
+    private final CloseCode closeCode;
+    private final String section;
+
+    WSProtocolException(String section, String detail) {
+        this(section, detail, PROTOCOL_ERROR);
+    }
+
+    WSProtocolException(String section, String detail, Throwable cause) {
+        this(section, detail, PROTOCOL_ERROR, cause);
+    }
+
+    private WSProtocolException(String section, String detail, CloseCode code) {
+        super(formatMessage(section, detail));
+        this.closeCode = requireNonNull(code);
+        this.section = section;
+    }
+
+    WSProtocolException(String section, String detail, CloseCode code,
+                        Throwable cause) {
+        super(formatMessage(section, detail), cause);
+        this.closeCode = requireNonNull(code);
+        this.section = section;
+    }
+
+    private static String formatMessage(String section, String detail) {
+        if (requireNonNull(section).isEmpty()) {
+            throw new IllegalArgumentException();
+        }
+        if (requireNonNull(detail).isEmpty()) {
+            throw new IllegalArgumentException();
+        }
+        return WSUtils.webSocketSpecViolation(section, detail);
+    }
+
+    CloseCode getCloseCode() {
+        return closeCode;
+    }
+
+    public String getSection() {
+        return section;
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + "[" + closeCode + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WSReceiver.java	Thu May 12 11:03:07 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.net.http;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.net.ProtocolException;
+import java.net.http.WebSocket.Listener;
+import java.nio.ByteBuffer;
+import java.nio.channels.SelectionKey;
+import java.util.Optional;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.Supplier;
+
+import static java.lang.System.Logger.Level.ERROR;
+import static java.net.http.WSUtils.EMPTY_BYTE_BUFFER;
+import static java.net.http.WSUtils.logger;
+
+/*
+ * Receives incoming data from the channel and converts it into a sequence of
+ * messages, which are then passed to the listener.
+ */
+final class WSReceiver {
+
+    private final Listener listener;
+    private final WebSocket webSocket;
+    private final Supplier<WSShared<ByteBuffer>> buffersSupplier =
+            new WSSharedPool<>(() -> ByteBuffer.allocateDirect(32768), 2);
+    private final RawChannel channel;
+    private final RawChannel.NonBlockingEvent channelEvent;
+    private final WSSignalHandler handler;
+    private final AtomicLong demand = new AtomicLong();
+    private final AtomicBoolean readable = new AtomicBoolean();
+    private boolean started;
+    private volatile boolean closed;
+    private final WSFrame.Reader reader = new WSFrame.Reader();
+    private final WSFrameConsumer frameConsumer;
+    private WSShared<ByteBuffer> buf = WSShared.wrap(EMPTY_BYTE_BUFFER);
+    private WSShared<ByteBuffer> data; // TODO: initialize with leftovers from the RawChannel
+
+    WSReceiver(Listener listener, WebSocket webSocket, Executor executor,
+               RawChannel channel) {
+        this.listener = listener;
+        this.webSocket = webSocket;
+        this.channel = channel;
+        handler = new WSSignalHandler(executor, this::react);
+        channelEvent = createChannelEvent();
+        this.frameConsumer = new WSFrameConsumer(new MessageConsumer());
+    }
+
+    private void react() {
+        synchronized (this) {
+            while (demand.get() > 0 && !closed) {
+                try {
+                    if (data == null) {
+                        if (!getData()) {
+                            break;
+                        }
+                    }
+                    reader.readFrame(data, frameConsumer);
+                    if (!data.hasRemaining()) {
+                        data.dispose();
+                        data = null;
+                    }
+                    // In case of exception we don't need to clean any state,
+                    // since it's the terminal condition anyway. Nothing will be
+                    // retried.
+                } catch (WSProtocolException e) {
+                    // Translate into ProtocolException
+                    closeExceptionally(new ProtocolException().initCause(e));
+                } catch (Exception e) {
+                    closeExceptionally(e);
+                }
+            }
+        }
+    }
+
+    long request(long n) {
+        long newDemand = demand.accumulateAndGet(n, (p, i) -> p + i < 0 ? Long.MAX_VALUE : p + i);
+        handler.signal();
+        assert newDemand >= 0 : newDemand;
+        return newDemand;
+    }
+
+    private boolean getData() throws IOException {
+        if (!readable.get()) {
+            return false;
+        }
+        if (!buf.hasRemaining()) {
+            buf.dispose();
+            buf = buffersSupplier.get();
+            assert buf.hasRemaining() : buf;
+        }
+        int oldPosition = buf.position();
+        int oldLimit = buf.limit();
+        int numRead = channel.read(buf.buffer());
+        if (numRead > 0) {
+            data = buf.share(oldPosition, oldPosition + numRead);
+            buf.select(buf.limit(), oldLimit); // Move window to the free region
+            return true;
+        } else if (numRead == 0) {
+            readable.set(false);
+            channel.registerEvent(channelEvent);
+            return false;
+        } else {
+            assert numRead < 0 : numRead;
+            throw new WSProtocolException
+                    ("7.2.1.", "Stream ended before a Close frame has been received");
+        }
+    }
+
+    void start() {
+        synchronized (this) {
+            if (started) {
+                throw new IllegalStateException("Already started");
+            }
+            started = true;
+            try {
+                channel.registerEvent(channelEvent);
+            } catch (IOException e) {
+                throw new UncheckedIOException(e);
+            }
+            try {
+                listener.onOpen(webSocket);
+            } catch (Exception e) {
+                closeExceptionally(new RuntimeException("onOpen threw an exception", e));
+            }
+        }
+    }
+
+    private void close() { // TODO: move to WS.java
+        closed = true;
+    }
+
+    private void closeExceptionally(Throwable error) {  // TODO: move to WS.java
+        close();
+        try {
+            listener.onError(webSocket, error);
+        } catch (Exception e) {
+            logger.log(ERROR, "onError threw an exception", e);
+        }
+    }
+
+    private final class MessageConsumer implements WSMessageConsumer {
+
+        @Override
+        public void onText(WebSocket.MessagePart part, WSDisposableText data) {
+            decrementDemand();
+            CompletionStage<?> cs;
+            try {
+                cs = listener.onText(webSocket, data, part);
+            } catch (Exception e) {
+                closeExceptionally(new RuntimeException("onText threw an exception", e));
+                return;
+            }
+            follow(cs, data, "onText");
+        }
+
+        @Override
+        public void onBinary(WebSocket.MessagePart part, WSShared<ByteBuffer> data) {
+            decrementDemand();
+            CompletionStage<?> cs;
+            try {
+                cs = listener.onBinary(webSocket, data.buffer(), part);
+            } catch (Exception e) {
+                closeExceptionally(new RuntimeException("onBinary threw an exception", e));
+                return;
+            }
+            follow(cs, data, "onBinary");
+        }
+
+        @Override
+        public void onPing(WSShared<ByteBuffer> data) {
+            decrementDemand();
+            CompletionStage<?> cs;
+            try {
+                cs = listener.onPing(webSocket, data.buffer());
+            } catch (Exception e) {
+                closeExceptionally(new RuntimeException("onPing threw an exception", e));
+                return;
+            }
+            follow(cs, data, "onPing");
+        }
+
+        @Override
+        public void onPong(WSShared<ByteBuffer> data) {
+            decrementDemand();
+            CompletionStage<?> cs;
+            try {
+                cs = listener.onPong(webSocket, data.buffer());
+            } catch (Exception e) {
+                closeExceptionally(new RuntimeException("onPong threw an exception", e));
+                return;
+            }
+            follow(cs, data, "onPong");
+        }
+
+        @Override
+        public void onClose(WebSocket.CloseCode code, CharSequence reason) {
+            decrementDemand();
+            try {
+                close();
+                listener.onClose(webSocket, Optional.ofNullable(code), reason.toString());
+            } catch (Exception e) {
+                logger.log(ERROR, "onClose threw an exception", e);
+            }
+        }
+    }
+
+    private void follow(CompletionStage<?> cs, WSDisposable d, String source) {
+        if (cs == null) {
+            d.dispose();
+        } else {
+            cs.whenComplete((whatever, error) -> {
+                if (error != null) {
+                    String m = "CompletionStage returned by " + source + " completed exceptionally";
+                    closeExceptionally(new RuntimeException(m, error));
+                }
+                d.dispose();
+            });
+        }
+    }
+
+    private void decrementDemand() {
+        long newDemand = demand.decrementAndGet();
+        assert newDemand >= 0 : newDemand;
+    }
+
+    private RawChannel.NonBlockingEvent createChannelEvent() {
+        return new RawChannel.NonBlockingEvent() {
+
+            @Override
+            public int interestOps() {
+                return SelectionKey.OP_READ;
+            }
+
+            @Override
+            public void handle() {
+                boolean wasNotReadable = readable.compareAndSet(false, true);
+                assert wasNotReadable;
+                handler.signal();
+            }
+
+            @Override
+            public String toString() {
+                return "Read readiness event [" + channel + "]";
+            }
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WSShared.java	Thu May 12 11:03:07 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  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  License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General  License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+//
+//  +-----------+---------------+------------ ~ ------+
+//  |  shared#1 |    shared#2   | non-shared          |
+//  +-----------+---------------+------------ ~ ------+
+//  |                                                 |
+//  |<------------------  shared0  ---------- ~ ----->|
+//
+//
+// Objects of the type are not thread-safe. It's the responsibility of the
+// client to access shared buffers safely between threads.
+//
+// It would be perfect if we could extend java.nio.Buffer, but it's not an
+// option since Buffer and all its descendants have package-private
+// constructors.
+//
+abstract class WSShared<T extends Buffer> implements WSDisposable {
+
+    protected final AtomicBoolean disposed = new AtomicBoolean();
+    protected final T buffer;
+
+    protected WSShared(T buffer) {
+        this.buffer = Objects.requireNonNull(buffer);
+    }
+
+    static <T extends Buffer> WSShared<T> wrap(T buffer) {
+        return new WSShared<>(buffer) {
+            @Override
+            WSShared<T> share(int pos, int limit) {
+                throw new UnsupportedOperationException();
+            }
+        };
+    }
+
+    // TODO: should be a terminal operation as after it returns the buffer might
+    //       have escaped (we can't protect it any more)
+    public T buffer() {
+        checkDisposed();
+        return buffer;
+    }
+
+    abstract WSShared<T> share(final int pos, final int limit);
+
+    WSShared<T> select(final int pos, final int limit) {
+        checkRegion(pos, limit, buffer());
+        select(pos, limit, buffer());
+        return this;
+    }
+
+    @Override
+    public void dispose() {
+        if (!disposed.compareAndSet(false, true)) {
+            throw new IllegalStateException("Has been disposed previously");
+        }
+    }
+
+    int limit() {
+        return buffer().limit();
+    }
+
+    WSShared<T> limit(int newLimit) {
+        buffer().limit(newLimit);
+        return this;
+    }
+
+    int position() {
+        return buffer().position();
+    }
+
+    WSShared<T> position(int newPosition) {
+        buffer().position(newPosition);
+        return this;
+    }
+
+    int remaining() {
+        return buffer().remaining();
+    }
+
+    boolean hasRemaining() {
+        return buffer().hasRemaining();
+    }
+
+    WSShared<T> flip() {
+        buffer().flip();
+        return this;
+    }
+
+    WSShared<T> rewind() {
+        buffer().rewind();
+        return this;
+    }
+
+    WSShared<T> put(WSShared<? extends T> src) {
+        put(this.buffer(), src.buffer());
+        return this;
+    }
+
+    static void checkRegion(int position, int limit, Buffer buffer) {
+        if (position < 0 || position > buffer.capacity()) {
+            throw new IllegalArgumentException("position: " + position);
+        }
+        if (limit < 0 || limit > buffer.capacity()) {
+            throw new IllegalArgumentException("limit: " + limit);
+        }
+        if (limit < position) {
+            throw new IllegalArgumentException
+                    ("limit < position: limit=" + limit + ", position=" + position);
+        }
+    }
+
+    void select(int newPos, int newLim, Buffer buffer) {
+        int oldPos = buffer.position();
+        int oldLim = buffer.limit();
+        assert 0 <= oldPos && oldPos <= oldLim && oldLim <= buffer.capacity();
+        if (oldLim <= newPos) {
+            buffer().limit(newLim).position(newPos);
+        } else {
+            buffer.position(newPos).limit(newLim);
+        }
+    }
+
+    // The same as dst.put(src)
+    static <T extends Buffer> T put(T dst, T src) {
+        if (dst instanceof ByteBuffer) {
+            ((ByteBuffer) dst).put((ByteBuffer) src);
+        } else if (dst instanceof CharBuffer) {
+            ((CharBuffer) dst).put((CharBuffer) src);
+        } else {
+            // We don't work with buffers of other types
+            throw new IllegalArgumentException();
+        }
+        return dst;
+    }
+
+    // TODO: Remove when JDK-8150785 has been done
+    @SuppressWarnings("unchecked")
+    static <T extends Buffer> T slice(T buffer) {
+        if (buffer instanceof ByteBuffer) {
+            return (T) ((ByteBuffer) buffer).slice();
+        } else if (buffer instanceof CharBuffer) {
+            return (T) ((CharBuffer) buffer).slice();
+        } else {
+            // We don't work with buffers of other types
+            throw new IllegalArgumentException();
+        }
+    }
+
+    // TODO: Remove when JDK-8150785 has been done
+    @SuppressWarnings("unchecked")
+    static <T extends Buffer> T duplicate(T buffer) {
+        if (buffer instanceof ByteBuffer) {
+            return (T) ((ByteBuffer) buffer).duplicate();
+        } else if (buffer instanceof CharBuffer) {
+            return (T) ((CharBuffer) buffer).duplicate();
+        } else {
+            // We don't work with buffers of other types
+            throw new IllegalArgumentException();
+        }
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + "[" + WSUtils.toString(buffer()) + "]";
+    }
+
+    private void checkDisposed() {
+        if (disposed.get()) {
+            throw new IllegalStateException("Has been disposed previously");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WSSharedPool.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,148 @@
+/*
+ * 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  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  License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General  License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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.nio.Buffer;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Supplier;
+
+import static java.lang.System.Logger.Level.TRACE;
+import static java.net.http.WSShared.duplicate;
+import static java.net.http.WSUtils.logger;
+import static java.util.Objects.requireNonNull;
+
+final class WSSharedPool<T extends Buffer> implements Supplier<WSShared<T>> {
+
+    private final Supplier<T> factory;
+    private final BlockingQueue<T> queue;
+
+    WSSharedPool(Supplier<T> factory, int maxPoolSize) {
+        this.factory = requireNonNull(factory);
+        this.queue = new LinkedBlockingQueue<>(maxPoolSize);
+    }
+
+    @Override
+    public Pooled get() {
+        T b = queue.poll();
+        if (b == null) {
+            logger.log(TRACE, "Pool {0} contains no free buffers", this);
+            b = requireNonNull(factory.get());
+        }
+        Pooled buf = new Pooled(new AtomicInteger(1), b, duplicate(b));
+        logger.log(TRACE, "Pool {0} created new buffer {1}", this, buf);
+        return buf;
+    }
+
+    private void put(Pooled b) {
+        assert b.disposed.get() && b.refCount.get() == 0
+                : WSUtils.dump(b.disposed, b.refCount, b);
+        b.shared.clear();
+        boolean accepted = queue.offer(b.getShared());
+        if (logger.isLoggable(TRACE)) {
+            if (accepted) {
+                logger.log(TRACE, "Pool {0} accepted {1}", this, b);
+            } else {
+                logger.log(TRACE, "Pool {0} discarded {1}", this, b);
+            }
+        }
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + "[queue.size=" + queue.size() + "]";
+    }
+
+    private final class Pooled extends WSShared<T> {
+
+        private final AtomicInteger refCount;
+        private final T shared;
+
+        private Pooled(AtomicInteger refCount, T shared, T region) {
+            super(region);
+            this.refCount = refCount;
+            this.shared = shared;
+        }
+
+        private T getShared() {
+            return shared;
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public Pooled share(final int pos, final int limit) {
+            synchronized (this) {
+                T buffer = buffer();
+                checkRegion(pos, limit, buffer);
+                final int oldPos = buffer.position();
+                final int oldLimit = buffer.limit();
+                select(pos, limit, buffer);
+                T slice = WSShared.slice(buffer);
+                select(oldPos, oldLimit, buffer);
+                referenceAndGetCount();
+                Pooled buf = new Pooled(refCount, shared, slice);
+                logger.log(TRACE, "Shared {0} from {1}", buf, this);
+                return buf;
+            }
+        }
+
+        @Override
+        public void dispose() {
+            logger.log(TRACE, "Disposed {0}", this);
+            super.dispose();
+            if (dereferenceAndGetCount() == 0) {
+                WSSharedPool.this.put(this);
+            }
+        }
+
+        private int referenceAndGetCount() {
+            return refCount.updateAndGet(n -> {
+                if (n != Integer.MAX_VALUE) {
+                    return n + 1;
+                } else {
+                    throw new IllegalArgumentException
+                            ("Too many references: " + this);
+                }
+            });
+        }
+
+        private int dereferenceAndGetCount() {
+            return refCount.updateAndGet(n -> {
+                if (n > 0) {
+                    return n - 1;
+                } else {
+                    throw new InternalError();
+                }
+            });
+        }
+
+        @Override
+        public String toString() {
+            return WSUtils.toStringSimple(this) + "[" + WSUtils.toString(buffer)
+                    + "[refCount=" + refCount + ", disposed=" + disposed + "]]";
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WSSignalHandler.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,137 @@
+/*
+ * 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  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  License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General  License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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.concurrent.Executor;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static java.util.Objects.requireNonNull;
+
+//
+// The problem:
+// ------------
+//   1. For every invocation of 'signal()' there must be at least
+//      1 invocation of 'handler.run()' that goes after
+//   2. There must be no more than 1 thread running the 'handler.run()'
+//      at any given time
+//
+// For example, imagine each signal increments (+1) some number. Then the
+// handler responds (eventually) the way that makes the number 0.
+//
+// For each signal there's a response. Several signals may be handled by a
+// single response.
+//
+final class WSSignalHandler {
+
+    // In this state the task is neither submitted nor running.
+    // No one is handling signals. If a new signal has been received, the task
+    // has to be submitted to the executor in order to handle this signal.
+    private static final int DONE    = 0;
+
+    // In this state the task is running.
+    // * If the signaller has found the task in this state it will try to change
+    //   the state to RERUN in order to make the already running task to handle
+    //   the new signal before exiting.
+    // * If the task has found itself in this state it will exit.
+    private static final int RUNNING = 1;
+
+    // A signal to the task, that it must rerun on the spot (without being
+    // resubmitted to the executor).
+    // If the task has found itself in this state it resets the state to
+    // RUNNING and repeats the pass.
+    private static final int RERUN   = 2;
+
+    private final AtomicInteger state = new AtomicInteger(DONE);
+
+    private final Executor executor;
+    private final Runnable task;
+
+    WSSignalHandler(Executor executor, Runnable handler) {
+        this.executor = requireNonNull(executor);
+        requireNonNull(handler);
+
+        task = () -> {
+            while (!Thread.currentThread().isInterrupted()) {
+
+                try {
+                    handler.run();
+                } catch (Exception e) {
+                    // Sorry, the task won't be automatically retried;
+                    // hope next signals (if any) will kick off the handling
+                    state.set(DONE);
+                    throw e;
+                }
+
+                int prev = state.getAndUpdate(s -> {
+                    if (s == RUNNING) {
+                        return DONE;
+                    } else {
+                        return RUNNING;
+                    }
+                });
+
+                // Can't be DONE, since only the task itself may transit state
+                // into DONE (with one exception: RejectedExecution in signal();
+                // but in that case we couldn't be here at all)
+                assert prev == RUNNING || prev == RERUN;
+
+                if (prev == RUNNING) {
+                    break;
+                }
+            }
+        };
+    }
+
+    // Invoked by outer code to signal
+    void signal() {
+
+        int prev = state.getAndUpdate(s -> {
+            switch (s) {
+                case RUNNING:
+                    return RERUN;
+                case DONE:
+                    return RUNNING;
+                case RERUN:
+                    return RERUN;
+                default:
+                    throw new InternalError(String.valueOf(s));
+            }
+        });
+
+        if (prev != DONE) {
+            // Nothing to do! piggybacking on previous signal
+            return;
+        }
+        try {
+            executor.execute(task);
+        } catch (RejectedExecutionException e) {
+            // Sorry some signal() invocations may have been accepted, but won't
+            // be done, since the 'task' couldn't be submitted
+            state.set(DONE);
+            throw e;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WSTransmitter.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,176 @@
+/*
+ * 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  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  License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General  License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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.net.http.WSOutgoingMessage.Binary;
+import java.net.http.WSOutgoingMessage.Close;
+import java.net.http.WSOutgoingMessage.Ping;
+import java.net.http.WSOutgoingMessage.Pong;
+import java.net.http.WSOutgoingMessage.StreamedText;
+import java.net.http.WSOutgoingMessage.Text;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.CoderResult;
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.function.Consumer;
+import java.util.stream.Stream;
+
+import static java.lang.String.format;
+import static java.net.http.Pair.pair;
+
+/*
+ * Prepares outgoing messages for transmission.  Verifies the WebSocket state,
+ * places the message on the outbound queue, and notifies the signal handler.
+ */
+final class WSTransmitter {
+
+    private final BlockingQueue<Pair<WSOutgoingMessage, CompletableFuture<Void>>>
+            backlog = new LinkedBlockingQueue<>();
+    private final WSMessageSender sender;
+    private final WSSignalHandler handler;
+    private boolean previousMessageSent = true;
+    private boolean canSendBinary = true;
+    private boolean canSendText = true;
+
+    WSTransmitter(Executor executor, RawChannel channel, Consumer<Throwable> errorHandler) {
+        this.handler = new WSSignalHandler(executor, this::handleSignal);
+        Consumer<Throwable> sendCompletion = (error) -> {
+            synchronized (this) {
+                if (error == null) {
+                    previousMessageSent = true;
+                    handler.signal();
+                } else {
+                    errorHandler.accept(error);
+                    backlog.forEach(p -> p.second.completeExceptionally(error));
+                    backlog.clear();
+                }
+            }
+        };
+        this.sender = new WSMessageSender(channel, sendCompletion);
+    }
+
+    CompletableFuture<Void> sendText(CharSequence message, boolean isLast) {
+        checkAndUpdateText(isLast);
+        return acceptMessage(new Text(isLast, message));
+    }
+
+    CompletableFuture<Void> sendText(Stream<? extends CharSequence> message) {
+        checkAndUpdateText(true);
+        return acceptMessage(new StreamedText(message));
+    }
+
+    CompletableFuture<Void> sendBinary(ByteBuffer message, boolean isLast) {
+        checkAndUpdateBinary(isLast);
+        return acceptMessage(new Binary(isLast, message));
+    }
+
+    CompletableFuture<Void> sendPing(ByteBuffer message) {
+        checkSize(message.remaining(), 125);
+        return acceptMessage(new Ping(message));
+    }
+
+    CompletableFuture<Void> sendPong(ByteBuffer message) {
+        checkSize(message.remaining(), 125);
+        return acceptMessage(new Pong(message));
+    }
+
+    CompletableFuture<Void> sendClose(WebSocket.CloseCode code, CharSequence reason) {
+        return acceptMessage(createCloseMessage(code, reason));
+    }
+
+    CompletableFuture<Void> sendClose() {
+        return acceptMessage(new Close(ByteBuffer.allocate(0)));
+    }
+
+    private CompletableFuture<Void> acceptMessage(WSOutgoingMessage m) {
+        CompletableFuture<Void> cf = new CompletableFuture<>();
+        synchronized (this) {
+            backlog.offer(pair(m, cf));
+        }
+        handler.signal();
+        return cf;
+    }
+
+    /* Callback for pulling messages from the queue, and initiating the send. */
+    private void handleSignal() {
+        synchronized (this) {
+            while (!backlog.isEmpty() && previousMessageSent) {
+                previousMessageSent = false;
+                Pair<WSOutgoingMessage, CompletableFuture<Void>> p = backlog.peek();
+                boolean sent = sender.trySendFully(p.first);
+                if (sent) {
+                    backlog.remove();
+                    p.second.complete(null);
+                    previousMessageSent = true;
+                }
+            }
+        }
+    }
+
+    private Close createCloseMessage(WebSocket.CloseCode code, CharSequence reason) {
+        // TODO: move to construction of CloseDetail (JDK-8155621)
+        ByteBuffer b = ByteBuffer.allocateDirect(125).putChar((char) code.getCode());
+        CoderResult result = StandardCharsets.UTF_8.newEncoder()
+                .encode(CharBuffer.wrap(reason), b, true);
+        if (result.isError()) {
+            try {
+                result.throwException();
+            } catch (CharacterCodingException e) {
+                throw new IllegalArgumentException("Reason is a malformed UTF-16 sequence", e);
+            }
+        } else if (result.isOverflow()) {
+            throw new IllegalArgumentException("Reason is too long");
+        }
+        return new Close(b.flip());
+    }
+
+    private void checkSize(int size, int maxSize) {
+        if (size > maxSize) {
+            throw new IllegalArgumentException(
+                    format("The message is too long: %s;" +
+                            " expected not longer than %s", size, maxSize)
+            );
+        }
+    }
+
+    private void checkAndUpdateText(boolean isLast) {
+        if (!canSendText) {
+            throw new IllegalStateException("Unexpected text message");
+        }
+        canSendBinary = isLast;
+    }
+
+    private void checkAndUpdateBinary(boolean isLast) {
+        if (!canSendBinary) {
+            throw new IllegalStateException("Unexpected binary message");
+        }
+        canSendText = isLast;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WSUtils.java	Thu May 12 11:03:07 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  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  License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General  License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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.net.URI;
+import java.net.URISyntaxException;
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+final class WSUtils {
+
+    private WSUtils() { }
+
+    static final System.Logger logger = System.getLogger("java.net.http.WebSocket");
+    static final ByteBuffer EMPTY_BYTE_BUFFER = ByteBuffer.allocate(0);
+
+    //
+    // 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 String webSocketSpecViolation(String section, String detail) {
+        return "RFC 6455 " + section + " " + detail;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WSWriter.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,134 @@
+/*
+ * 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  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  License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General  License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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.nio.ByteBuffer;
+import java.nio.channels.SelectionKey;
+import java.util.function.Consumer;
+
+import static java.util.Objects.requireNonNull;
+
+/*
+ * Writes ByteBuffer[] to the channel in a non-blocking, asynchronous fashion.
+ *
+ * A client attempts to write data by calling
+ *
+ *     boolean tryWriteFully(ByteBuffer[] buffers)
+ *
+ * If the attempt was successful and all the data has been written, then the
+ * method returns `true`.
+ *
+ * If the data has been written partially, then the method returns `false`, and
+ * the writer (this object) attempts to complete the write asynchronously by
+ * calling, possibly more than once
+ *
+ *     boolean tryCompleteWrite()
+ *
+ * in its own threads.
+ *
+ * When the write has been completed asynchronously, the callback is signalled
+ * with `null`.
+ *
+ * If an error occurs in any of these stages it will NOT be thrown from the
+ * method. Instead `false` will be returned and the exception will be signalled
+ * to the callback. This is done in order to handle all exceptions in a single
+ * place.
+ */
+final class WSWriter {
+
+    private final RawChannel channel;
+    private final RawChannel.NonBlockingEvent writeReadinessHandler;
+    private final Consumer<Throwable> completionCallback;
+    private ByteBuffer[] buffers;
+    private int offset;
+
+    WSWriter(RawChannel channel, Consumer<Throwable> completionCallback) {
+        this.channel = channel;
+        this.completionCallback = completionCallback;
+        this.writeReadinessHandler = createHandler();
+    }
+
+    boolean tryWriteFully(ByteBuffer[] buffers) {
+        synchronized (this) {
+            this.buffers = requireNonNull(buffers);
+            this.offset = 0;
+        }
+        return tryCompleteWrite();
+    }
+
+    private final boolean tryCompleteWrite() {
+        try {
+            return writeNow();
+        } catch (IOException e) {
+            completionCallback.accept(e);
+            return false;
+        }
+    }
+
+    private boolean writeNow() throws IOException {
+        synchronized (this) {
+            for (; offset != -1; offset = nextUnwrittenIndex(buffers, offset)) {
+                long bytesWritten = channel.write(buffers, offset, buffers.length - offset);
+                if (bytesWritten == 0) {
+                    channel.registerEvent(writeReadinessHandler);
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
+    private static int nextUnwrittenIndex(ByteBuffer[] buffers, int offset) {
+        for (int i = offset; i < buffers.length; i++) {
+            if (buffers[i].hasRemaining()) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    private RawChannel.NonBlockingEvent createHandler() {
+        return new RawChannel.NonBlockingEvent() {
+
+            @Override
+            public int interestOps() {
+                return SelectionKey.OP_WRITE;
+            }
+
+            @Override
+            public void handle() {
+                if (tryCompleteWrite()) {
+                    completionCallback.accept(null);
+                }
+            }
+
+            @Override
+            public String toString() {
+                return "Write readiness event [" + channel + "]";
+            }
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WebSocket.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,1288 @@
+/*
+ * 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 java.net.http;
+
+import java.io.IOException;
+import java.net.ProtocolException;
+import java.net.URI;
+import java.nio.ByteBuffer;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Stream;
+
+/**
+ * A WebSocket client conforming to RFC&nbsp;6455.
+ *
+ * <p> A {@code WebSocket} provides full-duplex communication over a TCP
+ * connection.
+ *
+ * <p> To create a {@code WebSocket} use a {@linkplain #newBuilder(URI, Listener)
+ * builder}. Once a {@code WebSocket} is obtained, it's ready to send and
+ * receive messages. When the {@code WebSocket} is no longer
+ * needed it must be closed: a Close message must both be {@linkplain
+ * #sendClose() sent} and {@linkplain Listener#onClose(WebSocket, Optional,
+ * String) received}. Or to close abruptly, {@link #abort()} is called. Once
+ * closed it remains closed, cannot be reopened.
+ *
+ * <p> Messages of type {@code X} are sent through the {@code WebSocket.sendX}
+ * methods and received through {@link WebSocket.Listener}{@code .onX} methods
+ * asynchronously. Each of the methods begins the operation and returns a {@link
+ * CompletionStage} which completes when the operation has completed.
+ *
+ * <p> Messages are received only if {@linkplain #request(long) requested}.
+ *
+ * <p> One outstanding send operation is permitted: if another send operation is
+ * initiated before the previous one has completed, an {@link
+ * IllegalStateException IllegalStateException} will be thrown. When sending, a
+ * message should not be modified until the returned {@code CompletableFuture}
+ * completes (either normally or exceptionally).
+ *
+ * <p> Messages can be sent and received as a whole or in parts. A whole message
+ * is a sequence of one or more messages in which the last message is marked
+ * when it is sent or received.
+ *
+ * <p> If the message is contained in a {@link ByteBuffer}, bytes are considered
+ * arranged from the {@code buffer}'s {@link ByteBuffer#position() position} to
+ * the {@code buffer}'s {@link ByteBuffer#limit() limit}.
+ *
+ * <p> All message exchange is run by the threads belonging to the {@linkplain
+ * HttpClient#executorService() executor service} of {@code WebSocket}'s {@link
+ * HttpClient}.
+ *
+ * <p> Unless otherwise noted, passing a {@code null} argument to a constructor
+ * or method of this type will cause a {@link NullPointerException
+ * NullPointerException} to be thrown.
+ *
+ * @since 9
+ */
+public interface WebSocket {
+
+    /**
+     * Creates a builder of {@code WebSocket}s connected to the given URI and
+     * receiving events with the given {@code Listener}.
+     *
+     * <p> Equivalent to:
+     * <pre>{@code
+     *     WebSocket.newBuilder(uri, HttpClient.getDefault())
+     * }</pre>
+     *
+     * @param uri
+     *         the WebSocket URI as defined in the WebSocket Protocol
+     *         (with "ws" or "wss" scheme)
+     *
+     * @param listener
+     *         the listener
+     *
+     * @throws IllegalArgumentException
+     *         if the {@code uri} is not a WebSocket URI
+     * @throws SecurityException
+     *         if running under a security manager and the caller does
+     *         not have permission to access the
+     *         {@linkplain HttpClient#getDefault() default HttpClient}
+     *
+     * @return a builder
+     */
+    static Builder newBuilder(URI uri, Listener listener) {
+        return newBuilder(uri, HttpClient.getDefault(), listener);
+    }
+
+    /**
+     * Creates a builder of {@code WebSocket}s connected to the given URI and
+     * receiving events with the given {@code Listener}.
+     *
+     * <p> Providing a custom {@code client} allows for finer control over the
+     * opening handshake.
+     *
+     * <p> <b>Example</b>
+     * <pre>{@code
+     *     HttpClient client = HttpClient.create()
+     *             .proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 80)))
+     *             .build();
+     *     ...
+     *     WebSocket.newBuilder(URI.create("ws://websocket.example.com"), client, listener)...
+     * }</pre>
+     *
+     * @param uri
+     *         the WebSocket URI as defined in the WebSocket Protocol
+     *         (with "ws" or "wss" scheme)
+     *
+     * @param client
+     *         the HttpClient
+     * @param listener
+     *         the listener
+     *
+     * @throws IllegalArgumentException
+     *         if the uri is not a WebSocket URI
+     *
+     * @return a builder
+     */
+    static Builder newBuilder(URI uri, HttpClient client, Listener listener) {
+        return new WSBuilder(uri, client, listener);
+    }
+
+    /**
+     * A builder for creating {@code WebSocket} instances.
+     *
+     * <p> To build a {@code WebSocket}, instantiate a builder, configure it
+     * as required by calling intermediate methods (the ones that return the
+     * builder itself), then finally call {@link #buildAsync()} to get a {@link
+     * CompletableFuture} with resulting {@code WebSocket}.
+     *
+     * <p> If an intermediate method has not been called, an appropriate
+     * default value (or behavior) will be used. Unless otherwise noted, a
+     * repeated call to an intermediate method overwrites the previous value (or
+     * overrides the previous behaviour), if no exception is thrown.
+     *
+     * <p> Instances of {@code Builder} may not be safe for use by multiple
+     * threads.
+     *
+     * @since 9
+     */
+    interface Builder {
+
+        /**
+         * Adds the given name-value pair to the list of additional headers for
+         * the opening handshake.
+         *
+         * <p> Headers defined in WebSocket Protocol are not allowed to be added.
+         *
+         * @param name
+         *         the header name
+         * @param value
+         *         the header value
+         *
+         * @return this builder
+         *
+         * @throws IllegalArgumentException
+         *         if the {@code name} is a WebSocket defined header name
+         */
+        Builder header(String name, String value);
+
+        /**
+         * Includes a request for the given subprotocols during the opening
+         * handshake.
+         *
+         * <p> Among the requested subprotocols at most one will be chosen by
+         * the server. When the {@code WebSocket} is connected, the subprotocol
+         * in use is available from {@link WebSocket#getSubprotocol}.
+         * Subprotocols may be specified in the order of preference.
+         *
+         * <p> Each of the given subprotocols must conform to the relevant
+         * rules defined in the WebSocket Protocol.
+         *
+         * @param mostPreferred
+         *         the most preferred subprotocol
+         * @param lesserPreferred
+         *         the lesser preferred subprotocols, with the least preferred
+         *         at the end
+         *
+         * @return this builder
+         *
+         * @throws IllegalArgumentException
+         *         if any of the WebSocket Protocol rules relevant to
+         *         subprotocols are violated
+         */
+        Builder subprotocols(String mostPreferred, String... lesserPreferred);
+
+        /**
+         * Sets a timeout for the opening handshake.
+         *
+         * <p> If the opening handshake is not finished within the specified
+         * timeout then {@link #buildAsync()} completes exceptionally with a
+         * {@code HttpTimeoutException}.
+         *
+         * <p> If the timeout is not specified then it's deemed infinite.
+         *
+         * @param timeout
+         *         the maximum time to wait
+         * @param unit
+         *         the time unit of the timeout argument
+         *
+         * @return this builder
+         *
+         * @throws IllegalArgumentException
+         *         if the {@code timeout} is negative
+         */
+        Builder connectTimeout(long timeout, TimeUnit unit);
+
+        /**
+         * Builds a {@code WebSocket}.
+         *
+         * <p> Returns immediately with a {@code CompletableFuture<WebSocket>}
+         * which completes with the {@code WebSocket} when it is connected, or
+         * completes exceptionally if an error occurs.
+         *
+         * <p> {@code CompletableFuture} may complete exceptionally with the
+         * following errors:
+         * <ul>
+         * <li> {@link IOException}
+         *          if an I/O error occurs
+         * <li> {@link InterruptedException}
+         *          if the operation was interrupted
+         * <li> {@link SecurityException}
+         *          if a security manager is set, and the caller does not
+         *          have a {@link java.net.URLPermission} for the WebSocket URI
+         * <li> {@link WebSocketHandshakeException}
+         *          if the opening handshake fails
+         * </ul>
+         *
+         * @return a {@code CompletableFuture} of {@code WebSocket}
+         */
+        CompletableFuture<WebSocket> buildAsync();
+    }
+
+    /**
+     * A listener for events and messages on a {@code WebSocket}.
+     *
+     * <p> Each method below corresponds to a type of event.
+     * <ul>
+     * <li> {@link #onOpen onOpen} <br>
+     * This method is always the first to be invoked.
+     * <li> {@link #onText(WebSocket, WebSocket.Text, WebSocket.MessagePart)
+     * onText}, {@link #onBinary(WebSocket, ByteBuffer, WebSocket.MessagePart)
+     * onBinary}, {@link #onPing(WebSocket, ByteBuffer) onPing} and {@link
+     * #onPong(WebSocket, ByteBuffer) onPong} <br>
+     * These methods are invoked zero or more times after {@code onOpen}.
+     * <li> {@link #onClose(WebSocket, Optional, String) onClose}, {@link
+     * #onError(WebSocket, Throwable) onError} <br>
+     * Only one of these methods is invoked, and that method is invoked last and
+     * at most once.
+     * </ul>
+     *
+     * <pre><code>
+     *     onOpen (onText|onBinary|onPing|onPong)* (onClose|onError)?
+     * </code></pre>
+     *
+     * <p> Messages received by the {@code Listener} conform to the WebSocket
+     * Protocol, otherwise {@code onError} with a {@link ProtocolException} is
+     * invoked.
+     *
+     * <p> If a whole message is received, then the corresponding method
+     * ({@code onText} or {@code onBinary}) will be invoked with {@link
+     * WebSocket.MessagePart#WHOLE WHOLE} marker. Otherwise the method will be
+     * invoked with {@link WebSocket.MessagePart#FIRST FIRST}, zero or more
+     * times with {@link WebSocket.MessagePart#FIRST PART} and, finally, with
+     * {@link WebSocket.MessagePart#LAST LAST} markers.
+     *
+     * <pre><code>
+     *     WHOLE|(FIRST PART* LAST)
+     * </code></pre>
+     *
+     * <p> All methods are invoked in a sequential (and
+     * <a href="../../../java/util/concurrent/package-summary.html#MemoryVisibility">
+     * happens-before</a>) order, one after another, possibly by different
+     * threads. If any of the methods above throws an exception, {@code onError}
+     * is then invoked with that exception. Exceptions thrown from {@code
+     * onError} or {@code onClose} are ignored.
+     *
+     * <p> When the method returns, the message is deemed received. After this
+     * another messages may be received.
+     *
+     * <p> These invocations begin asynchronous processing which might not end
+     * with the invocation. To provide coordination, methods of {@code
+     * Listener} return a {@link CompletionStage CompletionStage}. The {@code
+     * CompletionStage} signals the {@code WebSocket} that the
+     * processing of a message has ended. For
+     * convenience, methods may return {@code null}, which means
+     * the same as returning an already completed {@code CompletionStage}. If
+     * the returned {@code CompletionStage} completes exceptionally, then {@link
+     * #onError(WebSocket, Throwable) onError} will be invoked with the
+     * exception.
+     *
+     * <p> Control of the message passes to the {@code Listener} with the
+     * invocation of the method. Control of the message returns to the {@code
+     * WebSocket} at the earliest of, either returning {@code null} from the
+     * method, or the completion of the {@code CompletionStage} returned from
+     * the method. The {@code WebSocket} does not access the message while it's
+     * not in its control. The {@code Listener} must not access the message
+     * after its control has been returned to the {@code WebSocket}.
+     *
+     * <p> It is the responsibility of the listener to make additional
+     * {@linkplain WebSocket#request(long) message requests}, when ready, so
+     * that messages are received eventually.
+     *
+     * <p> Methods above are never invoked with {@code null}s as their
+     * arguments.
+     *
+     * @since 9
+     */
+    interface Listener {
+
+        /**
+         * Notifies the {@code Listener} that it is connected to the provided
+         * {@code WebSocket}.
+         *
+         * <p> The {@code onOpen} method does not correspond to any message
+         * from the WebSocket Protocol. It is a synthetic event. It is the first
+         * {@code Listener}'s method to be invoked. No other {@code Listener}'s
+         * methods are invoked before this one. The method is usually used to
+         * make an initial {@linkplain WebSocket#request(long) request} for
+         * messages.
+         *
+         * <p> If an exception is thrown from this method then {@link
+         * #onError(WebSocket, Throwable) onError} will be invoked with the
+         * exception.
+         *
+         * @implSpec The default implementation {@linkplain WebSocket#request(long)
+         * requests one message}.
+         *
+         * @param webSocket
+         *         the WebSocket
+         */
+        default void onOpen(WebSocket webSocket) { webSocket.request(1); }
+
+        /**
+         * Receives a Text message.
+         *
+         * <p> The {@code onText} method is invoked zero or more times between
+         * {@code onOpen} and ({@code onClose} or {@code onError}).
+         *
+         * <p> This message may be a partial UTF-16 sequence. However, the
+         * concatenation of all messages through the last will be a whole UTF-16
+         * sequence.
+         *
+         * <p> If an exception is thrown from this method or the returned {@code
+         * CompletionStage} completes exceptionally, then {@link
+         * #onError(WebSocket, Throwable) onError} will be invoked with the
+         * exception.
+         *
+         * @implSpec The default implementation {@linkplain WebSocket#request(long)
+         * requests one more message}.
+         *
+         * @param webSocket
+         *         the WebSocket
+         * @param message
+         *         the message
+         * @param part
+         *         the part
+         *
+         * @return a CompletionStage that completes when the message processing
+         * is done; or {@code null} if already done
+         */
+        default CompletionStage<?> onText(WebSocket webSocket,
+                                          Text message,
+                                          MessagePart part) {
+            webSocket.request(1);
+            return null;
+        }
+
+        /**
+         * Receives a Binary message.
+         *
+         * <p> The {@code onBinary} method is invoked zero or more times
+         * between {@code onOpen} and ({@code onClose} or {@code onError}).
+         *
+         * <p> If an exception is thrown from this method or the returned {@code
+         * CompletionStage} completes exceptionally, then {@link
+         * #onError(WebSocket, Throwable) onError} will be invoked with this
+         * exception.
+         *
+         * @implSpec The default implementation {@linkplain WebSocket#request(long)
+         * requests one more message}.
+         *
+         * @param webSocket
+         *         the WebSocket
+         * @param message
+         *         the message
+         * @param part
+         *         the part
+         *
+         * @return a CompletionStage that completes when the message processing
+         * is done; or {@code null} if already done
+         */
+        default CompletionStage<?> onBinary(WebSocket webSocket,
+                                            ByteBuffer message,
+                                            MessagePart part) {
+            webSocket.request(1);
+            return null;
+        }
+
+        /**
+         * Receives a Ping message.
+         *
+         * <p> A Ping message may be sent or received by either client or
+         * server. It may serve either as a keepalive or as a means to verify
+         * that the remote endpoint is still responsive.
+         *
+         * <p> The message will consist of not more than {@code 125} bytes:
+         * {@code message.remaining() <= 125}.
+         *
+         * <p> The {@code onPing} is invoked zero or more times in between
+         * {@code onOpen} and ({@code onClose} or {@code onError}).
+         *
+         * <p> If an exception is thrown from this method or the returned {@code
+         * CompletionStage} completes exceptionally, then {@link
+         * #onError(WebSocket, Throwable) onError} will be invoked with this
+         * exception.
+         *
+         * @implNote
+         *
+         * <p> Replies with a Pong message and requests one more message when
+         * the Pong has been sent.
+         *
+         * @param webSocket
+         *         the WebSocket
+         * @param message
+         *         the message
+         *
+         * @return a CompletionStage that completes when the message processing
+         * is done; or {@code null} if already done
+         */
+        default CompletionStage<?> onPing(WebSocket webSocket,
+                                          ByteBuffer message) {
+            return webSocket.sendPong(message).thenRun(() -> webSocket.request(1));
+        }
+
+        /**
+         * Receives a Pong message.
+         *
+         * <p> A Pong message may be unsolicited or may be received in response
+         * to a previously sent Ping. In the latter case, the contents of the
+         * Pong is identical to the originating Ping.
+         *
+         * <p> The message will consist of not more than {@code 125} bytes:
+         * {@code message.remaining() <= 125}.
+         *
+         * <p> The {@code onPong} method is invoked zero or more times in
+         * between {@code onOpen} and ({@code onClose} or {@code onError}).
+         *
+         * <p> If an exception is thrown from this method or the returned {@code
+         * CompletionStage} completes exceptionally, then {@link
+         * #onError(WebSocket, Throwable) onError} will be invoked with this
+         * exception.
+         *
+         * @implSpec The default implementation {@linkplain WebSocket#request(long)
+         * requests one more message}.
+         *
+         * @param webSocket
+         *         the WebSocket
+         * @param message
+         *         the message
+         *
+         * @return a CompletionStage that completes when the message processing
+         * is done; or {@code null} if already done
+         */
+        default CompletionStage<?> onPong(WebSocket webSocket,
+                                          ByteBuffer message) {
+            webSocket.request(1);
+            return null;
+        }
+
+        /**
+         * Receives a Close message.
+         *
+         * <p> Once a Close message is received, the server will not send any
+         * more messages.
+         *
+         * <p> A Close message may consist of a close code and a reason for
+         * closing. The reason will have a UTF-8 representation not longer than
+         * {@code 123} bytes. The reason may be useful for debugging or passing
+         * information relevant to the connection but is not necessarily human
+         * readable.
+         *
+         * <p> {@code onClose} is the last invocation on the {@code Listener}.
+         * It is invoked at most once, but after {@code onOpen}. If an exception
+         * is thrown from this method, it is ignored.
+         *
+         * @implSpec The default implementation does nothing.
+         *
+         * @param webSocket
+         *         the WebSocket
+         * @param code
+         *         an {@code Optional} describing the close code, or
+         *         an empty {@code Optional} if the message doesn't contain it
+         * @param reason
+         *         the reason of close; can be empty
+         */
+        default void onClose(WebSocket webSocket, Optional<CloseCode> code,
+                             String reason) { }
+
+        /**
+         * Notifies an I/O or protocol error has occurred on the {@code
+         * WebSocket}.
+         *
+         * <p> The {@code onError} method does not correspond to any message
+         * from the WebSocket Protocol. It is a synthetic event. {@code onError}
+         * is the last invocation on the {@code Listener}. It is invoked at most
+         * once but after {@code onOpen}. If an exception is thrown from this
+         * method, it is ignored.
+         *
+         * <p> The WebSocket Protocol requires some errors occurs in the
+         * incoming destination must be fatal to the connection. In such cases
+         * the implementation takes care of closing the {@code WebSocket}. By
+         * the time {@code onError} is invoked, no more messages can be sent on
+         * this {@code WebSocket}.
+         *
+         * @apiNote Errors associated with send operations ({@link
+         * WebSocket#sendText(CharSequence, boolean) sendText}, {@link
+         * #sendBinary(ByteBuffer, boolean) sendBinary}, {@link
+         * #sendPing(ByteBuffer) sendPing}, {@link #sendPong(ByteBuffer)
+         * sendPong} and {@link #sendClose(CloseCode, CharSequence) sendClose})
+         * are reported to the {@code CompletionStage} operations return.
+         *
+         * @implSpec The default implementation does nothing.
+         *
+         * @param webSocket
+         *         the WebSocket
+         * @param error
+         *         the error
+         */
+        default void onError(WebSocket webSocket, Throwable error) { }
+    }
+
+    /**
+     * A marker used by {@link WebSocket.Listener} for partial message
+     * receiving.
+     *
+     * @since 9
+     */
+    enum MessagePart {
+
+        /**
+         * The first part of a message in a sequence.
+         */
+        FIRST,
+
+        /**
+         * A middle part of a message in a sequence.
+         */
+        PART,
+
+        /**
+         * The last part of a message in a sequence.
+         */
+        LAST,
+
+        /**
+         * A whole message. The message consists of a single part.
+         */
+        WHOLE;
+
+        /**
+         * Tells whether a part of a message received with this marker is the
+         * last part.
+         *
+         * @return {@code true} if LAST or WHOLE, {@code false} otherwise
+         */
+        public boolean isLast() {
+            return this == LAST || this == WHOLE;
+        }
+    }
+
+    /**
+     * Sends a Text message with bytes from the given {@code ByteBuffer}.
+     *
+     * <p> Returns immediately with a {@code CompletableFuture<Void>} which
+     * completes normally when the message has been sent, or completes
+     * exceptionally if an error occurs.
+     *
+     * <p> This message may be a partial UTF-8 sequence. However, the
+     * concatenation of all messages through the last must be a whole UTF-8
+     * sequence.
+     *
+     * <p> The {@code ByteBuffer} should not be modified until the returned
+     * {@code CompletableFuture} completes (either normally or exceptionally).
+     *
+     * <p> The returned {@code CompletableFuture} can complete exceptionally
+     * with:
+     * <ul>
+     * <li> {@link IOException}
+     *          if an I/O error occurs during this operation; or the
+     *          {@code WebSocket} closes while this operation is in progress;
+     *          or the {@code message} is a malformed UTF-8 sequence
+     * </ul>
+     *
+     * @param message
+     *         the message
+     * @param isLast
+     *         {@code true} if this is the final part of the message,
+     *         {@code false} otherwise
+     *
+     * @return a CompletableFuture of Void
+     *
+     * @throws IllegalStateException
+     *         if the WebSocket is closed
+     * @throws IllegalStateException
+     *         if a Close message has been sent already
+     * @throws IllegalStateException
+     *         if there is an outstanding send operation
+     * @throws IllegalStateException
+     *         if a previous Binary message
+     *         was not sent with {@code isLast == true}
+     */
+    CompletableFuture<Void> sendText(ByteBuffer message, boolean isLast);
+
+    /**
+     * Sends a Text message with characters from the given {@code
+     * CharSequence}.
+     *
+     * <p> Returns immediately with a {@code CompletableFuture<Void>} which
+     * completes normally when the message has been sent, or completes
+     * exceptionally if an error occurs.
+     *
+     * <p> This message may be a partial UTF-16 sequence. However, the
+     * concatenation of all messages through the last must be a whole UTF-16
+     * sequence.
+     *
+     * <p> The {@code CharSequence} should not be modified until the returned
+     * {@code CompletableFuture} completes (either normally or exceptionally).
+     *
+     * <p> The returned {@code CompletableFuture} can complete exceptionally
+     * with:
+     * <ul>
+     * <li> {@link IOException}
+     *          if an I/O error occurs during this operation; or the
+     *          {@code WebSocket} closes while this operation is in progress;
+     *          or the {@code message} is a malformed UTF-16 sequence
+     * </ul>
+     *
+     * @param message
+     *         the message
+     * @param isLast
+     *         {@code true} if this is the final part of the message
+     *         {@code false} otherwise
+     *
+     * @return a CompletableFuture of Void
+     *
+     * @throws IllegalStateException
+     *         if the WebSocket is closed
+     * @throws IllegalStateException
+     *         if a Close message has been already sent
+     * @throws IllegalStateException
+     *         if there is an outstanding send operation
+     * @throws IllegalStateException
+     *         if a previous Binary message was not sent
+     *         with {@code isLast == true}
+     */
+    CompletableFuture<Void> sendText(CharSequence message, boolean isLast);
+
+    /**
+     * Sends a whole Text message with characters from the given {@code
+     * CharSequence}.
+     *
+     * <p> This is a convenience method. For the general case, use {@link
+     * #sendText(CharSequence, boolean)}.
+     *
+     * <p> Returns immediately with a {@code CompletableFuture<Void>} which
+     * completes normally when the message has been sent, or completes
+     * exceptionally if an error occurs.
+     *
+     * <p> The {@code CharSequence} should not be modified until the returned
+     * {@code CompletableFuture} completes (either normally or exceptionally).
+     *
+     * <p> The returned {@code CompletableFuture} can complete exceptionally
+     * with:
+     * <ul>
+     * <li> {@link IOException}
+     *          if an I/O error occurs during this operation; or the
+     *          {@code WebSocket} closes while this operation is in progress;
+     *          or the message is a malformed UTF-16 sequence
+     * </ul>
+     *
+     * @param message
+     *         the message
+     *
+     * @return a CompletableFuture of Void
+     *
+     * @throws IllegalStateException
+     *         if the WebSocket is closed
+     * @throws IllegalStateException
+     *         if a Close message has been already sent
+     * @throws IllegalStateException
+     *         if there is an outstanding send operation
+     * @throws IllegalStateException
+     *         if a previous Binary message was not sent
+     *         with {@code isLast == true}
+     */
+    default CompletableFuture<Void> sendText(CharSequence message) {
+        return sendText(message, true);
+    }
+
+    /**
+     * Sends a whole Text message with characters from {@code
+     * CharacterSequence}s provided by the given {@code Stream}.
+     *
+     * <p> This is a convenience method. For the general case use {@link
+     * #sendText(CharSequence, boolean)}.
+     *
+     * <p> Returns immediately with a {@code CompletableFuture<Void>} which
+     * completes normally when the message has been sent, or completes
+     * exceptionally if an error occurs.
+     *
+     * <p> Streamed character sequences should not be modified until the
+     * returned {@code CompletableFuture} completes (either normally or
+     * exceptionally).
+     *
+     * <p> The returned {@code CompletableFuture} can complete exceptionally
+     * with:
+     * <ul>
+     * <li> {@link IOException}
+     *          if an I/O error occurs during this operation; or the
+     *          {@code WebSocket} closes while this operation is in progress;
+     *          or the message is a malformed UTF-16 sequence
+     * </ul>
+     *
+     * @param message
+     *         the message
+     *
+     * @return a CompletableFuture of Void
+     *
+     * @throws IllegalStateException
+     *         if the WebSocket is closed
+     * @throws IllegalStateException
+     *         if a Close message has been already sent
+     * @throws IllegalStateException
+     *         if there is an outstanding send operation
+     * @throws IllegalStateException
+     *         if a previous Binary message was not sent
+     *         with {@code isLast == true}
+     */
+    CompletableFuture<Void> sendText(Stream<? extends CharSequence> message);
+
+    /**
+     * Sends a Binary message with bytes from the given {@code ByteBuffer}.
+     *
+     * <p> Returns immediately with a {@code CompletableFuture<Void>} which
+     * completes normally when the message has been sent, or completes
+     * exceptionally if an error occurs.
+     *
+     * <p> The returned {@code CompletableFuture} can complete exceptionally
+     * with:
+     * <ul>
+     * <li> {@link IOException}
+     *          if an I/O error occurs during this operation or the
+     *          {@code WebSocket} closes while this operation is in progress
+     * </ul>
+     *
+     * @param message
+     *         the message
+     * @param isLast
+     *         {@code true} if this is the final part of the message,
+     *         {@code false} otherwise
+     *
+     * @return a CompletableFuture of Void
+     *
+     * @throws IllegalStateException
+     *         if the WebSocket is closed
+     * @throws IllegalStateException
+     *         if a Close message has been already sent
+     * @throws IllegalStateException
+     *         if there is an outstanding send operation
+     * @throws IllegalStateException
+     *         if a previous Text message was not sent
+     *         with {@code isLast == true}
+     */
+    CompletableFuture<Void> sendBinary(ByteBuffer message, boolean isLast);
+
+    /**
+     * Sends a Binary message with bytes from the given {@code byte[]}.
+     *
+     * <p> Returns immediately with a {@code CompletableFuture<Void>} which
+     * completes normally when the message has been sent, or completes
+     * exceptionally if an error occurs.
+     *
+     * <p> The returned {@code CompletableFuture} can complete exceptionally
+     * with:
+     * <ul>
+     * <li> {@link IOException}
+     *          if an I/O error occurs during this operation or the
+     *          {@code WebSocket} closes while this operation is in progress
+     * </ul>
+     *
+     * @implSpec This is equivalent to:
+     * <pre>{@code
+     *     sendBinary(ByteBuffer.wrap(message), isLast)
+     * }</pre>
+     *
+     * @param message
+     *         the message
+     * @param isLast
+     *         {@code true} if this is the final part of the message,
+     *         {@code false} otherwise
+     *
+     * @return a CompletableFuture of Void
+     *
+     * @throws IllegalStateException
+     *         if the WebSocket is closed
+     * @throws IllegalStateException
+     *         if a Close message has been already sent
+     * @throws IllegalStateException
+     *         if there is an outstanding send operation
+     * @throws IllegalStateException
+     *         if a previous Text message was not sent
+     *         with {@code isLast == true}
+     */
+    default CompletableFuture<Void> sendBinary(byte[] message, boolean isLast) {
+        Objects.requireNonNull(message, "message");
+        return sendBinary(ByteBuffer.wrap(message), isLast);
+    }
+
+    /**
+     * Sends a Ping message.
+     *
+     * <p> Returns immediately with a {@code CompletableFuture<Void>} which
+     * completes normally when the message has been sent, or completes
+     * exceptionally if an error occurs.
+     *
+     * <p> A Ping message may be sent or received by either client or server.
+     * It may serve either as a keepalive or as a means to verify that the
+     * remote endpoint is still responsive.
+     *
+     * <p> The message must consist of not more than {@code 125} bytes: {@code
+     * message.remaining() <= 125}.
+     *
+     * <p> The returned {@code CompletableFuture} can complete exceptionally
+     * with:
+     * <ul>
+     * <li> {@link IOException}
+     *          if an I/O error occurs during this operation or the
+     *          {@code WebSocket} closes while this operation is in progress
+     * </ul>
+     *
+     * @param message
+     *         the message
+     *
+     * @return a CompletableFuture of Void
+     *
+     * @throws IllegalStateException
+     *         if the WebSocket is closed
+     * @throws IllegalStateException
+     *         if a Close message has been already sent
+     * @throws IllegalStateException
+     *         if there is an outstanding send operation
+     * @throws IllegalArgumentException
+     *         if {@code message.remaining() > 125}
+     */
+    CompletableFuture<Void> sendPing(ByteBuffer message);
+
+    /**
+     * Sends a Pong message.
+     *
+     * <p> Returns immediately with a {@code CompletableFuture<Void>} which
+     * completes normally when the message has been sent, or completes
+     * exceptionally if an error occurs.
+     *
+     * <p> A Pong message may be unsolicited or may be sent in response to a
+     * previously received Ping. In latter case the contents of the Pong is
+     * identical to the originating Ping.
+     *
+     * <p> The message must consist of not more than {@code 125} bytes: {@code
+     * message.remaining() <= 125}.
+     *
+     * <p> The returned {@code CompletableFuture} can complete exceptionally
+     * with:
+     * <ul>
+     * <li> {@link IOException}
+     *          if an I/O error occurs during this operation or the
+     *          {@code WebSocket} closes while this operation is in progress
+     * </ul>
+     *
+     * @param message
+     *         the message
+     *
+     * @return a CompletableFuture of Void
+     *
+     * @throws IllegalStateException
+     *         if the WebSocket is closed
+     * @throws IllegalStateException
+     *         if a Close message has been already sent
+     * @throws IllegalStateException
+     *         if there is an outstanding send operation
+     * @throws IllegalArgumentException
+     *         if {@code message.remaining() > 125}
+     */
+    CompletableFuture<Void> sendPong(ByteBuffer message);
+
+    /**
+     * Sends a Close message with the given close code and the reason.
+     *
+     * <p> Returns immediately with a {@code CompletableFuture<Void>} which
+     * completes normally when the message has been sent, or completes
+     * exceptionally if an error occurs.
+     *
+     * <p> A Close message may consist of a close code and a reason for closing.
+     * The reason must have a valid UTF-8 representation not longer than {@code
+     * 123} bytes. The reason may be useful for debugging or passing information
+     * relevant to the connection but is not necessarily human readable.
+     *
+     * <p> The returned {@code CompletableFuture} can complete exceptionally
+     * with:
+     * <ul>
+     * <li> {@link IOException}
+     *          if an I/O error occurs during this operation or the
+     *          {@code WebSocket} closes while this operation is in progress
+     * </ul>
+     *
+     * @param code
+     *         the close code
+     * @param reason
+     *         the reason; can be empty
+     *
+     * @return a CompletableFuture of Void
+     *
+     * @throws IllegalStateException
+     *         if the WebSocket is closed
+     * @throws IllegalStateException
+     *         if a Close message has been already sent
+     * @throws IllegalStateException
+     *         if there is an outstanding send operation
+     * @throws IllegalArgumentException
+     *         if the {@code reason} doesn't have a valid UTF-8
+     *         representation not longer than {@code 123} bytes
+     */
+    CompletableFuture<Void> sendClose(CloseCode code, CharSequence reason);
+
+    /**
+     * Sends an empty Close message.
+     *
+     * <p> Returns immediately with a {@code CompletableFuture<Void>} which
+     * completes normally when the message has been sent, or completes
+     * exceptionally if an error occurs.
+     *
+     * <p> The returned {@code CompletableFuture} can complete exceptionally
+     * with:
+     * <ul>
+     * <li> {@link IOException}
+     *          if an I/O error occurs during this operation or the
+     *          {@code WebSocket} closes while this operation is in progress
+     * </ul>
+     *
+     * @return a CompletableFuture of Void
+     *
+     * @throws IllegalStateException
+     *         if the WebSocket is closed
+     * @throws IllegalStateException
+     *         if a Close message has been already sent
+     * @throws IllegalStateException
+     *         if there is an outstanding send operation
+     */
+    CompletableFuture<Void> sendClose();
+
+    /**
+     * Requests {@code n} more messages to be received by the {@link Listener
+     * Listener}.
+     *
+     * <p> The actual number might be fewer if either of the endpoints decide to
+     * close the connection before that or an error occurs.
+     *
+     * <p> A {@code WebSocket} that has just been created, hasn't requested
+     * anything yet. Usually the initial request for messages is done in {@link
+     * Listener#onOpen(java.net.http.WebSocket) Listener.onOpen}.
+     *
+     * If all requested messages have been received, and the server sends more,
+     * then these messages are queued.
+     *
+     * @implNote This implementation does not distinguish between partial and
+     * whole messages, because it's not known beforehand how a message will be
+     * received.
+     * <p> If a server sends more messages than requested, the implementation
+     * queues up these messages on the TCP connection and may eventually force
+     * the sender to stop sending through TCP flow control.
+     *
+     * @param n
+     *         the number of messages
+     *
+     * @throws IllegalArgumentException
+     *         if {@code n < 0}
+     *
+     * @return resulting unfulfilled demand with this request taken into account
+     */
+    // TODO return void as it's breaking encapsulation (leaking info when exactly something deemed delivered)
+    // or demand behaves after LONG.MAX_VALUE
+    long request(long n);
+
+    /**
+     * Returns a {@linkplain Builder#subprotocols(String, String...) subprotocol}
+     * in use.
+     *
+     * @return a subprotocol, or {@code null} if there is none
+     */
+    String getSubprotocol();
+
+    /**
+     * Tells whether the {@code WebSocket} is closed.
+     *
+     * <p> A {@code WebSocket} deemed closed when either the underlying socket
+     * is closed or the closing handshake is completed.
+     *
+     * @return {@code true} if the {@code WebSocket} is closed,
+     *         {@code false} otherwise
+     */
+    boolean isClosed();
+
+    /**
+     * Closes the {@code WebSocket} abruptly.
+     *
+     * <p> This method closes the underlying TCP connection. If the {@code
+     * WebSocket} is already closed then invoking this method has no effect.
+     *
+     * @throws IOException
+     *         if an I/O error occurs
+     */
+    void abort() throws IOException;
+
+    /**
+     * A {@code WebSocket} close status code.
+     *
+     * <p> Some codes <a href="https://tools.ietf.org/html/rfc6455#section-7.4">
+     * specified</a> in the WebSocket Protocol are defined as named constants
+     * here. Others can be {@linkplain #of(int) retrieved on demand}.
+     *
+     * <p> This is a
+     * <a href="../../lang/doc-files/ValueBased.html">value-based</a> class;
+     * use of identity-sensitive operations (including reference equality
+     * ({@code ==}), identity hash code, or synchronization) on instances of
+     * {@code CloseCode} may have unpredictable results and should be avoided.
+     *
+     * @since 9
+     */
+    final class CloseCode {
+
+        /**
+         * Indicates a normal close, meaning that the purpose for which the
+         * connection was established has been fulfilled.
+         *
+         * <p> Numerical representation: {@code 1000}
+         */
+        public static final CloseCode NORMAL_CLOSURE
+                = new CloseCode(1000, "NORMAL_CLOSURE");
+
+        /**
+         * Indicates that an endpoint is "going away", such as a server going
+         * down or a browser having navigated away from a page.
+         *
+         * <p> Numerical representation: {@code 1001}
+         */
+        public static final CloseCode GOING_AWAY
+                = new CloseCode(1001, "GOING_AWAY");
+
+        /**
+         * Indicates that an endpoint is terminating the connection due to a
+         * protocol error.
+         *
+         * <p> Numerical representation: {@code 1002}
+         */
+        public static final CloseCode PROTOCOL_ERROR
+                = new CloseCode(1002, "PROTOCOL_ERROR");
+
+        /**
+         * Indicates that an endpoint is terminating the connection because it
+         * has received a type of data it cannot accept (e.g., an endpoint that
+         * understands only text data MAY send this if it receives a binary
+         * message).
+         *
+         * <p> Numerical representation: {@code 1003}
+         */
+        public static final CloseCode CANNOT_ACCEPT
+                = new CloseCode(1003, "CANNOT_ACCEPT");
+
+        /**
+         * Indicates that an endpoint is terminating the connection because it
+         * has received data within a message that was not consistent with the
+         * type of the message (e.g., non-UTF-8 [RFC3629] data within a text
+         * message).
+         *
+         * <p> Numerical representation: {@code 1007}
+         */
+        public static final CloseCode NOT_CONSISTENT
+                = new CloseCode(1007, "NOT_CONSISTENT");
+
+        /**
+         * Indicates that an endpoint is terminating the connection because it
+         * has received a message that violates its policy. This is a generic
+         * status code that can be returned when there is no other more suitable
+         * status code (e.g., {@link #CANNOT_ACCEPT} or {@link #TOO_BIG}) or if
+         * there is a need to hide specific details about the policy.
+         *
+         * <p> Numerical representation: {@code 1008}
+         */
+        public static final CloseCode VIOLATED_POLICY
+                = new CloseCode(1008, "VIOLATED_POLICY");
+
+        /**
+         * Indicates that an endpoint is terminating the connection because it
+         * has received a message that is too big for it to process.
+         *
+         * <p> Numerical representation: {@code 1009}
+         */
+        public static final CloseCode TOO_BIG
+                = new CloseCode(1009, "TOO_BIG");
+
+        /**
+         * Indicates that an endpoint is terminating the connection because it
+         * encountered an unexpected condition that prevented it from fulfilling
+         * the request.
+         *
+         * <p> Numerical representation: {@code 1011}
+         */
+        public static final CloseCode UNEXPECTED_CONDITION
+                = new CloseCode(1011, "UNEXPECTED_CONDITION");
+
+        private static final Map<Integer, CloseCode> cached = Map.ofEntries(
+                entry(NORMAL_CLOSURE),
+                entry(GOING_AWAY),
+                entry(PROTOCOL_ERROR),
+                entry(CANNOT_ACCEPT),
+                entry(NOT_CONSISTENT),
+                entry(VIOLATED_POLICY),
+                entry(TOO_BIG),
+                entry(UNEXPECTED_CONDITION)
+        );
+
+        /**
+         * Returns a {@code CloseCode} from its numerical representation.
+         *
+         * <p> The given {@code code} should be in the range {@code 1000 <= code
+         * <= 4999}, and should not be equal to any of the following codes:
+         * {@code 1004}, {@code 1005}, {@code 1006} and {@code 1015}.
+         *
+         * @param code
+         *         numerical representation
+         *
+         * @return a close code corresponding to the provided numerical value
+         *
+         * @throws IllegalArgumentException
+         *         if {@code code} violates any of the requirements above
+         */
+        public static CloseCode of(int code) {
+            if (code < 1000 || code > 4999) {
+                throw new IllegalArgumentException("Out of range: " + code);
+            }
+            if (code == 1004 || code == 1005 || code == 1006 || code == 1015) {
+                throw new IllegalArgumentException("Reserved: " + code);
+            }
+            CloseCode closeCode = cached.get(code);
+            return closeCode != null ? closeCode : new CloseCode(code, "");
+        }
+
+        private final int code;
+        private final String description;
+
+        private CloseCode(int code, String description) {
+            assert description != null;
+            this.code = code;
+            this.description = description;
+        }
+
+        /**
+         * Returns a numerical representation of this close code.
+         *
+         * @return a numerical representation
+         */
+        public int getCode() {
+            return code;
+        }
+
+        /**
+         * Compares this close code to the specified object.
+         *
+         * @param o
+         *         the object to compare this {@code CloseCode} against
+         *
+         * @return {@code true} iff the argument is a close code with the same
+         * {@linkplain #getCode() numerical representation} as this one
+         */
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (!(o instanceof CloseCode)) {
+                return false;
+            }
+            CloseCode that = (CloseCode) o;
+            return code == that.code;
+        }
+
+        @Override
+        public int hashCode() {
+            return code;
+        }
+
+        /**
+         * Returns a human-readable representation of this close code.
+         *
+         * @apiNote The representation is not designed to be parsed; the format
+         * may change unexpectedly.
+         *
+         * @return a string representation
+         */
+        @Override
+        public String toString() {
+            return code + (description.isEmpty() ? "" : (": " + description));
+        }
+
+        private static Map.Entry<Integer, CloseCode> entry(CloseCode cc) {
+            return Map.entry(cc.getCode(), cc);
+        }
+    }
+
+    /**
+     * A character sequence that provides access to the characters UTF-8 decoded
+     * from a message in a {@code ByteBuffer}.
+     *
+     * @since 9
+     */
+    interface Text extends CharSequence {
+
+        // Methods from the CharSequence below are mentioned explicitly for the
+        // purpose of documentation, so when looking at javadoc it immediately
+        // obvious what methods Text has
+
+        @Override
+        int length();
+
+        @Override
+        char charAt(int index);
+
+        @Override
+        CharSequence subSequence(int start, int end);
+
+        /**
+         * Returns a string containing the characters in this sequence in the
+         * same order as this sequence. The length of the string will be the
+         * length of this sequence.
+         *
+         * @return a string consisting of exactly this sequence of characters
+         */
+        @Override
+        // TODO: remove the explicit javadoc above when:
+        // (JDK-8144034 has been resolved) AND (the comment is still identical
+        // to CharSequence#toString)
+        String toString();
+
+        /**
+         * Returns a read-only {@code ByteBuffer} containing the message encoded
+         * in UTF-8.
+         *
+         * @return a read-only ByteBuffer
+         */
+        ByteBuffer asByteBuffer();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WebSocketHandshakeException.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,66 @@
+/*
+ * 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 java.net.http;
+
+/**
+ * An exception used to signal the opening handshake failed.
+ *
+ * @since 9
+ */
+public final class WebSocketHandshakeException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+    private final transient HttpResponse response;
+
+    WebSocketHandshakeException(HttpResponse response) {
+        this(null, response);
+    }
+
+    WebSocketHandshakeException(String message, HttpResponse response) {
+        super(statusCodeOrFullMessage(message, response));
+        this.response = response;
+    }
+
+    /**
+     * // FIXME: terrible toString (+ not always status should be displayed I guess)
+     */
+    private static String statusCodeOrFullMessage(String m, HttpResponse response) {
+        return (m == null || m.isEmpty())
+                ? String.valueOf(response.statusCode())
+                : response.statusCode() + ": " + m;
+    }
+
+    /**
+     * Returns a HTTP response from the server.
+     *
+     * <p> The value may be unavailable ({@code null}) if this exception has
+     * been serialized and then read back in.
+     *
+     * @return server response
+     */
+    public HttpResponse getResponse() {
+        return response;
+    }
+}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/package-info.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/package-info.java	Thu May 12 11:03:07 2016 -0700
@@ -33,6 +33,7 @@
  *    <li>{@link java.net.http.HttpClient}</li>
  *    <li>{@link java.net.http.HttpRequest}</li>
  *    <li>{@link java.net.http.HttpResponse}</li>
+ *    <li>{@link java.net.http.WebSocket}</li>
  * </ul>
  *
  * @since 9
--- a/jdk/src/java.management/share/classes/javax/management/AttributeList.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.management/share/classes/javax/management/AttributeList.java	Thu May 12 11:03:07 2016 -0700
@@ -148,7 +148,7 @@
      * <p>If this method has ever been called on a given
      * {@code AttributeList} instance, a subsequent attempt to add
      * an object to that instance which is not an {@code Attribute}
-     * will fail with a {@code IllegalArgumentException}. For compatibility
+     * will fail with an {@code IllegalArgumentException}. For compatibility
      * reasons, an {@code AttributeList} on which this method has never
      * been called does allow objects other than {@code Attribute}s to
      * be added.</p>
--- a/jdk/src/java.management/share/classes/javax/management/MBeanFeatureInfo.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.management/share/classes/javax/management/MBeanFeatureInfo.java	Thu May 12 11:03:07 2016 -0700
@@ -215,7 +215,7 @@
      *    <ul>
      *    <li>1. The method {@link ObjectInputStream#readObject readObject()}
      *       is called twice to obtain the field names (a {@code String[]}) and
-     *       the field values (a {@code Object[]}) of the {@code descriptor}.
+     *       the field values (an {@code Object[]}) of the {@code descriptor}.
      *       The two obtained values then are used to construct
      *       an {@link ImmutableDescriptor} instance for the field
      *       {@code descriptor};</li>
--- a/jdk/src/java.management/share/classes/javax/management/MBeanInfo.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.management/share/classes/javax/management/MBeanInfo.java	Thu May 12 11:03:07 2016 -0700
@@ -670,7 +670,7 @@
      *    <ul>
      *    <li>1. The method {@link ObjectInputStream#readObject readObject()}
      *       is called twice to obtain the field names (a {@code String[]}) and
-     *       the field values (a {@code Object[]}) of the {@code descriptor}.
+     *       the field values (an {@code Object[]}) of the {@code descriptor}.
      *       The two obtained values then are used to construct
      *       an {@link ImmutableDescriptor} instance for the field
      *       {@code descriptor};</li>
--- a/jdk/src/java.management/share/classes/sun/management/Sensor.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.management/share/classes/sun/management/Sensor.java	Thu May 12 11:03:07 2016 -0700
@@ -34,7 +34,7 @@
  * An abstract sensor.
  *
  * <p>
- * A {@code AbstractSensor} object consists of two attributes:
+ * An {@code AbstractSensor} object consists of two attributes:
  * <ul>
  *   <li>{@code on} is a boolean flag indicating if a sensor is
  *       triggered. This flag will be set or cleared by the
--- a/jdk/src/java.management/share/classes/sun/management/counter/perf/InstrumentationException.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.management/share/classes/sun/management/counter/perf/InstrumentationException.java	Thu May 12 11:03:07 2016 -0700
@@ -27,14 +27,14 @@
 
 public class InstrumentationException extends RuntimeException {
     /**
-     * Constructs a {@code InstrumentationException} with no
+     * Constructs an {@code InstrumentationException} with no
      * detail message.
      */
      public InstrumentationException() {
      }
 
     /**
-     * Constructs a {@code InstrumentationException} with a specified
+     * Constructs an {@code InstrumentationException} with a specified
      * detail message.
      *
      * @param message the detail message
--- a/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/EventQueue.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/EventQueue.java	Thu May 12 11:03:07 2016 -0700
@@ -78,7 +78,7 @@
      *        {@code UnsolicitedNotificationEvent}.
      * If it is a subclass of {@code NamingEvent}, all listeners must implement
      * the corresponding subinterface of {@code NamingListener}.
-     * For example, for a {@code ObjectAddedEvent}, all listeners <em>must</em>
+     * For example, for an {@code ObjectAddedEvent}, all listeners <em>must</em>
      * implement the {@code ObjectAddedListener} interface.
      * <em>The current implementation does not check this before dispatching
      * the event.</em>
--- a/jdk/src/java.naming/share/classes/javax/naming/event/EventContext.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.naming/share/classes/javax/naming/event/EventContext.java	Thu May 12 11:03:07 2016 -0700
@@ -56,7 +56,7 @@
  *{@code NameNotFoundException}).
  *<p>
  * An application can use the method {@code targetMustExist()} to check
- * whether a {@code EventContext} supports registration
+ * whether an {@code EventContext} supports registration
  * of nonexistent targets.
  *
  *<h1>Event Source</h1>
@@ -92,7 +92,7 @@
  * which it invoked {@code addNamingListener()} (just as
  * it needs to keep a reference to the listener in order to remove it
  * later). It cannot expect to do a {@code lookup()} and get another instance of
- * a {@code EventContext} on which to perform the deregistration.
+ * an {@code EventContext} on which to perform the deregistration.
  *<h1>Lifetime of Registration</h1>
  * A registered listener becomes deregistered when:
  *<ul>
@@ -102,7 +102,7 @@
  *<li>{@code Context.close()} is invoked on the {@code EventContext}
  * instance with which it has registered.
  </ul>
- * Until that point, a {@code EventContext} instance that has outstanding
+ * Until that point, an {@code EventContext} instance that has outstanding
  * listeners will continue to exist and be maintained by the service provider.
  *
  *<h1>Listener Implementations</h1>
--- a/jdk/src/java.naming/share/classes/javax/naming/event/NamingListener.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.naming/share/classes/javax/naming/event/NamingListener.java	Thu May 12 11:03:07 2016 -0700
@@ -40,7 +40,7 @@
   * from the {@code EventContext} with which it has registered.
   *<p>
   * For example, suppose a listener implements {@code ObjectChangeListener} and
-  * registers with a {@code EventContext}.
+  * registers with an {@code EventContext}.
   * Then, if the connection to the server is subsequently broken,
   * the listener will receive a {@code NamingExceptionEvent} and may
   * take some corrective action, such as notifying the user of the application.
--- a/jdk/src/java.naming/share/classes/javax/naming/ldap/UnsolicitedNotificationListener.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.naming/share/classes/javax/naming/ldap/UnsolicitedNotificationListener.java	Thu May 12 11:03:07 2016 -0700
@@ -32,7 +32,7 @@
  * "Unsolicited notification" is defined in
  * <A HREF="http://www.ietf.org/rfc/rfc2251.txt">RFC 2251</A>.
  * It allows the server to send unsolicited notifications to the client.
- * A {@code UnsolicitedNotificationListener} must:
+ * An {@code UnsolicitedNotificationListener} must:
  *<ol>
  * <li>Implement this interface and its method
  * <li>Implement {@code NamingListener.namingExceptionThrown()} so
@@ -41,7 +41,7 @@
  * <li>Register with the context using one of the {@code addNamingListener()}
  * methods from {@code EventContext} or {@code EventDirContext}.
  * Only the {@code NamingListener} argument of these methods are applicable;
- * the rest are ignored for a {@code UnsolicitedNotificationListener}.
+ * the rest are ignored for an {@code UnsolicitedNotificationListener}.
  * (These arguments might be applicable to the listener if it implements
  * other listener interfaces).
  *</ol>
--- a/jdk/src/java.rmi/share/classes/java/rmi/server/RMISocketFactory.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.rmi/share/classes/java/rmi/server/RMISocketFactory.java	Thu May 12 11:03:07 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
@@ -35,21 +35,8 @@
  * request that the RMI runtime use its socket factory instance
  * instead of the default implementation.
  *
- * <p>The default socket factory implementation performs a
- * three-tiered approach to creating client sockets. First, a direct
- * socket connection to the remote VM is attempted.  If that fails
- * (due to a firewall), the runtime uses HTTP with the explicit port
- * number of the server.  If the firewall does not allow this type of
- * communication, then HTTP to a cgi-bin script on the server is used
- * to POST the RMI call. The HTTP tunneling mechanisms are disabled by
- * default. This behavior is controlled by the {@code java.rmi.server.disableHttp}
- * property, whose default value is {@code true}. Setting this property's
- * value to {@code false} will enable the HTTP tunneling mechanisms.
- *
- * <p><strong>Deprecated: HTTP Tunneling.</strong> <em>The HTTP tunneling mechanisms
- * described above, specifically HTTP with an explicit port and HTTP to a
- * cgi-bin script, are deprecated. These HTTP tunneling mechanisms are
- * subject to removal in a future release of the platform.</em>
+ * <p>The default socket factory implementation creates a direct
+ * socket connection to the remote host.
  *
  * <p>The default socket factory implementation creates server sockets that
  * are bound to the wildcard address, which accepts requests from all network
@@ -181,7 +168,7 @@
     public synchronized static RMISocketFactory getDefaultSocketFactory() {
         if (defaultSocketFactory == null) {
             defaultSocketFactory =
-                new sun.rmi.transport.proxy.RMIMasterSocketFactory();
+                new sun.rmi.transport.tcp.TCPDirectSocketFactory();
         }
         return defaultSocketFactory;
     }
--- a/jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/CGIHandler.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,423 +0,0 @@
-/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.rmi.transport.proxy;
-
-import java.io.*;
-import java.net.*;
-import java.util.Hashtable;
-
-/**
- * CGIClientException is thrown when an error is detected
- * in a client's request.
- */
-class CGIClientException extends Exception {
-    private static final long serialVersionUID = 8147981687059865216L;
-
-    public CGIClientException(String s) {
-        super(s);
-    }
-
-    public CGIClientException(String s, Throwable cause) {
-        super(s, cause);
-    }
-}
-
-/**
- * CGIServerException is thrown when an error occurs here on the server.
- */
-class CGIServerException extends Exception {
-
-    private static final long serialVersionUID = 6928425456704527017L;
-
-    public CGIServerException(String s) {
-        super(s);
-    }
-
-    public CGIServerException(String s, Throwable cause) {
-        super(s, cause);
-    }
-}
-
-/**
- * CGICommandHandler is the interface to an object that handles a
- * particular supported command.
- */
-interface CGICommandHandler {
-
-    /**
-     * Return the string form of the command
-     * to be recognized in the query string.
-     */
-    public String getName();
-
-    /**
-     * Execute the command with the given string as parameter.
-     */
-    public void execute(String param) throws CGIClientException, CGIServerException;
-}
-
-/**
- * The CGIHandler class contains methods for executing as a CGI program.
- * The main function interprets the query string as a command of the form
- * "{@code <command>=<parameters>}".
- *
- * This class depends on the CGI 1.0 environment variables being set as
- * properties of the same name in this Java VM.
- *
- * All data and methods of this class are static because they are specific
- * to this particular CGI process.
- */
-public final class CGIHandler {
-
-    /* get CGI parameters that we need */
-    static int ContentLength;
-    static String QueryString;
-    static String RequestMethod;
-    static String ServerName;
-    static int ServerPort;
-
-    static {
-        java.security.AccessController.doPrivileged(
-            new java.security.PrivilegedAction<Void>() {
-            public Void run() {
-                ContentLength =
-                    Integer.getInteger("CONTENT_LENGTH", 0).intValue();
-                QueryString = System.getProperty("QUERY_STRING", "");
-                RequestMethod = System.getProperty("REQUEST_METHOD", "");
-                ServerName = System.getProperty("SERVER_NAME", "");
-                ServerPort = Integer.getInteger("SERVER_PORT", 0).intValue();
-                return null;
-            }
-        });
-    }
-
-    /* list of handlers for supported commands */
-    private static CGICommandHandler commands[] = {
-        new CGIForwardCommand(),
-        new CGIGethostnameCommand(),
-        new CGIPingCommand(),
-        new CGITryHostnameCommand()
-    };
-
-    /* construct table mapping command strings to handlers */
-    private static Hashtable<String, CGICommandHandler> commandLookup;
-    static {
-        commandLookup = new Hashtable<>();
-        for (int i = 0; i < commands.length; ++ i)
-            commandLookup.put(commands[i].getName(), commands[i]);
-    }
-
-    /* prevent instantiation of this class */
-    private CGIHandler() {}
-
-    /**
-     * Execute command given in query string on URL.  The string before
-     * the first '=' is interpreted as the command name, and the string
-     * after the first '=' is the parameters to the command.
-     */
-    public static void main(String args[])
-    {
-        try {
-            String command, param;
-            int delim = QueryString.indexOf('=');
-            if (delim == -1) {
-                command = QueryString;
-                param = "";
-            }
-            else {
-                command = QueryString.substring(0, delim);
-                param = QueryString.substring(delim + 1);
-            }
-            CGICommandHandler handler =
-                commandLookup.get(command);
-            if (handler != null)
-                try {
-                    handler.execute(param);
-                } catch (CGIClientException e) {
-                    e.printStackTrace();
-                    returnClientError(e.getMessage());
-                } catch (CGIServerException e) {
-                    e.printStackTrace();
-                    returnServerError(e.getMessage());
-                }
-            else
-                returnClientError("invalid command.");
-        } catch (Exception e) {
-            e.printStackTrace();
-            returnServerError("internal error: " + e.getMessage());
-        }
-        System.exit(0);
-    }
-
-    /**
-     * Return an HTML error message indicating there was error in
-     * the client's request.
-     */
-    private static void returnClientError(String message)
-    {
-        System.out.println("Status: 400 Bad Request: " + message);
-        System.out.println("Content-type: text/html");
-        System.out.println("");
-        System.out.println("<HTML>" +
-                           "<HEAD><TITLE>Java RMI Client Error" +
-                           "</TITLE></HEAD>" +
-                           "<BODY>");
-        System.out.println("<H1>Java RMI Client Error</H1>");
-        System.out.println("");
-        System.out.println(message);
-        System.out.println("</BODY></HTML>");
-        System.exit(1);
-    }
-
-    /**
-     * Return an HTML error message indicating an error occurred
-     * here on the server.
-     */
-    private static void returnServerError(String message)
-    {
-        System.out.println("Status: 500 Server Error: " + message);
-        System.out.println("Content-type: text/html");
-        System.out.println("");
-        System.out.println("<HTML>" +
-                           "<HEAD><TITLE>Java RMI Server Error" +
-                           "</TITLE></HEAD>" +
-                           "<BODY>");
-        System.out.println("<H1>Java RMI Server Error</H1>");
-        System.out.println("");
-        System.out.println(message);
-        System.out.println("</BODY></HTML>");
-        System.exit(1);
-    }
-}
-
-/**
- * "forward" command: Forward request body to local port on the server,
- * and send response back to client.
- */
-final class CGIForwardCommand implements CGICommandHandler {
-
-    public String getName() {
-        return "forward";
-    }
-
-    @SuppressWarnings("deprecation")
-    private String getLine (DataInputStream socketIn) throws IOException {
-        return socketIn.readLine();
-    }
-
-    public void execute(String param) throws CGIClientException, CGIServerException
-    {
-        if (!CGIHandler.RequestMethod.equals("POST"))
-            throw new CGIClientException("can only forward POST requests");
-
-        int port;
-        try {
-            port = Integer.parseInt(param);
-        } catch (NumberFormatException e) {
-            throw new CGIClientException("invalid port number.", e);
-        }
-        if (port <= 0 || port > 0xFFFF)
-            throw new CGIClientException("invalid port: " + port);
-        if (port < 1024)
-            throw new CGIClientException("permission denied for port: " +
-                                         port);
-
-        byte buffer[];
-        Socket socket;
-        try {
-            socket = new Socket(InetAddress.getLocalHost(), port);
-        } catch (IOException e) {
-            throw new CGIServerException("could not connect to local port", e);
-        }
-
-        /*
-         * read client's request body
-         */
-        DataInputStream clientIn = new DataInputStream(System.in);
-        buffer = new byte[CGIHandler.ContentLength];
-        try {
-            clientIn.readFully(buffer);
-        } catch (EOFException e) {
-            throw new CGIClientException("unexpected EOF reading request body", e);
-        } catch (IOException e) {
-            throw new CGIClientException("error reading request body", e);
-        }
-
-        /*
-         * send to local server in HTTP
-         */
-        try {
-            DataOutputStream socketOut =
-                new DataOutputStream(socket.getOutputStream());
-            socketOut.writeBytes("POST / HTTP/1.0\r\n");
-            socketOut.writeBytes("Content-length: " +
-                                 CGIHandler.ContentLength + "\r\n\r\n");
-            socketOut.write(buffer);
-            socketOut.flush();
-        } catch (IOException e) {
-            throw new CGIServerException("error writing to server", e);
-        }
-
-        /*
-         * read response
-         */
-        DataInputStream socketIn;
-        try {
-            socketIn = new DataInputStream(socket.getInputStream());
-        } catch (IOException e) {
-            throw new CGIServerException("error reading from server", e);
-        }
-        String key = "Content-length:".toLowerCase();
-        boolean contentLengthFound = false;
-        String line;
-        int responseContentLength = -1;
-        do {
-            try {
-                line = getLine(socketIn);
-            } catch (IOException e) {
-                throw new CGIServerException("error reading from server", e);
-            }
-            if (line == null)
-                throw new CGIServerException(
-                    "unexpected EOF reading server response");
-
-            if (line.toLowerCase().startsWith(key)) {
-                if (contentLengthFound) {
-                    throw new CGIServerException(
-                            "Multiple Content-length entries found.");
-                } else {
-                    responseContentLength =
-                        Integer.parseInt(line.substring(key.length()).trim());
-                    contentLengthFound = true;
-                }
-            }
-        } while ((line.length() != 0) &&
-                 (line.charAt(0) != '\r') && (line.charAt(0) != '\n'));
-
-        if (!contentLengthFound || responseContentLength < 0)
-            throw new CGIServerException(
-                "missing or invalid content length in server response");
-        buffer = new byte[responseContentLength];
-        try {
-            socketIn.readFully(buffer);
-        } catch (EOFException e) {
-            throw new CGIServerException(
-                "unexpected EOF reading server response", e);
-        } catch (IOException e) {
-            throw new CGIServerException("error reading from server", e);
-        }
-
-        /*
-         * send response back to client
-         */
-        System.out.println("Status: 200 OK");
-        System.out.println("Content-type: application/octet-stream");
-        System.out.println("");
-        try {
-            System.out.write(buffer);
-        } catch (IOException e) {
-            throw new CGIServerException("error writing response", e);
-        }
-        System.out.flush();
-    }
-}
-
-/**
- * "gethostname" command: Return the host name of the server as the
- * response body
- */
-final class CGIGethostnameCommand implements CGICommandHandler {
-
-    public String getName() {
-        return "gethostname";
-    }
-
-    public void execute(String param)
-    {
-        System.out.println("Status: 200 OK");
-        System.out.println("Content-type: application/octet-stream");
-        System.out.println("Content-length: " +
-                           CGIHandler.ServerName.length());
-        System.out.println("");
-        System.out.print(CGIHandler.ServerName);
-        System.out.flush();
-    }
-}
-
-/**
- * "ping" command: Return an OK status to indicate that connection
- * was successful.
- */
-final class CGIPingCommand implements CGICommandHandler {
-
-    public String getName() {
-        return "ping";
-    }
-
-    public void execute(String param)
-    {
-        System.out.println("Status: 200 OK");
-        System.out.println("Content-type: application/octet-stream");
-        System.out.println("Content-length: 0");
-        System.out.println("");
-    }
-}
-
-/**
- * "tryhostname" command: Return a human readable message describing
- * what host name is available to local Java VMs.
- */
-final class CGITryHostnameCommand implements CGICommandHandler {
-
-    public String getName() {
-        return "tryhostname";
-    }
-
-    public void execute(String param)
-    {
-        System.out.println("Status: 200 OK");
-        System.out.println("Content-type: text/html");
-        System.out.println("");
-        System.out.println("<HTML>" +
-                           "<HEAD><TITLE>Java RMI Server Hostname Info" +
-                           "</TITLE></HEAD>" +
-                           "<BODY>");
-        System.out.println("<H1>Java RMI Server Hostname Info</H1>");
-        System.out.println("<H2>Local host name available to Java VM:</H2>");
-        System.out.print("<P>InetAddress.getLocalHost().getHostName()");
-        try {
-            String localHostName = InetAddress.getLocalHost().getHostName();
-
-            System.out.println(" = " + localHostName);
-        } catch (UnknownHostException e) {
-            System.out.println(" threw java.net.UnknownHostException");
-        }
-
-        System.out.println("<H2>Server host information obtained through CGI interface from HTTP server:</H2>");
-        System.out.println("<P>SERVER_NAME = " + CGIHandler.ServerName);
-        System.out.println("<P>SERVER_PORT = " + CGIHandler.ServerPort);
-        System.out.println("</BODY></HTML>");
-    }
-}
--- a/jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/HttpAwareServerSocket.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-/*
- * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.rmi.transport.proxy;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.net.ServerSocket;
-import java.net.Socket;
-import sun.rmi.runtime.Log;
-
-/**
- * The HttpAwareServerSocket class extends the java.net.ServerSocket
- * class.  It behaves like a ServerSocket, except that if
- * the first four bytes of an accepted socket are the letters "POST",
- * then it returns an HttpReceiveSocket instead of a java.net.Socket.
- * This means that the accept method blocks until four bytes have been
- * read from the new socket's input stream.
- */
-class HttpAwareServerSocket extends ServerSocket {
-
-    /**
-     * Create a server socket on a specified port.
-     * @param port the port
-     * @exception IOException IO error when opening the socket.
-     */
-    public HttpAwareServerSocket(int port) throws IOException
-    {
-        super(port);
-    }
-
-    /**
-     * Create a server socket, bind it to the specified local port
-     * and listen to it.  You can connect to an annonymous port by
-     * specifying the port number to be 0.  <i>backlog</i> specifies
-     * how many connection requests the system will queue up while waiting
-     * for the ServerSocket to execute accept().
-     * @param port the specified port
-     * @param backlog the number of queued connect requests pending accept
-     */
-    public HttpAwareServerSocket(int port, int backlog) throws IOException
-    {
-        super(port, backlog);
-    }
-
-    /**
-     * Accept a connection. This method will block until the connection
-     * is made and four bytes can be read from the input stream.
-     * If the first four bytes are "POST", then an HttpReceiveSocket is
-     * returned, which will handle the HTTP protocol wrapping.
-     * Otherwise, a WrappedSocket is returned.  The input stream will be
-     * reset to the beginning of the transmission.
-     * In either case, a BufferedInputStream will already be on top of
-     * the underlying socket's input stream.
-     * @exception IOException IO error when waiting for the connection.
-     */
-    public Socket accept() throws IOException
-    {
-        Socket socket = super.accept();
-        BufferedInputStream in =
-            new BufferedInputStream(socket.getInputStream());
-
-        RMIMasterSocketFactory.proxyLog.log(Log.BRIEF,
-            "socket accepted (checking for POST)");
-
-        in.mark(4);
-        boolean isHttp = (in.read() == 'P') &&
-                         (in.read() == 'O') &&
-                         (in.read() == 'S') &&
-                         (in.read() == 'T');
-        in.reset();
-
-        if (RMIMasterSocketFactory.proxyLog.isLoggable(Log.BRIEF)) {
-            RMIMasterSocketFactory.proxyLog.log(Log.BRIEF,
-                (isHttp ? "POST found, HTTP socket returned" :
-                          "POST not found, direct socket returned"));
-        }
-
-        if (isHttp)
-            return new HttpReceiveSocket(socket, in, null);
-        else
-            return new WrappedSocket(socket, in, null);
-    }
-
-    /**
-     * Return the implementation address and implementation port of
-     * the HttpAwareServerSocket as a String.
-     */
-    public String toString()
-    {
-        return "HttpAware" + super.toString();
-    }
-}
--- a/jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/HttpInputStream.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,205 +0,0 @@
-/*
- * Copyright (c) 1996, 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.rmi.transport.proxy;
-
-import java.io.*;
-
-import sun.rmi.runtime.Log;
-
-/**
- * The HttpInputStream class assists the HttpSendSocket and HttpReceiveSocket
- * classes by filtering out the header for the message as well as any
- * data after its proper content length.
- */
-class HttpInputStream extends FilterInputStream {
-
-    /** bytes remaining to be read from proper content of message */
-    protected int bytesLeft;
-
-    /** bytes remaining to be read at time of last mark */
-    protected int bytesLeftAtMark;
-
-    /**
-     * Create new filter on a given input stream.
-     * @param in the InputStream to filter from
-     */
-    @SuppressWarnings("deprecation")
-    public HttpInputStream(InputStream in) throws IOException
-    {
-        super(in);
-
-        if (in.markSupported())
-            in.mark(0); // prevent resetting back to old marks
-
-        // pull out header, looking for content length
-
-        DataInputStream dis = new DataInputStream(in);
-        String key = "Content-length:".toLowerCase();
-        boolean contentLengthFound = false;
-        String line;
-        do {
-            line = dis.readLine();
-
-            if (RMIMasterSocketFactory.proxyLog.isLoggable(Log.VERBOSE)) {
-                RMIMasterSocketFactory.proxyLog.log(Log.VERBOSE,
-                    "received header line: \"" + line + "\"");
-            }
-
-            if (line == null)
-                throw new EOFException();
-
-            if (line.toLowerCase().startsWith(key)) {
-                if (contentLengthFound) {
-                    throw new IOException(
-                            "Multiple Content-length entries found.");
-                } else {
-                    bytesLeft =
-                        Integer.parseInt(line.substring(key.length()).trim());
-                    contentLengthFound = true;
-                }
-            }
-
-            // The idea here is to go past the first blank line.
-            // Some DataInputStream.readLine() documentation specifies that
-            // it does include the line-terminating character(s) in the
-            // returned string, but it actually doesn't, so we'll cover
-            // all cases here...
-        } while ((line.length() != 0) &&
-                 (line.charAt(0) != '\r') && (line.charAt(0) != '\n'));
-
-        if (!contentLengthFound || bytesLeft < 0) {
-            // This really shouldn't happen, but if it does, shoud we fail??
-            // For now, just give up and let a whole lot of bytes through...
-            bytesLeft = Integer.MAX_VALUE;
-        }
-        bytesLeftAtMark = bytesLeft;
-
-        if (RMIMasterSocketFactory.proxyLog.isLoggable(Log.VERBOSE)) {
-            RMIMasterSocketFactory.proxyLog.log(Log.VERBOSE,
-                "content length: " + bytesLeft);
-        }
-    }
-
-    /**
-     * Returns the number of bytes that can be read with blocking.
-     * Make sure that this does not exceed the number of bytes remaining
-     * in the proper content of the message.
-     */
-    public int available() throws IOException
-    {
-        int bytesAvailable = in.available();
-        if (bytesAvailable > bytesLeft)
-            bytesAvailable = bytesLeft;
-
-        return bytesAvailable;
-    }
-
-    /**
-     * Read a byte of data from the stream.  Make sure that one is available
-     * from the proper content of the message, else -1 is returned to
-     * indicate to the user that the end of the stream has been reached.
-     */
-    public int read() throws IOException
-    {
-        if (bytesLeft > 0) {
-            int data = in.read();
-            if (data != -1)
-                -- bytesLeft;
-
-            if (RMIMasterSocketFactory.proxyLog.isLoggable(Log.VERBOSE)) {
-                RMIMasterSocketFactory.proxyLog.log(Log.VERBOSE,
-                   "received byte: '" +
-                    ((data & 0x7F) < ' ' ? " " : String.valueOf((char) data)) +
-                    "' " + data);
-            }
-
-            return data;
-        }
-        else {
-            RMIMasterSocketFactory.proxyLog.log(Log.VERBOSE,
-                                                "read past content length");
-
-            return -1;
-        }
-    }
-
-    public int read(byte b[], int off, int len) throws IOException
-    {
-        if (bytesLeft == 0 && len > 0) {
-            RMIMasterSocketFactory.proxyLog.log(Log.VERBOSE,
-                                                "read past content length");
-
-            return -1;
-        }
-        if (len > bytesLeft)
-            len = bytesLeft;
-        int bytesRead = in.read(b, off, len);
-        bytesLeft -= bytesRead;
-
-        if (RMIMasterSocketFactory.proxyLog.isLoggable(Log.VERBOSE)) {
-            RMIMasterSocketFactory.proxyLog.log(Log.VERBOSE,
-                "read " + bytesRead + " bytes, " + bytesLeft + " remaining");
-        }
-
-        return bytesRead;
-    }
-
-    /**
-     * Mark the current position in the stream (for future calls to reset).
-     * Remember where we are within the proper content of the message, so
-     * that a reset method call can recreate our state properly.
-     * @param readlimit how many bytes can be read before mark becomes invalid
-     */
-    public void mark(int readlimit)
-    {
-        in.mark(readlimit);
-        if (in.markSupported())
-            bytesLeftAtMark = bytesLeft;
-    }
-
-    /**
-     * Repositions the stream to the last marked position.  Make sure to
-     * adjust our position within the proper content accordingly.
-     */
-    public void reset() throws IOException
-    {
-        in.reset();
-        bytesLeft = bytesLeftAtMark;
-    }
-
-    /**
-     * Skips bytes of the stream.  Make sure to adjust our
-     * position within the proper content accordingly.
-     * @param n number of bytes to be skipped
-     */
-    public long skip(long n) throws IOException
-    {
-        if (n > bytesLeft)
-            n = bytesLeft;
-        long bytesSkipped = in.skip(n);
-        bytesLeft -= bytesSkipped;
-        return bytesSkipped;
-    }
-}
--- a/jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/HttpOutputStream.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 1996, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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.transport.proxy;
-
-import java.io.*;
-
-/**
- * The HttpOutputStream class assists the HttpSendSocket and HttpReceiveSocket
- * classes by providing an output stream that buffers its entire input until
- * closed, and then it sends the complete transmission prefixed by the end of
- * an HTTP header that specifies the content length.
- */
-class HttpOutputStream extends ByteArrayOutputStream {
-
-    /** the output stream to send response to */
-    protected OutputStream out;
-
-    /** true if HTTP response has been sent */
-    boolean responseSent = false;
-
-    /**
-     * Begin buffering new HTTP response to be sent to a given stream.
-     * @param out the OutputStream to send response to
-     */
-    public HttpOutputStream(OutputStream out) {
-        super();
-        this.out = out;
-    }
-
-    /**
-     * On close, send HTTP-packaged response.
-     */
-    public synchronized void close() throws IOException {
-        if (!responseSent) {
-            /*
-             * If response would have zero content length, then make it
-             * have some arbitrary data so that certain clients will not
-             * fail because the "document contains no data".
-             */
-            if (size() == 0)
-                write(emptyData);
-
-            DataOutputStream dos = new DataOutputStream(out);
-            dos.writeBytes("Content-type: application/octet-stream\r\n");
-            dos.writeBytes("Content-length: " + size() + "\r\n");
-            dos.writeBytes("\r\n");
-            writeTo(dos);
-            dos.flush();
-            // Do not close the underlying stream here, because that would
-            // close the underlying socket and prevent reading a response.
-            reset(); // reset byte array
-            responseSent = true;
-        }
-    }
-
-    /** data to send if the response would otherwise be empty */
-    private static byte[] emptyData = { 0 };
-}
--- a/jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/HttpReceiveSocket.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-/*
- * Copyright (c) 1996, 2000, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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.transport.proxy;
-
-import java.io.*;
-import java.net.Socket;
-import java.net.InetAddress;
-
-/**
- * The HttpReceiveSocket class extends the WrappedSocket class
- * by removing the HTTP protocol packaging from the input stream and
- * formatting the output stream as an HTTP response.
- *
- * NOTES:
- *
- * The output stream must be explicitly closed for the output to be
- * sent, since the HttpResponseOutputStream needs to buffer the entire
- * transmission to be able to fill in the content-length field of
- * the HTTP header.  Closing this socket will do this.
- *
- * The constructor blocks until the HTTP protocol header
- * is received.  This could be fixed, but I don't think it should be a
- * problem because this object would not be created unless the
- * HttpAwareServerSocket has detected the beginning of the header
- * anyway, so the rest should be there.
- *
- * This socket can only be used to process one POST and reply to it.
- * Another message would be received on a newly accepted socket anyway.
- */
-public class HttpReceiveSocket extends WrappedSocket implements RMISocketInfo {
-
-    /** true if the HTTP header has pushed through the output stream yet */
-    private boolean headerSent = false;
-
-    /**
-     * Layer on top of a pre-existing Socket object, and use specified
-     * input and output streams.
-     * @param socket the pre-existing socket to use
-     * @param in the InputStream to use for this socket (can be null)
-     * @param out the OutputStream to use for this socket (can be null)
-     */
-    public HttpReceiveSocket(Socket socket, InputStream in, OutputStream out)
-        throws IOException
-    {
-        super(socket, in, out);
-
-        this.in = new HttpInputStream(in != null ? in :
-                                                   socket.getInputStream());
-        this.out = (out != null ? out :
-                    socket.getOutputStream());
-    }
-
-    /**
-     * Indicate that this socket is not reusable.
-     */
-    public boolean isReusable()
-    {
-        return false;
-    }
-
-    /**
-     * Get the address to which this socket is connected.  "null" is always
-     * returned (to indicate an unknown address) because the originating
-     * host's IP address cannot be reliably determined: both because the
-     * request probably went through a proxy server, and because if it was
-     * delivered by a local forwarder (CGI script or servlet), we do NOT
-     * want it to appear as if the call is coming from the local host (in
-     * case the remote object makes access control decisions based on the
-     * "client host" of a remote call; see bugid 4399040).
-     */
-    public InetAddress getInetAddress() {
-        return null;
-    }
-
-    /**
-     * Get an OutputStream for this socket.
-     */
-    public OutputStream getOutputStream() throws IOException
-    {
-        if (!headerSent) { // could this be done in constructor??
-            DataOutputStream dos = new DataOutputStream(out);
-            dos.writeBytes("HTTP/1.0 200 OK\r\n");
-            dos.flush();
-            headerSent = true;
-            out = new HttpOutputStream(out);
-        }
-        return out;
-    }
-
-    /**
-     * Close the socket.
-     */
-    public synchronized void close() throws IOException
-    {
-        getOutputStream().close(); // make sure response is sent
-        socket.close();
-    }
-
-    /**
-     * Return string representation of the socket.
-     */
-    public String toString()
-    {
-        return "HttpReceive" + socket.toString();
-    }
-}
--- a/jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/HttpSendInputStream.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,161 +0,0 @@
-/*
- * Copyright (c) 1996, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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.transport.proxy;
-
-import java.io.*;
-
-/**
- * The HttpSendInputStream class is used by the HttpSendSocket class as
- * a layer on the top of the InputStream it returns so that it can be
- * notified of attempts to read from it.  This allows the HttpSendSocket
- * to know when it should push across its output message.
- */
-class HttpSendInputStream extends FilterInputStream {
-
-    /** the HttpSendSocket object that is providing this stream */
-    HttpSendSocket owner;
-
-    /**
-     * Create new filter on a given input stream.
-     * @param in the InputStream to filter from
-     * @param owner the HttpSendSocket that is providing this stream
-     */
-    public HttpSendInputStream(InputStream in, HttpSendSocket owner)
-        throws IOException
-    {
-        super(in);
-
-        this.owner = owner;
-    }
-
-    /**
-     * Mark this stream as inactive for its owner socket, so the next time
-     * a read is attempted, the owner will be notified and a new underlying
-     * input stream obtained.
-     */
-    public void deactivate()
-    {
-        in = null;
-    }
-
-    /**
-     * Read a byte of data from the stream.
-     */
-    public int read() throws IOException
-    {
-        if (in == null)
-            in = owner.readNotify();
-        return in.read();
-    }
-
-    /**
-     * Read into an array of bytes.
-     * @param b the buffer into which the data is to be read
-     * @param off the start offset of the data
-     * @param len the maximum number of bytes to read
-     */
-    public int read(byte b[], int off, int len) throws IOException
-    {
-        if (len == 0)
-            return 0;
-        if (in == null)
-            in = owner.readNotify();
-        return in.read(b, off, len);
-    }
-
-    /**
-     * Skip bytes of input.
-     * @param n the number of bytes to be skipped
-     */
-    public long skip(long n) throws IOException
-    {
-        if (n == 0)
-            return 0;
-        if (in == null)
-            in = owner.readNotify();
-        return in.skip(n);
-    }
-
-    /**
-     * Return the number of bytes that can be read without blocking.
-     */
-    public int available() throws IOException
-    {
-        if (in == null)
-            in = owner.readNotify();
-        return in.available();
-    }
-
-    /**
-     * Close the stream.
-     */
-    public void close() throws IOException
-    {
-        owner.close();
-    }
-
-    /**
-     * Mark the current position in the stream.
-     * @param readlimit how many bytes can be read before mark becomes invalid
-     */
-    public synchronized void mark(int readlimit)
-    {
-        if (in == null) {
-            try {
-                in = owner.readNotify();
-            }
-            catch (IOException e) {
-                return;
-            }
-        }
-        in.mark(readlimit);
-    }
-
-    /**
-     * Reposition the stream to the last marked position.
-     */
-    public synchronized void reset() throws IOException
-    {
-        if (in == null)
-            in = owner.readNotify();
-        in.reset();
-    }
-
-    /**
-     * Return true if this stream type supports mark/reset.
-     */
-    public boolean markSupported()
-    {
-        if (in == null) {
-            try {
-                in = owner.readNotify();
-            }
-            catch (IOException e) {
-                return false;
-            }
-        }
-        return in.markSupported();
-    }
-}
--- a/jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/HttpSendOutputStream.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 1996, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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.transport.proxy;
-
-import java.io.*;
-
-/**
- * The HttpSendOutputStream class is used by the HttpSendSocket class as
- * a layer on the top of the OutputStream it returns so that it can be
- * notified of attempts to write to it.  This allows the HttpSendSocket
- * to know when it should construct a new message.
- */
-class HttpSendOutputStream extends FilterOutputStream {
-
-    /** the HttpSendSocket object that is providing this stream */
-    HttpSendSocket owner;
-
-    /**
-     * Create new filter on a given output stream.
-     * @param out the OutputStream to filter from
-     * @param owner the HttpSendSocket that is providing this stream
-     */
-    public HttpSendOutputStream(OutputStream out, HttpSendSocket owner)
-        throws IOException
-    {
-        super(out);
-
-        this.owner = owner;
-    }
-
-    /**
-     * Mark this stream as inactive for its owner socket, so the next time
-     * a write is attempted, the owner will be notified and a new underlying
-     * output stream obtained.
-     */
-    public void deactivate()
-    {
-        out = null;
-    }
-
-    /**
-     * Write a byte of data to the stream.
-     */
-    public void write(int b) throws IOException
-    {
-        if (out == null)
-            out = owner.writeNotify();
-        out.write(b);
-    }
-
-    /**
-     * Write a subarray of bytes.
-     * @param b the buffer from which the data is to be written
-     * @param off the start offset of the data
-     * @param len the number of bytes to be written
-     */
-    public void write(byte b[], int off, int len) throws IOException
-    {
-        if (len == 0)
-            return;
-        if (out == null)
-            out = owner.writeNotify();
-        out.write(b, off, len);
-    }
-
-    /**
-     * Flush the stream.
-     */
-    public void flush() throws IOException
-    {
-        if (out != null)
-            out.flush();
-    }
-
-    /**
-     * Close the stream.
-     */
-    public void close() throws IOException
-    {
-        flush();
-        owner.close();
-    }
-}
--- a/jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/HttpSendSocket.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,344 +0,0 @@
-/*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.rmi.transport.proxy;
-
-import java.io.*;
-import java.net.*;
-import java.security.PrivilegedAction;
-
-import sun.rmi.runtime.Log;
-
-/**
- * The HttpSendSocket class extends the java.net.Socket class
- * by enclosing the data output stream in, then extracting the input
- * stream from, an HTTP protocol transmission.
- *
- * NOTES:
- *
- * Since the length of the output request must be known before the
- * HTTP header can be completed, all of the output is buffered by
- * an HttpOutputStream object until either an attempt is made to
- * read from this socket, or the socket is explicitly closed.
- *
- * On the first read attempt to read from this socket, the buffered
- * output is sent to the destination as the body of an HTTP POST
- * request.  All reads will then acquire data from the body of
- * the response.  A subsequent attempt to write to this socket will
- * throw an IOException.
- */
-class HttpSendSocket extends Socket implements RMISocketInfo {
-
-    /** the host to connect to */
-    protected String host;
-
-    /** the port to connect to */
-    protected int port;
-
-    /** the URL to forward through */
-    protected URL url;
-
-    /** the object managing this connection through the URL */
-    protected URLConnection conn = null;
-
-    /** internal input stream for this socket */
-    protected InputStream in = null;
-
-    /** internal output stream for this socket */
-    protected OutputStream out = null;
-
-    /** the notifying input stream returned to users */
-    protected HttpSendInputStream inNotifier;
-
-    /** the notifying output stream returned to users */
-    protected HttpSendOutputStream outNotifier;
-
-    /**
-     * Line separator string.  This is the value of the line.separator
-     * property at the moment that the socket was created.
-     */
-    private String lineSeparator =
-        java.security.AccessController.doPrivileged(
-            (PrivilegedAction<String>) () -> System.getProperty("line.separator"));
-
-    /**
-     * Create a stream socket and connect it to the specified port on
-     * the specified host.
-     * @param host the host
-     * @param port the port
-     */
-    public HttpSendSocket(String host, int port, URL url) throws IOException
-    {
-        super((SocketImpl)null);        // no underlying SocketImpl for this object
-
-        if (RMIMasterSocketFactory.proxyLog.isLoggable(Log.VERBOSE)) {
-            RMIMasterSocketFactory.proxyLog.log(Log.VERBOSE,
-                "host = " + host + ", port = " + port + ", url = " + url);
-        }
-
-        this.host = host;
-        this.port = port;
-        this.url = url;
-
-        inNotifier = new HttpSendInputStream(null, this);
-        outNotifier = new HttpSendOutputStream(writeNotify(), this);
-    }
-
-    /**
-     * Create a stream socket and connect it to the specified port on
-     * the specified host.
-     * @param host the host
-     * @param port the port
-     */
-    public HttpSendSocket(String host, int port) throws IOException
-    {
-        this(host, port, new URL("http", host, port, "/"));
-    }
-
-    /**
-     * Create a stream socket and connect it to the specified address on
-     * the specified port.
-     * @param address the address
-     * @param port the port
-     */
-    public HttpSendSocket(InetAddress address, int port) throws IOException
-    {
-        this(address.getHostName(), port);
-    }
-
-    /**
-     * Indicate that this socket is not reusable.
-     */
-    public boolean isReusable()
-    {
-        return false;
-    }
-
-    /**
-     * Create a new socket connection to host (or proxy), and prepare to
-     * send HTTP transmission.
-     */
-    public synchronized OutputStream writeNotify() throws IOException
-    {
-        if (conn != null) {
-            throw new IOException("attempt to write on HttpSendSocket after " +
-                                  "request has been sent");
-        }
-
-        conn = url.openConnection();
-        conn.setDoOutput(true);
-        conn.setUseCaches(false);
-        conn.setRequestProperty("Content-type", "application/octet-stream");
-
-        inNotifier.deactivate();
-        in = null;
-
-        return out = conn.getOutputStream();
-    }
-
-    /**
-     * Send HTTP output transmission and prepare to receive response.
-     */
-    public synchronized InputStream readNotify() throws IOException
-    {
-        RMIMasterSocketFactory.proxyLog.log(Log.VERBOSE,
-            "sending request and activating input stream");
-
-        outNotifier.deactivate();
-        out.close();
-        out = null;
-
-        try {
-            in = conn.getInputStream();
-        } catch (IOException e) {
-            RMIMasterSocketFactory.proxyLog.log(Log.BRIEF,
-                "failed to get input stream, exception: ", e);
-
-            throw new IOException("HTTP request failed");
-        }
-
-        /*
-         * If an HTTP error response is returned, sometimes an IOException
-         * is thrown, which is handled above, and other times it isn't, and
-         * the error response body will be available for reading.
-         * As a safety net to catch any such unexpected HTTP behavior, we
-         * verify that the content type of the response is what the
-         * HttpOutputStream generates: "application/octet-stream".
-         * (Servers' error responses will generally be "text/html".)
-         * Any error response body is printed to the log.
-         */
-        String contentType = conn.getContentType();
-        if (contentType == null ||
-            !conn.getContentType().equals("application/octet-stream"))
-        {
-            if (RMIMasterSocketFactory.proxyLog.isLoggable(Log.BRIEF)) {
-                String message;
-                if (contentType == null) {
-                    message = "missing content type in response" +
-                        lineSeparator;
-                } else {
-                    message = "invalid content type in response: " +
-                        contentType + lineSeparator;
-                }
-
-                message += "HttpSendSocket.readNotify: response body: ";
-                try {
-                    BufferedReader din = new BufferedReader(new InputStreamReader(in));
-                    String line;
-                    while ((line = din.readLine()) != null)
-                        message += line + lineSeparator;
-                } catch (IOException e) {
-                }
-                RMIMasterSocketFactory.proxyLog.log(Log.BRIEF, message);
-            }
-
-            throw new IOException("HTTP request failed");
-        }
-
-        return in;
-    }
-
-    /**
-     * Get the address to which the socket is connected.
-     */
-    public InetAddress getInetAddress()
-    {
-        try {
-            return InetAddress.getByName(host);
-        } catch (UnknownHostException e) {
-            return null;        // null if couldn't resolve destination host
-        }
-    }
-
-    /**
-     * Get the local address to which the socket is bound.
-     */
-    public InetAddress getLocalAddress()
-    {
-        try {
-            return InetAddress.getLocalHost();
-        } catch (UnknownHostException e) {
-            return null;        // null if couldn't determine local host
-        }
-    }
-
-    /**
-     * Get the remote port to which the socket is connected.
-     */
-    public int getPort()
-    {
-        return port;
-    }
-
-    /**
-     * Get the local port to which the socket is connected.
-     */
-    public int getLocalPort()
-    {
-        return -1;      // request not applicable to this socket type
-    }
-
-    /**
-     * Get an InputStream for this socket.
-     */
-    public InputStream getInputStream() throws IOException
-    {
-        return inNotifier;
-    }
-
-    /**
-     * Get an OutputStream for this socket.
-     */
-    public OutputStream getOutputStream() throws IOException
-    {
-        return outNotifier;
-    }
-
-    /**
-     * Enable/disable TCP_NODELAY.
-     * This operation has no effect for an HttpSendSocket.
-     */
-    public void setTcpNoDelay(boolean on) throws SocketException
-    {
-    }
-
-    /**
-     * Retrieve whether TCP_NODELAY is enabled.
-     */
-    public boolean getTcpNoDelay() throws SocketException
-    {
-        return false;   // imply option is disabled
-    }
-
-    /**
-     * Enable/disable SO_LINGER with the specified linger time.
-     * This operation has no effect for an HttpSendSocket.
-     */
-    public void setSoLinger(boolean on, int val) throws SocketException
-    {
-    }
-
-    /**
-     * Retrive setting for SO_LINGER.
-     */
-    public int getSoLinger() throws SocketException
-    {
-        return -1;      // imply option is disabled
-    }
-
-    /**
-     * Enable/disable SO_TIMEOUT with the specified timeout
-     * This operation has no effect for an HttpSendSocket.
-     */
-    public synchronized void setSoTimeout(int timeout) throws SocketException
-    {
-    }
-
-    /**
-     * Retrive setting for SO_TIMEOUT.
-     */
-    public synchronized int getSoTimeout() throws SocketException
-    {
-        return 0;       // imply option is disabled
-    }
-
-    /**
-     * Close the socket.
-     */
-    public synchronized void close() throws IOException
-    {
-        if (out != null) // push out transmission if not done
-            out.close();
-    }
-
-    /**
-     * Return string representation of this pseudo-socket.
-     */
-    public String toString()
-    {
-        return "HttpSendSocket[host=" + host +
-               ",port=" + port +
-               ",url=" + url + "]";
-    }
-}
--- a/jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/RMIDirectSocketFactory.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 1996, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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.transport.proxy;
-
-import java.io.IOException;
-import java.net.Socket;
-import java.net.ServerSocket;
-import java.rmi.server.RMISocketFactory;
-
-/**
- * RMIDirectSocketFactory creates a direct socket connection to the
- * specified port on the specified host.
- */
-public class RMIDirectSocketFactory extends RMISocketFactory {
-
-    public Socket createSocket(String host, int port) throws IOException
-    {
-        return new Socket(host, port);
-    }
-
-    public ServerSocket createServerSocket(int port) throws IOException
-    {
-        return new ServerSocket(port);
-    }
-}
--- a/jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/RMIHttpToCGISocketFactory.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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.transport.proxy;
-
-import java.io.IOException;
-import java.net.Socket;
-import java.net.ServerSocket;
-import java.net.URL;
-import java.rmi.server.RMISocketFactory;
-
-/**
- * RMIHttpToCGISocketFactory creates a socket connection to the
- * specified host that is comminicated within an HTTP request,
- * forwarded through the default firewall proxy, to the target host's
- * normal HTTP server, to a CGI program which forwards the request to
- * the actual specified port on the socket.
- */
-public class RMIHttpToCGISocketFactory extends RMISocketFactory {
-
-    public Socket createSocket(String host, int port)
-        throws IOException
-    {
-        return new HttpSendSocket(host, port,
-                                  new URL("http", host,
-                                          "/cgi-bin/java-rmi.cgi" +
-                                          "?forward=" + port));
-    }
-
-    public ServerSocket createServerSocket(int port) throws IOException
-    {
-        return new HttpAwareServerSocket(port);
-    }
-}
--- a/jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/RMIHttpToPortSocketFactory.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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.transport.proxy;
-
-import java.io.IOException;
-import java.net.Socket;
-import java.net.ServerSocket;
-import java.net.URL;
-import java.rmi.server.RMISocketFactory;
-
-/**
- * RMIHttpToPortSocketFactory creates a socket connection to the
- * specified host that is communicated within an HTTP request,
- * forwarded through the default firewall proxy, directly to the
- * specified port.
- */
-public class RMIHttpToPortSocketFactory extends RMISocketFactory {
-
-    public Socket createSocket(String host, int port)
-        throws IOException
-    {
-        return new HttpSendSocket(host, port,
-                                  new URL("http", host, port, "/"));
-    }
-
-    public ServerSocket createServerSocket(int port)
-        throws IOException
-    {
-        return new HttpAwareServerSocket(port);
-    }
-}
--- a/jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/RMIMasterSocketFactory.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,468 +0,0 @@
-/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.rmi.transport.proxy;
-
-import java.io.*;
-import java.net.*;
-import java.security.*;
-import java.util.*;
-import java.rmi.server.LogStream;
-import java.rmi.server.RMISocketFactory;
-import sun.rmi.runtime.Log;
-import sun.rmi.runtime.NewThreadAction;
-
-/**
- * RMIMasterSocketFactory attempts to create a socket connection to the
- * specified host using successively less efficient mechanisms
- * until one succeeds.  If the host is successfully connected to,
- * the factory for the successful mechanism is stored in an internal
- * hash table keyed by the host name, so that future attempts to
- * connect to the same host will automatically use the same
- * mechanism.
- */
-@SuppressWarnings("deprecation")
-public class RMIMasterSocketFactory extends RMISocketFactory {
-
-    /** "proxy" package log level */
-    static int logLevel = LogStream.parseLevel(getLogLevel());
-
-    private static String getLogLevel() {
-        return java.security.AccessController.doPrivileged(
-            (PrivilegedAction<String>) () -> System.getProperty("sun.rmi.transport.proxy.logLevel"));
-    }
-
-    /* proxy package log */
-    static final Log proxyLog =
-        Log.getLog("sun.rmi.transport.tcp.proxy",
-                   "transport", RMIMasterSocketFactory.logLevel);
-
-    /** timeout for attemping direct socket connections */
-    private static long connectTimeout = getConnectTimeout();
-
-    private static long getConnectTimeout() {
-        return java.security.AccessController.doPrivileged((PrivilegedAction<Long>) () ->
-            Long.getLong("sun.rmi.transport.proxy.connectTimeout", 15000)); // default: 15 seconds
-    }
-
-    /** whether to fallback to HTTP on general connect failures */
-    private static final boolean eagerHttpFallback =
-        java.security.AccessController.doPrivileged((PrivilegedAction<Boolean>) () ->
-            Boolean.getBoolean("sun.rmi.transport.proxy.eagerHttpFallback"));
-
-    /** table of hosts successfully connected to and the factory used */
-    private Hashtable<String, RMISocketFactory> successTable =
-        new Hashtable<>();
-
-    /** maximum number of hosts to remember successful connection to */
-    private static final int MaxRememberedHosts = 64;
-
-    /** list of the hosts in successTable in initial connection order */
-    private Vector<String> hostList = new Vector<>(MaxRememberedHosts);
-
-    /** default factory for initial use for direct socket connection */
-    protected RMISocketFactory initialFactory = new RMIDirectSocketFactory();
-
-    /** ordered list of factories to try as alternate connection
-      * mechanisms if a direct socket connections fails */
-    protected Vector<RMISocketFactory> altFactoryList;
-
-    /**
-     * Create a RMIMasterSocketFactory object.  Establish order of
-     * connection mechanisms to attempt on createSocket, if a direct
-     * socket connection fails.
-     */
-    public RMIMasterSocketFactory() {
-        altFactoryList = new Vector<>(2);
-        boolean setFactories = false;
-
-        try {
-            String proxyHost;
-            proxyHost = java.security.AccessController.doPrivileged(
-               (PrivilegedAction<String>) () -> System.getProperty("http.proxyHost"));
-
-            if (proxyHost == null)
-                proxyHost = java.security.AccessController.doPrivileged(
-                    (PrivilegedAction<String>) () -> System.getProperty("proxyHost"));
-
-            boolean disable = java.security.AccessController.doPrivileged(
-                (PrivilegedAction<String>) () -> System.getProperty("java.rmi.server.disableHttp", "true"))
-                .equalsIgnoreCase("true");
-
-            if (!disable && proxyHost != null && proxyHost.length() > 0) {
-                setFactories = true;
-            }
-        } catch (Exception e) {
-            // unable to obtain the properties, so use the default behavior.
-        }
-
-        if (setFactories) {
-            altFactoryList.addElement(new RMIHttpToPortSocketFactory());
-            altFactoryList.addElement(new RMIHttpToCGISocketFactory());
-        }
-    }
-
-    /**
-     * Create a new client socket.  If we remember connecting to this host
-     * successfully before, then use the same factory again.  Otherwise,
-     * try using a direct socket connection and then the alternate factories
-     * in the order specified in altFactoryList.
-     */
-    public Socket createSocket(String host, int port)
-        throws IOException
-    {
-        if (proxyLog.isLoggable(Log.BRIEF)) {
-            proxyLog.log(Log.BRIEF, "host: " + host + ", port: " + port);
-        }
-
-        /*
-         * If we don't have any alternate factories to consult, short circuit
-         * the fallback procedure and delegate to the initial factory.
-         */
-        if (altFactoryList.size() == 0) {
-            return initialFactory.createSocket(host, port);
-        }
-
-        RMISocketFactory factory;
-
-        /*
-         * If we remember successfully connecting to this host before,
-         * use the same factory.
-         */
-        factory = successTable.get(host);
-        if (factory != null) {
-            if (proxyLog.isLoggable(Log.BRIEF)) {
-                proxyLog.log(Log.BRIEF,
-                    "previously successful factory found: " + factory);
-            }
-            return factory.createSocket(host, port);
-        }
-
-        /*
-         * Next, try a direct socket connection.  Open socket in another
-         * thread and only wait for specified timeout, in case the socket
-         * would otherwise spend minutes trying an unreachable host.
-         */
-        Socket initialSocket = null;
-        Socket fallbackSocket = null;
-        final AsyncConnector connector =
-            new AsyncConnector(initialFactory, host, port,
-                AccessController.getContext());
-                // connection must be attempted with
-                // this thread's access control context
-        IOException initialFailure = null;
-
-        try {
-            synchronized (connector) {
-
-                Thread t = java.security.AccessController.doPrivileged(
-                    new NewThreadAction(connector, "AsyncConnector", true));
-                t.start();
-
-                try {
-                    long now = System.currentTimeMillis();
-                    long deadline = now + connectTimeout;
-                    do {
-                        connector.wait(deadline - now);
-                        initialSocket = checkConnector(connector);
-                        if (initialSocket != null)
-                            break;
-                        now = System.currentTimeMillis();
-                    } while (now < deadline);
-                } catch (InterruptedException e) {
-                    throw new InterruptedIOException(
-                        "interrupted while waiting for connector");
-                }
-            }
-
-            // assume no route to host (for now) if no connection yet
-            if (initialSocket == null)
-                throw new NoRouteToHostException(
-                    "connect timed out: " + host);
-
-            proxyLog.log(Log.BRIEF, "direct socket connection successful");
-
-            return initialSocket;
-
-        } catch (UnknownHostException | NoRouteToHostException e) {
-            initialFailure = e;
-        } catch (SocketException e) {
-            if (eagerHttpFallback) {
-                initialFailure = e;
-            } else {
-                throw e;
-            }
-        } finally {
-            if (initialFailure != null) {
-
-                if (proxyLog.isLoggable(Log.BRIEF)) {
-                    proxyLog.log(Log.BRIEF,
-                        "direct socket connection failed: ", initialFailure);
-                }
-
-                // Finally, try any alternate connection mechanisms.
-                for (int i = 0; i < altFactoryList.size(); ++ i) {
-                    factory = altFactoryList.elementAt(i);
-                    if (proxyLog.isLoggable(Log.BRIEF)) {
-                        proxyLog.log(Log.BRIEF,
-                            "trying with factory: " + factory);
-                    }
-                    try (Socket testSocket =
-                            factory.createSocket(host, port)) {
-                        // For HTTP connections, the output (POST request) must
-                        // be sent before we verify a successful connection.
-                        // So, sacrifice a socket for the sake of testing...
-                        // The following sequence should verify a successful
-                        // HTTP connection if no IOException is thrown.
-                        InputStream in = testSocket.getInputStream();
-                        int b = in.read(); // probably -1 for EOF...
-                    } catch (IOException ex) {
-                        if (proxyLog.isLoggable(Log.BRIEF)) {
-                            proxyLog.log(Log.BRIEF, "factory failed: ", ex);
-                        }
-
-                        continue;
-                    }
-                    proxyLog.log(Log.BRIEF, "factory succeeded");
-
-                    // factory succeeded, open new socket for caller's use
-                    try {
-                        fallbackSocket = factory.createSocket(host, port);
-                    } catch (IOException ex) {  // if it fails 2nd time,
-                    }                           // just give up
-                    break;
-                }
-            }
-        }
-
-        synchronized (successTable) {
-            try {
-                // check once again to see if direct connection succeeded
-                synchronized (connector) {
-                    initialSocket = checkConnector(connector);
-                }
-                if (initialSocket != null) {
-                    // if we had made another one as well, clean it up...
-                    if (fallbackSocket != null)
-                        fallbackSocket.close();
-                    return initialSocket;
-                }
-                // if connector ever does get socket, it won't be used
-                connector.notUsed();
-            } catch (UnknownHostException | NoRouteToHostException e) {
-                initialFailure = e;
-            } catch (SocketException e) {
-                if (eagerHttpFallback) {
-                    initialFailure = e;
-                } else {
-                    throw e;
-                }
-            }
-            // if we had found an alternate mechanism, go and use it
-            if (fallbackSocket != null) {
-                // remember this successful host/factory pair
-                rememberFactory(host, factory);
-                return fallbackSocket;
-            }
-            throw initialFailure;
-        }
-    }
-
-    /**
-     * Remember a successful factory for connecting to host.
-     * Currently, excess hosts are removed from the remembered list
-     * using a Least Recently Created strategy.
-     */
-    void rememberFactory(String host, RMISocketFactory factory) {
-        synchronized (successTable) {
-            while (hostList.size() >= MaxRememberedHosts) {
-                successTable.remove(hostList.elementAt(0));
-                hostList.removeElementAt(0);
-            }
-            hostList.addElement(host);
-            successTable.put(host, factory);
-        }
-    }
-
-    /**
-     * Check if an AsyncConnector succeeded.  If not, return socket
-     * given to fall back to.
-     */
-    Socket checkConnector(AsyncConnector connector)
-        throws IOException
-    {
-        Exception e = connector.getException();
-        if (e != null) {
-            e.fillInStackTrace();
-            /*
-             * The AsyncConnector implementation guaranteed that the exception
-             * will be either an IOException or a RuntimeException, and we can
-             * only throw one of those, so convince that compiler that it must
-             * be one of those.
-             */
-            if (e instanceof IOException) {
-                throw (IOException) e;
-            } else if (e instanceof RuntimeException) {
-                throw (RuntimeException) e;
-            } else {
-                throw new Error("internal error: " +
-                    "unexpected checked exception: " + e.toString());
-            }
-        }
-        return connector.getSocket();
-    }
-
-    /**
-     * Create a new server socket.
-     */
-    public ServerSocket createServerSocket(int port) throws IOException {
-        //return new HttpAwareServerSocket(port);
-        return initialFactory.createServerSocket(port);
-    }
-
-
-    /**
-     * AsyncConnector is used by RMIMasterSocketFactory to attempt socket
-     * connections on a separate thread.  This allows RMIMasterSocketFactory
-     * to control how long it will wait for the connection to succeed.
-     */
-    private class AsyncConnector implements Runnable {
-
-        /** what factory to use to attempt connection */
-        private RMISocketFactory factory;
-
-        /** the host to connect to */
-        private String host;
-
-        /** the port to connect to */
-        private int port;
-
-        /** access control context to attempt connection within */
-        private AccessControlContext acc;
-
-        /** exception that occurred during connection, if any */
-        private Exception exception = null;
-
-        /** the connected socket, if successful */
-        private Socket socket = null;
-
-        /** socket should be closed after created, if ever */
-        private boolean cleanUp = false;
-
-        /**
-         * Create a new asynchronous connector object.
-         */
-        AsyncConnector(RMISocketFactory factory, String host, int port,
-                       AccessControlContext acc)
-        {
-            this.factory = factory;
-            this.host    = host;
-            this.port    = port;
-            this.acc     = acc;
-            SecurityManager security = System.getSecurityManager();
-            if (security != null) {
-                security.checkConnect(host, port);
-            }
-        }
-
-        /**
-         * Attempt socket connection in separate thread.  If successful,
-         * notify master waiting,
-         */
-        public void run() {
-            try {
-                /*
-                 * Using the privileges of the thread that wants to make the
-                 * connection is tempting, but it will fail with applets with
-                 * the current applet security manager because the applet
-                 * network connection policy is not captured in the permission
-                 * framework of the access control context we have.
-                 *
-                 * java.security.AccessController.beginPrivileged(acc);
-                 */
-                try {
-                    Socket temp = factory.createSocket(host, port);
-                    synchronized (this) {
-                        socket = temp;
-                        notify();
-                    }
-                    rememberFactory(host, factory);
-                    synchronized (this) {
-                        if (cleanUp)
-                          try {
-                              socket.close();
-                          } catch (IOException e) {
-                          }
-                    }
-                } catch (Exception e) {
-                    /*
-                     * Note that the only exceptions which could actually have
-                     * occurred here are IOException or RuntimeException.
-                     */
-                    synchronized (this) {
-                        exception = e;
-                        notify();
-                    }
-                }
-            } finally {
-                /*
-                 * See above comments for matching beginPrivileged() call that
-                 * is also commented out.
-                 *
-                 * java.security.AccessController.endPrivileged();
-                 */
-            }
-        }
-
-        /**
-         * Get exception that occurred during connection attempt, if any.
-         * In the current implementation, this is guaranteed to be either
-         * an IOException or a RuntimeException.
-         */
-        private synchronized Exception getException() {
-            return exception;
-        }
-
-        /**
-         * Get successful socket, if any.
-         */
-        private synchronized Socket getSocket() {
-            return socket;
-        }
-
-        /**
-         * Note that this connector's socket, if ever successfully created,
-         * will not be used, so it should be cleaned up quickly
-         */
-        synchronized void notUsed() {
-            if (socket != null) {
-                try {
-                    socket.close();
-                } catch (IOException e) {
-                }
-            }
-            cleanUp = true;
-        }
-    }
-}
--- a/jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/RMISocketInfo.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 1996, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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.transport.proxy;
-
-/**
- * RMISocketInfo is an interface that extensions of the java.net.Socket
- * class may use to provide more information on its capabilities.
- */
-public interface RMISocketInfo {
-
-    /**
-     * Return true if this socket can be used for more than one
-     * RMI call.  If a socket does not implement this interface, then
-     * it is assumed to be reusable.
-     */
-    public boolean isReusable();
-}
--- a/jdk/src/java.rmi/share/classes/sun/rmi/transport/proxy/WrappedSocket.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,192 +0,0 @@
-/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.rmi.transport.proxy;
-
-import java.io.*;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.SocketException;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-/**
- * The WrappedSocket class provides a general wrapper for providing an
- * extended implementation of java.net.Socket that can be attached to
- * a pre-existing Socket object.  WrappedSocket itself provides a
- * constructor for specifying alternate input or output streams to be
- * returned than those of the underlying Socket.
- */
-class WrappedSocket extends Socket {
-
-    /** the underlying concrete socket */
-    protected Socket socket;
-
-    /** the input stream to return for socket */
-    protected InputStream in = null;
-
-    /** the output stream to return for socket */
-    protected OutputStream out = null;
-
-    /**
-     * Layer on top of a pre-existing Socket object, and use specified
-     * input and output streams.  This allows the creator of the
-     * underlying socket to peek at the beginning of the input with a
-     * BufferedInputStream and determine which kind of socket
-     * to create, without consuming the input.
-     * @param socket the pre-existing socket to use
-     * @param in the InputStream to return to users (can be null)
-     * @param out the OutputStream to return to users (can be null)
-     */
-    public WrappedSocket(Socket socket, InputStream in, OutputStream out)
-        throws IOException
-    {
-        super((java.net.SocketImpl)null);       // no underlying SocketImpl for this object
-        this.socket = socket;
-        this.in = in;
-        this.out = out;
-    }
-
-    /**
-     * Get the address to which the socket is connected.
-     */
-    public InetAddress getInetAddress()
-    {
-        return socket.getInetAddress();
-    }
-
-    /**
-     * Get the local address to which the socket is bound.
-     */
-    public InetAddress getLocalAddress() {
-        return  AccessController.doPrivileged(
-                        new PrivilegedAction<InetAddress>() {
-                            @Override
-                            public InetAddress run() {
-                                return socket.getLocalAddress();
-
-                            }
-                        });
-    }
-
-    /**
-     * Get the remote port to which the socket is connected.
-     */
-    public int getPort()
-    {
-        return socket.getPort();
-    }
-
-    /**
-     * Get the local port to which the socket is connected.
-     */
-    public int getLocalPort()
-    {
-        return socket.getLocalPort();
-    }
-
-    /**
-     * Get an InputStream for this socket.
-     */
-    public InputStream getInputStream() throws IOException
-    {
-        if (in == null)
-            in = socket.getInputStream();
-        return in;
-    }
-
-    /**
-     * Get an OutputStream for this socket.
-     */
-    public OutputStream getOutputStream() throws IOException
-    {
-        if (out == null)
-            out = socket.getOutputStream();
-        return out;
-    }
-
-    /**
-     * Enable/disable TCP_NODELAY.
-     */
-    public void setTcpNoDelay(boolean on) throws SocketException
-    {
-        socket.setTcpNoDelay(on);
-    }
-
-    /**
-     * Retrieve whether TCP_NODELAY is enabled.
-     */
-    public boolean getTcpNoDelay() throws SocketException
-    {
-        return socket.getTcpNoDelay();
-    }
-
-    /**
-     * Enable/disable SO_LINGER with the specified linger time.
-     */
-    public void setSoLinger(boolean on, int val) throws SocketException
-    {
-        socket.setSoLinger(on, val);
-    }
-
-    /**
-     * Retrive setting for SO_LINGER.
-     */
-    public int getSoLinger() throws SocketException
-    {
-        return socket.getSoLinger();
-    }
-
-    /**
-     * Enable/disable SO_TIMEOUT with the specified timeout
-     */
-    public synchronized void setSoTimeout(int timeout) throws SocketException
-    {
-        socket.setSoTimeout(timeout);
-    }
-
-    /**
-     * Retrive setting for SO_TIMEOUT.
-     */
-    public synchronized int getSoTimeout() throws SocketException
-    {
-        return socket.getSoTimeout();
-    }
-
-    /**
-     * Close the socket.
-     */
-    public synchronized void close() throws IOException
-    {
-        socket.close();
-    }
-
-    /**
-     * Return string representation of the socket.
-     */
-    public String toString()
-    {
-        return "Wrapped" + socket.toString();
-    }
-}
--- a/jdk/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPConnection.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPConnection.java	Thu May 12 11:03:07 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2001, 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,14 +26,10 @@
 package sun.rmi.transport.tcp;
 
 import java.io.*;
-import java.net.InetAddress;
 import java.net.Socket;
-import java.net.SocketException;
 import java.rmi.*;
-import java.rmi.server.RMISocketFactory;
 import sun.rmi.runtime.Log;
 import sun.rmi.transport.*;
-import sun.rmi.transport.proxy.*;
 
 public class TCPConnection implements Connection {
 
@@ -120,10 +116,7 @@
      */
     public boolean isReusable()
     {
-        if ((socket != null) && (socket instanceof RMISocketInfo))
-            return ((RMISocketInfo) socket).isReusable();
-        else
-            return true;
+        return true;
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPDirectSocketFactory.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1996, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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.transport.tcp;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.net.ServerSocket;
+import java.rmi.server.RMISocketFactory;
+
+/**
+ * RMIDirectSocketFactory creates a direct socket connection to the
+ * specified port on the specified host.
+ */
+public class TCPDirectSocketFactory extends RMISocketFactory {
+
+    public Socket createSocket(String host, int port) throws IOException
+    {
+        return new Socket(host, port);
+    }
+
+    public ServerSocket createServerSocket(int port) throws IOException
+    {
+        return new ServerSocket(port);
+    }
+}
--- a/jdk/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPTransport.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPTransport.java	Thu May 12 11:03:07 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2014, 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
@@ -75,7 +75,6 @@
 import sun.rmi.transport.Target;
 import sun.rmi.transport.Transport;
 import sun.rmi.transport.TransportConstants;
-import sun.rmi.transport.proxy.HttpReceiveSocket;
 
 /**
  * TCPTransport is the socket-based implementation of the RMI Transport
@@ -711,35 +710,10 @@
                         ? sockIn
                         : new BufferedInputStream(sockIn);
 
-                // Read magic (or HTTP wrapper)
-                bufIn.mark(4);
+                // Read magic
                 DataInputStream in = new DataInputStream(bufIn);
                 int magic = in.readInt();
 
-                if (magic == POST) {
-                    tcpLog.log(Log.BRIEF, "decoding HTTP-wrapped call");
-
-                    // It's really a HTTP-wrapped request.  Repackage
-                    // the socket in a HttpReceiveSocket, reinitialize
-                    // sockIn and in, and reread magic.
-                    bufIn.reset();      // unread "POST"
-
-                    try {
-                        socket = new HttpReceiveSocket(socket, bufIn, null);
-                        remoteHost = "0.0.0.0";
-                        sockIn = socket.getInputStream();
-                        bufIn = new BufferedInputStream(sockIn);
-                        in = new DataInputStream(bufIn);
-                        magic = in.readInt();
-
-                    } catch (IOException e) {
-                        throw new RemoteException("Error HTTP-unwrapping call",
-                                                  e);
-                    }
-                }
-                // bufIn's mark will invalidate itself when it overflows
-                // so it doesn't have to be turned off
-
                 // read and verify transport header
                 short version = in.readShort();
                 if (magic != TransportConstants.Magic ||
--- a/jdk/src/java.security.jgss/share/classes/javax/security/auth/kerberos/EncryptionKey.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.security.jgss/share/classes/javax/security/auth/kerberos/EncryptionKey.java	Thu May 12 11:03:07 2016 -0700
@@ -61,7 +61,7 @@
     private transient boolean destroyed = false;
 
     /**
-     * Constructs a {@code EncryptionKey} from the given bytes and
+     * Constructs an {@code EncryptionKey} from the given bytes and
      * the key type.
      * <p>
      * The contents of the byte array are copied; subsequent modification of
--- a/jdk/src/java.sql.rowset/share/classes/com/sun/rowset/JdbcRowSetImpl.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.sql.rowset/share/classes/com/sun/rowset/JdbcRowSetImpl.java	Thu May 12 11:03:07 2016 -0700
@@ -3799,7 +3799,7 @@
      * Retrieves the column id as {@code int} array that was set using
      * {@code setMatchColumn(int [])} for this rowset.
      *
-     * @return a {@code int} array object that contains the column ids
+     * @return an {@code int} array object that contains the column ids
      *         for the rowset which has this as the match columns.
      *
      * @throws SQLException if an error occurs or column index is not set
@@ -6226,7 +6226,7 @@
 
 
    /**
-    * Sets the designated parameter to a {@code InputStream} object.  The inputstream must contain  the number
+    * Sets the designated parameter to an {@code InputStream} object.  The inputstream must contain  the number
     * of characters specified by length otherwise a {@code SQLException} will be
     * generated when the {@code PreparedStatement} is executed.
     * This method differs from the {@code setBinaryStream (int, InputStream, int)}
@@ -6256,7 +6256,7 @@
    }
 
  /**
-    * Sets the designated parameter to a {@code InputStream} object.
+    * Sets the designated parameter to an {@code InputStream} object.
     * This method differs from the {@code setBinaryStream (int, InputStream)}
     * This method differs from the {@code setBinaryStream (int, InputStream)}
     * method because it informs the driver that the parameter value should be
@@ -6287,7 +6287,7 @@
    }
 
    /**
-    * Sets the designated parameter to a {@code InputStream} object.  The {@code inputstream} must contain  the number
+    * Sets the designated parameter to an {@code InputStream} object.  The {@code inputstream} must contain  the number
     * of characters specified by length, otherwise a {@code SQLException} will be
     * generated when the {@code CallableStatement} is executed.
     * This method differs from the {@code setBinaryStream (int, InputStream, int)}
@@ -6336,7 +6336,7 @@
    }
 
    /**
-    * Sets the designated parameter to a {@code InputStream} object.
+    * Sets the designated parameter to an {@code InputStream} object.
     * This method differs from the {@code setBinaryStream (int, InputStream)}
     * method because it informs the driver that the parameter value should be
     * sent to the server as a {@code BLOB}.  When the {@code setBinaryStream} method is used,
--- a/jdk/src/java.sql.rowset/share/classes/com/sun/rowset/internal/SyncResolverImpl.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.sql.rowset/share/classes/com/sun/rowset/internal/SyncResolverImpl.java	Thu May 12 11:03:07 2016 -0700
@@ -4586,7 +4586,7 @@
      * Retrieves the column id as {@code int} array that was set using
      * {@code setMatchColumn(int [])} for this rowset.
      *
-     * @return a {@code int} array object that contains the column ids
+     * @return an {@code int} array object that contains the column ids
      *         for the rowset which has this as the match columns.
      *
      * @throws SQLException if an error occurs or column index is not set
--- a/jdk/src/java.sql/share/classes/java/sql/CallableStatement.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.sql/share/classes/java/sql/CallableStatement.java	Thu May 12 11:03:07 2016 -0700
@@ -1882,7 +1882,7 @@
        throws SQLException;
 
     /**
-     * Sets the designated parameter to a {@code InputStream} object.
+     * Sets the designated parameter to an {@code InputStream} object.
      * The <code>Inputstream</code> must contain the number
      * of characters specified by length, otherwise a <code>SQLException</code> will be
      * generated when the <code>CallableStatement</code> is executed.
@@ -2379,7 +2379,7 @@
        throws SQLException;
 
     /**
-     * Sets the designated parameter to a {@code InputStream} object.
+     * Sets the designated parameter to an {@code InputStream} object.
      * This method differs from the <code>setBinaryStream (int, InputStream)</code>
      * method because it informs the driver that the parameter value should be
      * sent to the server as a <code>BLOB</code>.  When the <code>setBinaryStream</code> method is used,
--- a/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/encryption/AgreementMethod.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/encryption/AgreementMethod.java	Thu May 12 11:03:07 2016 -0700
@@ -101,7 +101,7 @@
     /**
      * Adds additional {@code AgreementMethod} information.
      *
-     * @param info a {@code Element} that represents additional information
+     * @param info an {@code Element} that represents additional information
      * specified by
      *   <pre>{@code
      *     <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
@@ -112,7 +112,7 @@
     /**
      * Removes additional {@code AgreementMethod} information.
      *
-     * @param info a {@code Element} that represents additional information
+     * @param info an {@code Element} that represents additional information
      * specified by
      *   <pre>{@code
      *     <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
--- a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/InvalidModuleException.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/InvalidModuleException.java	Thu May 12 11:03:07 2016 -0700
@@ -36,14 +36,14 @@
     private static final long serialVersionUID = 7907359387320658039L;
 
     /**
-     * Constructs a {@code InvalidModuleException} with no detail message.
+     * Constructs an {@code InvalidModuleException} with no detail message.
      */
     public InvalidModuleException() {
         super();
     }
 
     /**
-     * Constructs a {@code InvalidModuleException} with the given detail
+     * Constructs an {@code InvalidModuleException} with the given detail
      * message.
      *
      * @param msg
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/PluginOrderingGraph.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/PluginOrderingGraph.java	Thu May 12 11:03:07 2016 -0700
@@ -35,10 +35,6 @@
 import jdk.tools.jlink.plugin.Plugin;
 import jdk.tools.jlink.plugin.PluginException;
 
-/**
- *
- * @author jdenise
- */
 public class PluginOrderingGraph {
 
     static class Node {
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Utils.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Utils.java	Thu May 12 11:03:07 2016 -0700
@@ -32,10 +32,6 @@
 import jdk.tools.jlink.plugin.Plugin;
 import jdk.tools.jlink.plugin.Plugin.PluginType;
 
-/**
- *
- * @author jdenise
- */
 public class Utils {
 
     private Utils() {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OrderResourcesPlugin.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,214 @@
+/*
+ * 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.jlink.internal.plugins;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+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.Set;
+import java.util.function.ToIntFunction;
+import jdk.tools.jlink.plugin.PluginException;
+import jdk.tools.jlink.plugin.Pool;
+import jdk.tools.jlink.plugin.Pool.ModuleData;
+import jdk.tools.jlink.plugin.Pool.ModuleDataType;
+import jdk.tools.jlink.plugin.TransformerPlugin;
+import jdk.tools.jlink.internal.Utils;
+
+/**
+ *
+ * Order Resources plugin
+ */
+public final class OrderResourcesPlugin implements TransformerPlugin {
+    public static final String NAME = "order-resources";
+    private final List<ToIntFunction<String>> filters;
+    private final Map<String, Integer> orderedPaths;
+
+    public OrderResourcesPlugin() {
+        this.filters = new ArrayList<>();
+        this.orderedPaths = new HashMap<>();
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
+    }
+
+    static class SortWrapper {
+        private final ModuleData resource;
+        private final int ordinal;
+
+        SortWrapper(ModuleData resource, int ordinal) {
+            this.resource = resource;
+            this.ordinal = ordinal;
+        }
+
+        ModuleData getResource() {
+            return resource;
+        }
+
+        String getPath() {
+            return resource.getPath();
+        }
+
+        int getOrdinal() {
+            return ordinal;
+        }
+    }
+
+    private String stripModule(String path) {
+        if (path.startsWith("/")) {
+            int index = path.indexOf('/', 1);
+
+            if (index != -1) {
+                return path.substring(index + 1);
+            }
+        }
+
+        return path;
+    }
+
+    private int getOrdinal(ModuleData resource) {
+        String path = resource.getPath();
+
+        Integer value = orderedPaths.get(stripModule(path));
+
+        if (value != null) {
+            return value;
+        }
+
+        for (ToIntFunction<String> function : filters) {
+            int ordinal = function.applyAsInt(path);
+
+            if (ordinal != Integer.MAX_VALUE) {
+                return ordinal;
+            }
+        }
+
+        return Integer.MAX_VALUE;
+    }
+
+    private static int compare(SortWrapper wrapper1, SortWrapper wrapper2) {
+        int compare = wrapper1.getOrdinal() - wrapper2.getOrdinal();
+
+        if (compare != 0) {
+            return compare;
+        }
+
+        return wrapper1.getPath().compareTo(wrapper2.getPath());
+    }
+
+    @Override
+    public void visit(Pool in, Pool out) {
+        in.getContent().stream()
+                .filter(resource -> resource.getType()
+                        .equals(ModuleDataType.CLASS_OR_RESOURCE))
+                .map((resource) -> new SortWrapper(resource, getOrdinal(resource)))
+                .sorted(OrderResourcesPlugin::compare)
+                .forEach((wrapper) -> out.add(wrapper.getResource()));
+        in.getContent().stream()
+                .filter(other -> !other.getType()
+                        .equals(ModuleDataType.CLASS_OR_RESOURCE))
+                .forEach((other) -> out.add(other));
+    }
+
+    @Override
+    public Set<PluginType> getType() {
+        Set<PluginType> set = new HashSet<>();
+        set.add(CATEGORY.SORTER);
+
+        return Collections.unmodifiableSet(set);
+    }
+
+    @Override
+    public String getDescription() {
+        return PluginsResourceBundle.getDescription(NAME);
+    }
+
+    @Override
+    public boolean hasArguments() {
+        return true;
+    }
+
+    @Override
+    public String getArgumentsDescription() {
+       return PluginsResourceBundle.getArgument(NAME);
+    }
+
+    @Override
+    public void configure(Map<String, String> config) {
+        String val = config.get(NAME);
+        String[] patterns = Utils.listParser.apply(val);
+        int ordinal = 0;
+
+        for (String pattern : patterns) {
+            if (pattern.startsWith("@")) {
+                File file = new File(pattern.substring(1));
+
+                if (file.exists()) {
+                    List<String> lines;
+
+                    try {
+                        lines = Files.readAllLines(file.toPath());
+                    } catch (IOException ex) {
+                        throw new PluginException(ex);
+                    }
+
+                    for (String line : lines) {
+                        if (!line.startsWith("#")) {
+                            orderedPaths.put(line + ".class", ordinal++);
+                        }
+                    }
+                }
+            } else {
+                boolean endsWith = pattern.startsWith("*");
+                boolean startsWith = pattern.endsWith("*");
+                ToIntFunction<String> function;
+                final int result = ordinal++;
+
+                if (startsWith && endsWith) {
+                    final String string = pattern.substring(1, pattern.length() - 1);
+                    function = (path)-> path.contains(string) ? result : Integer.MAX_VALUE;
+                } else if (startsWith) {
+                    final String string = pattern.substring(0, pattern.length() - 1);
+                    function = (path)-> path.startsWith(string) ? result : Integer.MAX_VALUE;
+                } else if (endsWith) {
+                    final String string = pattern.substring(1);
+                    function = (path)-> path.endsWith(string) ? result : Integer.MAX_VALUE;
+                } else {
+                    final String string = pattern;
+                    function = (path)-> path.equals(string) ? result : Integer.MAX_VALUE;
+                }
+
+                filters.add(function);
+            }
+        }
+    }
+}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SortResourcesPlugin.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,201 +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.jlink.internal.plugins;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-import jdk.tools.jlink.plugin.PluginException;
-import jdk.tools.jlink.plugin.Pool;
-import jdk.tools.jlink.plugin.Pool.ModuleData;
-import jdk.tools.jlink.plugin.Pool.ModuleDataType;
-import jdk.tools.jlink.plugin.TransformerPlugin;
-import jdk.tools.jlink.internal.Utils;
-
-/**
- *
- * Sort Resources plugin
- */
-public final class SortResourcesPlugin implements TransformerPlugin {
-
-    public static final String NAME = "sort-resources";
-    private final List<Pattern> filters = new ArrayList<>();
-    private List<String> orderedPaths;
-    private boolean isFile;
-
-    @Override
-    public String getName() {
-        return NAME;
-    }
-
-    static class SortWrapper {
-
-        private final ModuleData resource;
-        private final int ordinal;
-
-        SortWrapper(ModuleData resource, int ordinal) {
-            this.resource = resource;
-            this.ordinal = ordinal;
-        }
-
-        ModuleData getResource() {
-            return resource;
-        }
-
-        String getPath() {
-            return resource.getPath();
-        }
-
-        int getOrdinal() {
-            return ordinal;
-        }
-    }
-
-    private int getPatternOrdinal(String path) {
-        int ordinal = -1;
-        for (int i = 0; i < filters.size(); i++) {
-            Matcher m = filters.get(i).matcher(path);
-            if (m.matches()) {
-                ordinal = i;
-                break;
-            }
-        }
-        return ordinal;
-    }
-
-    private int getFileOrdinal(String path) {
-        return orderedPaths.indexOf(path);
-    }
-
-    @Override
-    public void visit(Pool in, Pool out) {
-        in.getContent().stream()
-                .filter(w -> w.getType().equals(ModuleDataType.CLASS_OR_RESOURCE))
-                .map((r) -> new SortWrapper(r, isFile
-                        ? getFileOrdinal(r.getPath())
-                        : getPatternOrdinal(r.getPath())))
-                .sorted((sw1, sw2) -> {
-                    int ordinal1 = sw1.getOrdinal();
-                    int ordinal2 = sw2.getOrdinal();
-
-                    if (ordinal1 >= 0) {
-                        if (ordinal2 >= 0) {
-                            return ordinal1 - ordinal2;
-                        } else {
-                            return -1;
-                        }
-                    } else if (ordinal2 >= 0) {
-                        return 1;
-                    }
-
-                    return sw1.getPath().compareTo(sw2.getPath());
-                }).forEach((sw) -> {
-            try {
-                out.add(sw.getResource());
-            } catch (Exception ex) {
-                throw new RuntimeException(ex);
-            }
-        });
-        in.getContent().stream()
-                .filter(m -> !m.getType().equals(ModuleDataType.CLASS_OR_RESOURCE))
-                .forEach((m) -> {
-                    try {
-                        out.add(m);
-                    } catch (Exception ex) {
-                        throw new RuntimeException(ex);
-                    }
-                });
-    }
-
-    @Override
-    public Set<PluginType> getType() {
-        Set<PluginType> set = new HashSet<>();
-        set.add(CATEGORY.SORTER);
-        return Collections.unmodifiableSet(set);
-    }
-
-    @Override
-    public String getDescription() {
-        return PluginsResourceBundle.getDescription(NAME);
-    }
-
-    @Override
-    public boolean hasArguments() {
-        return true;
-    }
-
-    @Override
-    public String getArgumentsDescription() {
-       return PluginsResourceBundle.getArgument(NAME);
-    }
-
-    @Override
-    public void configure(Map<String, String> config) {
-        String val = config.get(NAME);
-        try {
-            String[] patterns = Utils.listParser.apply(val);
-            boolean isf = false;
-            List<String> paths = null;
-            if (patterns != null) {
-                if (patterns.length == 1) {
-                    String filePath = patterns[0];
-                    File f = new File(filePath);
-                    if (f.exists()) {
-                        isf = true;
-                        try (FileInputStream fis = new FileInputStream(f);
-                                InputStreamReader ins
-                                = new InputStreamReader(fis, StandardCharsets.UTF_8);
-                                BufferedReader reader = new BufferedReader(ins)) {
-                            paths = reader.lines().collect(Collectors.toList());
-                        }
-                    }
-                }
-                if (!isf) {
-                    for (String p : patterns) {
-                        p = p.replaceAll(" ", "");
-                        Pattern pattern = Pattern.compile(ResourceFilter.escape(p));
-                        filters.add(pattern);
-                    }
-                }
-            }
-            orderedPaths = paths;
-            isFile = isf;
-        } catch (IOException ex) {
-            throw new PluginException(ex);
-        }
-    }
-}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties	Thu May 12 11:03:07 2016 -0700
@@ -53,10 +53,10 @@
 
 onoff.argument=<on|off>
 
-sort-resources.argument=<paths in priority order | file with resource paths>
+order-resources.argument=<paths in priority order | file with resource paths>
 
-sort-resources.description=\
-Sort resources. e.g.: */modules-info.class,/java-base/java/lang/*
+order-resources.description=\
+Order resources. e.g.: */module-info.class,/java.base/java/lang/*
 
 strip-debug.description=\
 Strip debug information from the output image
@@ -68,7 +68,7 @@
 
 vm.description=\
 Select the HotSpot VM in the output image.  Default is all
- 
+
 zip.argument=[comma separated list of resource paths]
 
 zip.description=ZIP Compression
@@ -160,7 +160,7 @@
 
 err.no.plugins.path=No plugins path argument.
 
-err.dir.already.exits=directory already exists: {0} 
+err.dir.already.exits=directory already exists: {0}
 
 err.invalid.index=invalid index for option {0}
 
--- a/jdk/src/jdk.jlink/share/classes/module-info.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/src/jdk.jlink/share/classes/module-info.java	Thu May 12 11:03:07 2016 -0700
@@ -40,7 +40,7 @@
     provides jdk.tools.jlink.plugin.TransformerPlugin with jdk.tools.jlink.internal.plugins.ExcludeFilesPlugin;
     provides jdk.tools.jlink.plugin.TransformerPlugin with jdk.tools.jlink.internal.plugins.SystemModuleDescriptorPlugin;
     provides jdk.tools.jlink.plugin.TransformerPlugin with jdk.tools.jlink.internal.plugins.StripNativeCommandsPlugin;
-    provides jdk.tools.jlink.plugin.TransformerPlugin with jdk.tools.jlink.internal.plugins.SortResourcesPlugin;
+    provides jdk.tools.jlink.plugin.TransformerPlugin with jdk.tools.jlink.internal.plugins.OrderResourcesPlugin;
     provides jdk.tools.jlink.plugin.TransformerPlugin with jdk.tools.jlink.internal.plugins.DefaultCompressPlugin;
     provides jdk.tools.jlink.plugin.TransformerPlugin with jdk.tools.jlink.internal.plugins.OptimizationPlugin;
     provides jdk.tools.jlink.plugin.TransformerPlugin with jdk.tools.jlink.internal.plugins.ExcludeVMPlugin;
--- a/jdk/test/Makefile	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/Makefile	Thu May 12 11:03:07 2016 -0700
@@ -76,14 +76,20 @@
 TEST_ROOT := $(shell $(PWD))
 
 # Root of all test results
-ifdef ALT_OUTPUTDIR
-  ABS_OUTPUTDIR = $(shell $(CD) $(ALT_OUTPUTDIR) && $(PWD))
+ifdef TEST_OUTPUT_DIR
+  $(shell $(MKDIR) -p $(TEST_OUTPUT_DIR)/jtreg)
+  ABS_TEST_OUTPUT_DIR := \
+    $(shell $(CD) $(TEST_OUTPUT_DIR)/jtreg && $(PWD))
 else
-  ABS_OUTPUTDIR = $(shell $(CD) $(TEST_ROOT)/.. && $(PWD))
-endif
+  ifdef ALT_OUTPUTDIR
+    ABS_OUTPUTDIR = $(shell $(CD) $(ALT_OUTPUTDIR) && $(PWD))
+  else
+    ABS_OUTPUTDIR = $(shell $(CD) $(TEST_ROOT)/.. && $(PWD))
+  endif
 
-ABS_PLATFORM_BUILD_ROOT = $(ABS_OUTPUTDIR)
-ABS_TEST_OUTPUT_DIR := $(ABS_PLATFORM_BUILD_ROOT)/testoutput/$(UNIQUE_DIR)
+  ABS_PLATFORM_BUILD_ROOT = $(ABS_OUTPUTDIR)
+  ABS_TEST_OUTPUT_DIR := $(ABS_PLATFORM_BUILD_ROOT)/testoutput/$(UNIQUE_DIR)
+endif
 
 # Expect JPRT to set PRODUCT_HOME (the product or jdk in this case to test)
 ifndef PRODUCT_HOME
--- a/jdk/test/java/lang/Integer/BitTwiddle.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/lang/Integer/BitTwiddle.java	Thu May 12 11:03:07 2016 -0700
@@ -58,6 +58,21 @@
 
         for (int i = 0; i < N; i++) {
             int x = rnd.nextInt();
+
+            String expected = new StringBuilder()
+                .append(leftpad(toBinaryString(x), 32))
+                .reverse().toString();
+
+            String actual = leftpad(toBinaryString(reverse(x)), 32);
+
+            if (!expected.equals(actual)) {
+                throw new RuntimeException("reverse: \n" +
+                        expected + " \n" + actual);
+            }
+        }
+
+        for (int i = 0; i < N; i++) {
+            int x = rnd.nextInt();
             if (highestOneBit(x) != reverse(lowestOneBit(reverse(x))))
                 throw new RuntimeException("g: " + toHexString(x));
         }
@@ -136,4 +151,12 @@
                 throw new RuntimeException("z: " + toHexString(x));
         }
     }
+
+    private static String leftpad(String s, int width) {
+        String r = s;
+        for (int c = 0; c < width - s.length(); c++) {
+            r = "0" + r;
+        }
+        return r;
+    }
 }
--- a/jdk/test/java/lang/Long/BitTwiddle.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/lang/Long/BitTwiddle.java	Thu May 12 11:03:07 2016 -0700
@@ -58,6 +58,21 @@
 
         for (int i = 0; i < N; i++) {
             long x = rnd.nextLong();
+
+            String expected = new StringBuilder()
+                .append(leftpad(toBinaryString(x), 64))
+                .reverse().toString();
+
+            String actual = leftpad(toBinaryString(reverse(x)), 64);
+
+            if (!expected.equals(actual)) {
+                throw new RuntimeException("reverse: \n" +
+                        expected + " \n" + actual);
+            }
+        }
+
+        for (int i = 0; i < N; i++) {
+            long x = rnd.nextLong();
             if (highestOneBit(x) != reverse(lowestOneBit(reverse(x))))
                 throw new RuntimeException("g: " + toHexString(x));
         }
@@ -136,4 +151,12 @@
                 throw new RuntimeException("z: " + toHexString(x));
         }
     }
+
+    private static String leftpad(String s, int width) {
+        String r = s;
+        for (int c = 0; c < width - s.length(); c++) {
+            r = "0" + r;
+        }
+        return r;
+    }
 }
--- a/jdk/test/java/lang/StackWalker/EmbeddedStackWalkTest.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/lang/StackWalker/EmbeddedStackWalkTest.java	Thu May 12 11:03:07 2016 -0700
@@ -140,8 +140,8 @@
                 s.limit(BIG_LOOP)
                  .filter(f -> c.getName().equals(f.getClassName()) && mn.equals(f.getMethodName()))
                  .forEach(f -> {
-                    assertEquals(f.getFileName().get(), fileName);
-                    int line = f.getLineNumber().getAsInt();
+                    assertEquals(f.getFileName(), fileName);
+                    int line = f.getLineNumber();
                     assertTrue(line >= BEGIN_LINE && line <= END_LINE);
 
                     StackTraceElement st = f.toStackTraceElement();
--- a/jdk/test/java/lang/StackWalker/StackRecorderUtil.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/lang/StackWalker/StackRecorderUtil.java	Thu May 12 11:03:07 2016 -0700
@@ -100,8 +100,8 @@
             }
             if (!Objects.equals(ste.getClassName(), sf.getClassName())
                 || !Objects.equals(ste.getMethodName(), sf.getMethodName())
-                || !Objects.equals(ste.getFileName(), sf.getFileName().orElse(null))
-                || !Objects.equals(ste.getLineNumber(), sf.getLineNumber().orElse(-1))
+                || !Objects.equals(ste.getFileName(), sf.getFileName())
+                || !Objects.equals(ste.getLineNumber(), sf.getLineNumber())
                 || !Objects.equals(ste.isNativeMethod(), sf.isNativeMethod())) {
                 throw new RuntimeException("StackFrame and StackTraceElement differ: " +
                         "sf=" + sf + ", ste=" + ste);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StackWalker/TestBCI.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,190 @@
+/*
+ * 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 8140450
+ * @summary Basic test for the StackWalker::getByteCodeIndex method
+ * @modules jdk.jdeps/com.sun.tools.classfile
+ * @run main TestBCI
+ */
+
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.Code_attribute;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.Descriptor;
+import com.sun.tools.classfile.LineNumberTable_attribute;
+import com.sun.tools.classfile.Method;
+
+import java.lang.StackWalker.StackFrame;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import static java.lang.StackWalker.Option.RETAIN_CLASS_REFERENCE;
+
+public class TestBCI {
+    public static void main(String... args) throws Exception {
+        TestBCI test = new TestBCI(Walker.class);
+        System.out.println("Line number table:");
+        test.methods.values().stream()
+            .sorted(Comparator.comparing(MethodInfo::name).reversed())
+            .forEach(System.out::println);
+
+        // walk the stack
+        test.walk();
+    }
+
+    private final Map<String, MethodInfo> methods;
+    private final Class<?> clazz;
+    TestBCI(Class<?> c) throws ConstantPoolException, IOException {
+        Map<String, MethodInfo> methods;
+        String filename = c.getName().replace('.', '/') + ".class";
+        try (InputStream in = c.getResourceAsStream(filename)) {
+            ClassFile cf = ClassFile.read(in);
+            methods = Arrays.stream(cf.methods)
+                .map(m -> new MethodInfo(cf, m))
+                .collect(Collectors.toMap(MethodInfo::name, Function.identity()));
+        }
+        this.clazz = c;
+        this.methods = methods;
+    }
+
+    void walk() {
+        Walker walker = new Walker();
+        walker.m1();
+    }
+
+    void verify(StackFrame frame) {
+        if (frame.getDeclaringClass() != clazz)
+            return;
+
+        int bci = frame.getByteCodeIndex();
+        int lineNumber = frame.getLineNumber();
+        System.out.format("%s.%s bci %d (%s:%d)%n",
+                          frame.getClassName(), frame.getMethodName(), bci,
+                          frame.getFileName(), lineNumber);
+
+        MethodInfo method = methods.get(frame.getMethodName());
+        SortedSet<Integer> values = method.findLineNumbers(bci).get();
+        if (!values.contains(lineNumber)) {
+            throw new RuntimeException("line number for bci: " + bci + " "
+                + lineNumber + " not matched line number table: " + values);
+        }
+    }
+
+    /*
+     * BCIs in the execution stack when StackWalker::forEach is invoked
+     * will cover BCI range in the line number table.
+     */
+    class Walker {
+        final StackWalker walker = StackWalker.getInstance(RETAIN_CLASS_REFERENCE);
+        void m1() {
+            int i = (int)Math.random()+2;
+            m2(i*2);
+        }
+
+        void m2(int i) {
+            i++;
+            m3(i);
+        }
+
+        void m3(int i) {
+            i++; m4(i++);
+        }
+
+        int m4(int i) {
+            walker.forEach(TestBCI.this::verify);
+            return i;
+        }
+    }
+
+    static class MethodInfo {
+        final Method method;
+        final String name;
+        final String paramTypes;
+        final String returnType;
+        final Map<Integer, SortedSet<Integer>> bciToLineNumbers = new HashMap<>();
+        MethodInfo(ClassFile cf, Method m) {
+            this.method = m;
+
+            String name;
+            String paramTypes;
+            String returnType;
+            LineNumberTable_attribute.Entry[] lineNumberTable;
+            try {
+                // method name
+                name = m.getName(cf.constant_pool);
+                // signature
+                paramTypes = m.descriptor.getParameterTypes(cf.constant_pool);
+                returnType = m.descriptor.getReturnType(cf.constant_pool);
+                Code_attribute codeAttr = (Code_attribute)
+                    m.attributes.get(Attribute.Code);
+                lineNumberTable = ((LineNumberTable_attribute)
+                    codeAttr.attributes.get(Attribute.LineNumberTable)).line_number_table;
+            } catch (ConstantPoolException|Descriptor.InvalidDescriptor e) {
+                throw new RuntimeException(e);
+            }
+            this.name = name;
+            this.paramTypes = paramTypes;
+            this.returnType = returnType;
+            Arrays.stream(lineNumberTable).forEach(entry ->
+                bciToLineNumbers.computeIfAbsent(entry.start_pc, _n -> new TreeSet<>())
+                    .add(entry.line_number));
+        }
+
+        String name() {
+            return name;
+        }
+
+        Optional<SortedSet<Integer>> findLineNumbers(int value) {
+            return bciToLineNumbers.entrySet().stream()
+                    .sorted(Map.Entry.comparingByKey(Comparator.reverseOrder()))
+                    .filter(e -> e.getKey().intValue() <= value)
+                    .map(Map.Entry::getValue)
+                    .findFirst();
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(name);
+            sb.append(paramTypes).append(returnType).append(" ");
+            bciToLineNumbers.entrySet().stream()
+                .sorted(Map.Entry.comparingByKey())
+                .forEach(entry -> sb.append("bci:").append(entry.getKey()).append(" ")
+                                    .append(entry.getValue()).append(" "));
+            return sb.toString();
+        }
+    }
+
+}
--- a/jdk/test/java/lang/System/LoggerFinder/jdk/DefaultLoggerBridgeTest/DefaultLoggerBridgeTest.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/lang/System/LoggerFinder/jdk/DefaultLoggerBridgeTest/DefaultLoggerBridgeTest.java	Thu May 12 11:03:07 2016 -0700
@@ -59,7 +59,9 @@
  * @modules java.base/sun.util.logging
  *          java.base/jdk.internal.logger
  *          java.logging/sun.util.logging.internal
- * @run  main/othervm DefaultLoggerBridgeTest
+ * @run  main/othervm DefaultLoggerBridgeTest NOSECURITY
+ * @run  main/othervm DefaultLoggerBridgeTest NOPERMISSIONS
+ * @run  main/othervm DefaultLoggerBridgeTest WITHPERMISSIONS
  * @author danielfuchs
  */
 public class DefaultLoggerBridgeTest {
@@ -275,7 +277,6 @@
             };
 
         Stream.of(args).map(TestCases::valueOf).forEach((testCase) -> {
-            LoggerFinder provider;
             switch (testCase) {
                 case NOSECURITY:
                     System.out.println("\n*** Without Security Manager\n");
@@ -396,10 +397,10 @@
         final boolean old = allowAll.get().get();
         allowAll.get().set(true);
         try {
+            appSink = LoggingProviderImpl.getLogManagerAccess().demandLoggerFor(
+                    LogManager.getLogManager(), "foo", DefaultLoggerBridgeTest.class.getModule());
             sysSink = LoggingProviderImpl.getLogManagerAccess().demandLoggerFor(
                     LogManager.getLogManager(), "foo", Thread.class.getModule());
-            appSink = LoggingProviderImpl.getLogManagerAccess().demandLoggerFor(
-                    LogManager.getLogManager(), "foo", DefaultLoggerBridgeTest.class.getModule());
             if (appSink == sysSink) {
                 throw new RuntimeException("identical backend loggers");
             }
--- a/jdk/test/java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java	Thu May 12 11:03:07 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
@@ -28,7 +28,7 @@
  * @summary Test verifies that lambda forms are cached when run with multiple threads
  * @author kshefov
  * @library /lib/testlibrary/jsr292 /lib/testlibrary
- * @modules java.management
+ * @modules jdk.management
  * @build TestMethods
  * @build LambdaFormTestCase
  * @build LFCachingTestCase
--- a/jdk/test/java/lang/management/BufferPoolMXBean/Basic.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/lang/management/BufferPoolMXBean/Basic.java	Thu May 12 11:03:07 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2015, 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
@@ -24,7 +24,7 @@
 /* @test
  * @bug 6606598 7024172
  * @summary Unit test for java.lang.management.BufferPoolMXBean
- * @modules java.management
+ * @modules jdk.management
  * @run main/othervm Basic
  * @key randomness
  */
--- a/jdk/test/java/lang/management/GarbageCollectorMXBean/GcInfoCompositeType.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/lang/management/GarbageCollectorMXBean/GcInfoCompositeType.java	Thu May 12 11:03:07 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2015 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
@@ -26,8 +26,7 @@
  * @bug     6396794
  * @summary Check that LastGcInfo contents are reasonable
  * @author  Eamonn McManus
- * @modules java.management
- *          jdk.management
+ * @modules jdk.management
  * @run     main/othervm -XX:-ExplicitGCInvokesConcurrent GcInfoCompositeType
  */
 // Passing "-XX:-ExplicitGCInvokesConcurrent" to force System.gc()
--- a/jdk/test/java/lang/management/MXBean/MXBeanBehavior.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/lang/management/MXBean/MXBeanBehavior.java	Thu May 12 11:03:07 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
@@ -27,8 +27,7 @@
  * @summary Check that java.lang.management MXBeans have the same behavior
  *          as user MXBeans
  * @author  Eamonn McManus
- * @modules java.management
- *          jdk.management
+ * @modules jdk.management
  * @run     main/othervm MXBeanBehavior
  */
 
--- a/jdk/test/java/lang/management/ManagementFactory/GetPlatformMXBeans.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/lang/management/ManagementFactory/GetPlatformMXBeans.java	Thu May 12 11:03:07 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
@@ -28,7 +28,7 @@
  *          methods and PlatformManagedObject.getObjectName()
  * @author  Mandy Chung
  *
- * @modules java.management
+ * @modules jdk.management
  * @run main GetPlatformMXBeans
  */
 
--- a/jdk/test/java/lang/management/ManagementFactory/GetPlatformManagementInterfaces.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/lang/management/ManagementFactory/GetPlatformManagementInterfaces.java	Thu May 12 11:03:07 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
@@ -28,7 +28,7 @@
  *          ManagementFactory.getPlatformManagementInterfaces() method
  * @author  Frederic Parain
  *
- * @modules java.management
+ * @modules jdk.management
  * @run main GetPlatformManagementInterfaces
  */
 
--- a/jdk/test/java/lang/management/ManagementFactory/MBeanServerMXBeanUnsupportedTest.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/lang/management/ManagementFactory/MBeanServerMXBeanUnsupportedTest.java	Thu May 12 11:03:07 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2015, 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
@@ -27,8 +27,7 @@
  * @summary Test that all the platform MXBeans are wrapped in StandardMBean so
  *          an MBeanServer which does not have support for MXBeans can be used.
  * @author Luis-Miguel Alventosa
- * @modules java.management
- *          jdk.management
+ * @modules jdk.management
  * @run clean MBeanServerMXBeanUnsupportedTest
  * @run build MBeanServerMXBeanUnsupportedTest
  * @run main/othervm MBeanServerMXBeanUnsupportedTest
--- a/jdk/test/java/lang/management/ManagementFactory/MXBeanException.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/lang/management/ManagementFactory/MXBeanException.java	Thu May 12 11:03:07 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,7 +29,7 @@
  *
  * @author  Mandy Chung
  *
- * @modules java.management
+ * @modules jdk.management
  * @build MXBeanException
  * @run main MXBeanException
  */
--- a/jdk/test/java/lang/management/ManagementFactory/MXBeanProxyTest.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/lang/management/ManagementFactory/MXBeanProxyTest.java	Thu May 12 11:03:07 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
@@ -25,7 +25,7 @@
  * @test
  * @bug     5024531
  * @summary Basic Test for ManagementFactory.newPlatformMXBean().
- * @modules java.management
+ * @modules jdk.management
  * @run main/othervm MXBeanProxyTest
  * @author  Mandy Chung
  */
--- a/jdk/test/java/lang/management/ManagementFactory/PlatformMBeanServerTest.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/lang/management/ManagementFactory/PlatformMBeanServerTest.java	Thu May 12 11:03:07 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
@@ -26,7 +26,7 @@
  * @bug     4947536
  * @summary Basic unit test of ManagementFactory.getPlatformMBeanServer()
  * @author  Mandy Chung
- * @modules java.management
+ * @modules jdk.management
  */
 
 import java.lang.management.*;
--- a/jdk/test/java/lang/management/ManagementFactory/ProxyExceptions.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/lang/management/ManagementFactory/ProxyExceptions.java	Thu May 12 11:03:07 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
@@ -27,8 +27,7 @@
  * @summary Test type mapping of the platform MXBean proxy
  *          returned from Management.newPlatformMXBeanProxy().
  * @author  Mandy Chung
- * @modules java.management
- *          jdk.management
+ * @modules jdk.management
  */
 import java.lang.management.*;
 import javax.management.*;
--- a/jdk/test/java/lang/management/ManagementFactory/ProxyTypeMapping.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/lang/management/ManagementFactory/ProxyTypeMapping.java	Thu May 12 11:03:07 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
@@ -28,8 +28,7 @@
  *          returned from Management.newPlatformMXBeanProxy().
  * @author  Mandy Chung
  *
- * @modules java.management
- *          jdk.management
+ * @modules jdk.management
  * @compile ProxyTypeMapping.java
  * @run main/othervm -verbose:gc ProxyTypeMapping
  */
--- a/jdk/test/java/lang/management/ManagementFactory/ThreadMXBeanProxy.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/lang/management/ManagementFactory/ThreadMXBeanProxy.java	Thu May 12 11:03:07 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
@@ -29,7 +29,7 @@
  *
  * @author  Mandy Chung
  *
- * @modules java.management
+ * @modules jdk.management
  * @run main ThreadMXBeanProxy
  */
 
--- a/jdk/test/java/lang/management/ManagementFactory/ValidateOpenTypes.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/lang/management/ManagementFactory/ValidateOpenTypes.java	Thu May 12 11:03:07 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
@@ -28,8 +28,7 @@
  *          MBeanServer.
  * @author  Mandy Chung
  *
- * @modules java.management
- *          jdk.management
+ * @modules jdk.management
  * @compile ValidateOpenTypes.java
  * @run main/othervm -verbose:gc ValidateOpenTypes
  */
--- a/jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java	Thu May 12 11:03:07 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
@@ -31,7 +31,7 @@
  * @author  Mandy Chung
  *
  * @library /lib/testlibrary/
- * @modules java.management
+ * @modules jdk.management
  * @build jdk.testlibrary.* CollectionUsageThreshold MemoryUtil RunUtil
  * @requires vm.opt.ExplicitGCInvokesConcurrent == "false" | vm.opt.ExplicitGCInvokesConcurrent == "null"
  * @run main/timeout=300 CollectionUsageThreshold
--- a/jdk/test/java/lang/management/MemoryMXBean/GetMBeanInfo.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/lang/management/MemoryMXBean/GetMBeanInfo.java	Thu May 12 11:03:07 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
@@ -27,7 +27,7 @@
  * @summary Make sure MemoryMXBean has two notification types.
  * @author  Mandy Chung
  *
- * @modules java.management
+ * @modules jdk.management
  * @run main GetMBeanInfo
  */
 
--- a/jdk/test/java/lang/management/MemoryMXBean/MemoryManagement.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/lang/management/MemoryMXBean/MemoryManagement.java	Thu May 12 11:03:07 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
@@ -30,7 +30,7 @@
  *
  * @author  Mandy Chung
  *
- * @modules java.management
+ * @modules jdk.management
  * @build MemoryManagement MemoryUtil
  * @run main/othervm/timeout=600 -Xmn8m -XX:+IgnoreUnrecognizedVMOptions -XX:G1HeapRegionSize=1 -XX:-UseLargePages MemoryManagement
  */
--- a/jdk/test/java/lang/management/MemoryMXBean/MemoryTest.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/lang/management/MemoryMXBean/MemoryTest.java	Thu May 12 11:03:07 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
@@ -28,7 +28,7 @@
  *          MemoryMXBean.getMemoryManager().
  * @author  Mandy Chung
  *
- * @modules java.management
+ * @modules jdk.management
  * @run main MemoryTest 2
  */
 
--- a/jdk/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java	Thu May 12 11:03:07 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
@@ -33,7 +33,7 @@
  * @author  Mandy Chung
  *
  * @library /lib/testlibrary/
- * @modules java.management
+ * @modules jdk.management
  * @build jdk.testlibrary.* ResetPeakMemoryUsage MemoryUtil RunUtil
  * @run main ResetPeakMemoryUsage
  */
--- a/jdk/test/java/lang/management/PlatformLoggingMXBean/LoggingMXBeanTest.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/lang/management/PlatformLoggingMXBean/LoggingMXBeanTest.java	Thu May 12 11:03:07 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
@@ -27,8 +27,7 @@
  * @summary Test if proxy for PlatformLoggingMXBean is equivalent
  *          to proxy for LoggingMXBean
  *
- * @modules java.management
- *          jdk.management
+ * @modules jdk.management
  * @build LoggingMXBeanTest
  * @run main LoggingMXBeanTest
  */
--- a/jdk/test/java/lang/management/PlatformLoggingMXBean/PlatformLoggingMXBeanTest.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/lang/management/PlatformLoggingMXBean/PlatformLoggingMXBeanTest.java	Thu May 12 11:03:07 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
@@ -29,8 +29,7 @@
  *          This test performs similar testing as
  *          java/util/logging/LoggingMXBeanTest.
  *
- * @modules java.management
- *          jdk.management
+ * @modules jdk.management
  * @build PlatformLoggingMXBeanTest
  * @run main PlatformLoggingMXBeanTest
  */
--- a/jdk/test/java/lang/management/ThreadMXBean/ThreadInfoArray.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/lang/management/ThreadMXBean/ThreadInfoArray.java	Thu May 12 11:03:07 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
@@ -30,7 +30,7 @@
  * @author  Mandy Chung
  * @author  Jaroslav Bachorik
  *
- * @modules java.management
+ * @modules jdk.management
  * @build ThreadInfoArray
  * @run main ThreadInfoArray
  */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/BasicWebSocketAPITest.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,332 @@
+/*
+ * 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.testng.annotations.Test;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.WebSocket;
+import java.net.http.WebSocket.CloseCode;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+import java.util.stream.Stream;
+
+/*
+ * @test
+ * @bug 8087113
+ * @build TestKit
+ * @run testng/othervm BasicWebSocketAPITest
+ */
+public class BasicWebSocketAPITest {
+
+    @Test
+    public void webSocket() throws Exception {
+        checkAndClose(
+                (ws) ->
+                        TestKit.assertThrows(IllegalArgumentException.class,
+                                "(?i).*\\bnegative\\b.*",
+                                () -> ws.request(-1))
+        );
+        checkAndClose((ws) ->
+                TestKit.assertNotThrows(() -> ws.request(0))
+        );
+        checkAndClose((ws) ->
+                TestKit.assertNotThrows(() -> ws.request(1))
+        );
+        checkAndClose((ws) ->
+                TestKit.assertNotThrows(() -> ws.request(Long.MAX_VALUE))
+        );
+        checkAndClose((ws) ->
+                TestKit.assertNotThrows(ws::isClosed)
+        );
+        checkAndClose((ws) ->
+                TestKit.assertNotThrows(ws::getSubprotocol)
+        );
+        checkAndClose(
+                (ws) -> {
+                    try {
+                        ws.abort();
+                    } catch (IOException ignored) { }
+                    // No matter what happens during the first abort invocation,
+                    // other invocations must return normally
+                    TestKit.assertNotThrows(ws::abort);
+                    TestKit.assertNotThrows(ws::abort);
+                }
+        );
+        checkAndClose(
+                (ws) ->
+                        TestKit.assertThrows(NullPointerException.class,
+                                "message",
+                                () -> ws.sendBinary((byte[]) null, true))
+        );
+        checkAndClose(
+                (ws) ->
+                        TestKit.assertThrows(NullPointerException.class,
+                                "message",
+                                () -> ws.sendBinary((ByteBuffer) null, true))
+        );
+        checkAndClose(
+                (ws) ->
+                        TestKit.assertThrows(NullPointerException.class,
+                                "message",
+                                () -> ws.sendPing(null))
+        );
+        checkAndClose(
+                (ws) ->
+                        TestKit.assertThrows(NullPointerException.class,
+                                "message",
+                                () -> ws.sendPong(null))
+        );
+        checkAndClose(
+                (ws) ->
+                        TestKit.assertThrows(NullPointerException.class,
+                                "message",
+                                () -> ws.sendText((CharSequence) null, true))
+        );
+        checkAndClose(
+                (ws) ->
+                        TestKit.assertThrows(NullPointerException.class,
+                                "message",
+                                () -> ws.sendText((CharSequence) null))
+        );
+        checkAndClose(
+                (ws) ->
+                        TestKit.assertThrows(NullPointerException.class,
+                                "message",
+                                () -> ws.sendText((Stream<? extends CharSequence>) null))
+        );
+        checkAndClose(
+                (ws) ->
+                        TestKit.assertThrows(NullPointerException.class,
+                                "code",
+                                () -> ws.sendClose(null, ""))
+        );
+        checkAndClose(
+                (ws) ->
+                        TestKit.assertNotThrows(
+                                () -> ws.sendClose(CloseCode.NORMAL_CLOSURE, ""))
+        );
+        checkAndClose(
+                (ws) ->
+                        TestKit.assertThrows(NullPointerException.class,
+                                "reason",
+                                () -> ws.sendClose(CloseCode.NORMAL_CLOSURE, null))
+        );
+        checkAndClose(
+                (ws) ->
+                        TestKit.assertThrows(NullPointerException.class,
+                                "code|reason",
+                                () -> ws.sendClose(null, null))
+        );
+    }
+
+    @Test
+    public void builder() {
+        URI ws = URI.create("ws://localhost:9001");
+        // FIXME: check all 24 cases:
+        // {null, ws, wss, incorrect} x {null, HttpClient.getDefault(), custom} x {null, listener}
+        //
+        // if (any null) or (any incorrect)
+        //     NPE or IAE is thrown
+        // else
+        //     builder is created
+        TestKit.assertThrows(NullPointerException.class,
+                "uri",
+                () -> WebSocket.newBuilder(null, defaultListener())
+        );
+        TestKit.assertThrows(NullPointerException.class,
+                "listener",
+                () -> WebSocket.newBuilder(ws, null)
+        );
+        URI uri = URI.create("ftp://localhost:9001");
+        TestKit.assertThrows(IllegalArgumentException.class,
+                "(?i).*\\buri\\b\\s+\\bscheme\\b.*",
+                () -> WebSocket.newBuilder(uri, defaultListener())
+        );
+        TestKit.assertNotThrows(
+                () -> WebSocket.newBuilder(ws, defaultListener())
+        );
+        URI uri1 = URI.create("wss://localhost:9001");
+        TestKit.assertNotThrows(
+                () -> WebSocket.newBuilder(uri1, defaultListener())
+        );
+        URI uri2 = URI.create("wss://localhost:9001#a");
+        TestKit.assertThrows(IllegalArgumentException.class,
+                "(?i).*\\bfragment\\b.*",
+                () -> WebSocket.newBuilder(uri2, HttpClient.getDefault(), defaultListener())
+        );
+        TestKit.assertThrows(NullPointerException.class,
+                "uri",
+                () -> WebSocket.newBuilder(null, HttpClient.getDefault(), defaultListener())
+        );
+        TestKit.assertThrows(NullPointerException.class,
+                "client",
+                () -> WebSocket.newBuilder(ws, null, defaultListener())
+        );
+        TestKit.assertThrows(NullPointerException.class,
+                "listener",
+                () -> WebSocket.newBuilder(ws, HttpClient.getDefault(), null)
+        );
+        // FIXME: check timeout works
+        // (i.e. it directly influences the time WebSocket waits for connection + opening handshake)
+        TestKit.assertNotThrows(
+                () -> WebSocket.newBuilder(ws, defaultListener()).connectTimeout(1, TimeUnit.SECONDS)
+        );
+        WebSocket.Builder builder = WebSocket.newBuilder(ws, defaultListener());
+        TestKit.assertThrows(IllegalArgumentException.class,
+                "(?i).*\\bnegative\\b.*",
+                () -> builder.connectTimeout(-1, TimeUnit.SECONDS)
+        );
+        WebSocket.Builder builder1 = WebSocket.newBuilder(ws, defaultListener());
+        TestKit.assertThrows(NullPointerException.class,
+                "unit",
+                () -> builder1.connectTimeout(1, null)
+        );
+        // FIXME: check these headers are actually received by the server
+        TestKit.assertNotThrows(
+                () -> WebSocket.newBuilder(ws, defaultListener()).header("a", "b")
+        );
+        TestKit.assertNotThrows(
+                () -> WebSocket.newBuilder(ws, defaultListener()).header("a", "b").header("a", "b")
+        );
+        // FIXME: check all 18 cases:
+        // {null, websocket(7), custom} x {null, custom}
+        WebSocket.Builder builder2 = WebSocket.newBuilder(ws, defaultListener());
+        TestKit.assertThrows(NullPointerException.class,
+                "name",
+                () -> builder2.header(null, "b")
+        );
+        WebSocket.Builder builder3 = WebSocket.newBuilder(ws, defaultListener());
+        TestKit.assertThrows(NullPointerException.class,
+                "value",
+                () -> builder3.header("a", null)
+        );
+        WebSocket.Builder builder4 = WebSocket.newBuilder(ws, defaultListener());
+        TestKit.assertThrows(IllegalArgumentException.class,
+                () -> builder4.header("Sec-WebSocket-Accept", "")
+        );
+        WebSocket.Builder builder5 = WebSocket.newBuilder(ws, defaultListener());
+        TestKit.assertThrows(IllegalArgumentException.class,
+                () -> builder5.header("Sec-WebSocket-Extensions", "")
+        );
+        WebSocket.Builder builder6 = WebSocket.newBuilder(ws, defaultListener());
+        TestKit.assertThrows(IllegalArgumentException.class,
+                () -> builder6.header("Sec-WebSocket-Key", "")
+        );
+        WebSocket.Builder builder7 = WebSocket.newBuilder(ws, defaultListener());
+        TestKit.assertThrows(IllegalArgumentException.class,
+                () -> builder7.header("Sec-WebSocket-Protocol", "")
+        );
+        WebSocket.Builder builder8 = WebSocket.newBuilder(ws, defaultListener());
+        TestKit.assertThrows(IllegalArgumentException.class,
+                () -> builder8.header("Sec-WebSocket-Version", "")
+        );
+        WebSocket.Builder builder9 = WebSocket.newBuilder(ws, defaultListener());
+        TestKit.assertThrows(IllegalArgumentException.class,
+                () -> builder9.header("Connection", "")
+        );
+        WebSocket.Builder builder10 = WebSocket.newBuilder(ws, defaultListener());
+        TestKit.assertThrows(IllegalArgumentException.class,
+                () -> builder10.header("Upgrade", "")
+        );
+        // FIXME: check 3 cases (1 arg):
+        // {null, incorrect, custom}
+        // FIXME: check 12 cases (2 args):
+        // {null, incorrect, custom} x {(String) null, (String[]) null, incorrect, custom}
+        // FIXME: check 27 cases (3 args) (the interesting part in null inside var-arg):
+        // {null, incorrect, custom}^3
+        // FIXME: check the server receives them in the order listed
+        TestKit.assertThrows(NullPointerException.class,
+                "mostPreferred",
+                () -> WebSocket.newBuilder(ws, defaultListener()).subprotocols(null)
+        );
+        TestKit.assertThrows(NullPointerException.class,
+                "lesserPreferred",
+                () -> WebSocket.newBuilder(ws, defaultListener()).subprotocols("a", null)
+        );
+        TestKit.assertThrows(NullPointerException.class,
+                "lesserPreferred\\[0\\]",
+                () -> WebSocket.newBuilder(ws, defaultListener()).subprotocols("a", null, "b")
+        );
+        TestKit.assertThrows(NullPointerException.class,
+                "lesserPreferred\\[1\\]",
+                () -> WebSocket.newBuilder(ws, defaultListener()).subprotocols("a", "b", null)
+        );
+        TestKit.assertNotThrows(
+                () -> WebSocket.newBuilder(ws, defaultListener()).subprotocols("a")
+        );
+        TestKit.assertNotThrows(
+                () -> WebSocket.newBuilder(ws, defaultListener()).subprotocols("a", "b", "c")
+        );
+        WebSocket.Builder builder11 = WebSocket.newBuilder(ws, defaultListener());
+        TestKit.assertThrows(IllegalArgumentException.class,
+                () -> builder11.subprotocols("")
+        );
+        WebSocket.Builder builder12 = WebSocket.newBuilder(ws, defaultListener());
+        TestKit.assertThrows(IllegalArgumentException.class,
+                () -> builder12.subprotocols("a", "a")
+        );
+        WebSocket.Builder builder13 = WebSocket.newBuilder(ws, defaultListener());
+        TestKit.assertThrows(IllegalArgumentException.class,
+                () -> builder13.subprotocols("a" + ((char) 0x7f))
+        );
+    }
+
+    private static WebSocket.Listener defaultListener() {
+        return new WebSocket.Listener() { };
+    }
+
+    //
+    // Automatically closes everything after the check has been performed
+    //
+    private static void checkAndClose(Consumer<? super WebSocket> c) {
+        HandshakePhase HandshakePhase
+                = new HandshakePhase(new InetSocketAddress("127.0.0.1", 0));
+        URI serverURI = HandshakePhase.getURI();
+        CompletableFuture<SocketChannel> cfc = HandshakePhase.afterHandshake();
+        WebSocket.Builder b = WebSocket.newBuilder(serverURI, defaultListener());
+        CompletableFuture<WebSocket> cfw = b.buildAsync();
+
+        try {
+            WebSocket ws;
+            try {
+                ws = cfw.get();
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+            c.accept(ws);
+        } finally {
+            try {
+                SocketChannel now = cfc.getNow(null);
+                if (now != null) {
+                    now.close();
+                }
+            } catch (Throwable ignored) { }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/httpclient/HandshakePhase.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,265 @@
+/*
+ * 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.io.UncheckedIOException;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Function;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import static java.lang.String.format;
+import static java.util.Objects.requireNonNull;
+
+//
+// Performs a simple opening handshake and yields the channel.
+//
+// Client Request:
+//
+//    GET /chat HTTP/1.1
+//    Host: server.example.com
+//    Upgrade: websocket
+//    Connection: Upgrade
+//    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
+//    Origin: http://example.com
+//    Sec-WebSocket-Protocol: chat, superchat
+//    Sec-WebSocket-Version: 13
+//
+//
+// Server Response:
+//
+//    HTTP/1.1 101 Switching Protocols
+//    Upgrade: websocket
+//    Connection: Upgrade
+//    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
+//    Sec-WebSocket-Protocol: chat
+//
+final class HandshakePhase {
+
+    private final ServerSocketChannel ssc;
+
+    HandshakePhase(InetSocketAddress address) {
+        requireNonNull(address);
+        try {
+            ssc = ServerSocketChannel.open();
+            ssc.bind(address);
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    //
+    // Returned CF completes normally after the handshake has been performed
+    //
+    CompletableFuture<SocketChannel> afterHandshake(
+            Function<List<String>, List<String>> mapping) {
+        return CompletableFuture.supplyAsync(
+                () -> {
+                    SocketChannel socketChannel = accept();
+                    try {
+                        StringBuilder request = new StringBuilder();
+                        if (!readRequest(socketChannel, request)) {
+                            throw new IllegalStateException();
+                        }
+                        List<String> strings = Arrays.asList(
+                                request.toString().split("\r\n")
+                        );
+                        List<String> response = mapping.apply(strings);
+                        writeResponse(socketChannel, response);
+                        return socketChannel;
+                    } catch (Throwable t) {
+                        try {
+                            socketChannel.close();
+                        } catch (IOException ignored) { }
+                        throw t;
+                    }
+                });
+    }
+
+    CompletableFuture<SocketChannel> afterHandshake() {
+        return afterHandshake((request) -> {
+            List<String> response = new LinkedList<>();
+            Iterator<String> iterator = request.iterator();
+            if (!iterator.hasNext()) {
+                throw new IllegalStateException("The request is empty");
+            }
+            if (!"GET / HTTP/1.1".equals(iterator.next())) {
+                throw new IllegalStateException
+                        ("Unexpected status line: " + request.get(0));
+            }
+            response.add("HTTP/1.1 101 Switching Protocols");
+            Map<String, String> requestHeaders = new HashMap<>();
+            while (iterator.hasNext()) {
+                String header = iterator.next();
+                String[] split = header.split(": ");
+                if (split.length != 2) {
+                    throw new IllegalStateException
+                            ("Unexpected header: " + header
+                                    + ", split=" + Arrays.toString(split));
+                }
+                if (requestHeaders.put(split[0], split[1]) != null) {
+                    throw new IllegalStateException
+                            ("Duplicating headers: " + Arrays.toString(split));
+                }
+            }
+            if (requestHeaders.containsKey("Sec-WebSocket-Protocol")) {
+                throw new IllegalStateException("Subprotocols are not expected");
+            }
+            if (requestHeaders.containsKey("Sec-WebSocket-Extensions")) {
+                throw new IllegalStateException("Extensions are not expected");
+            }
+            expectHeader(requestHeaders, "Connection", "Upgrade");
+            response.add("Connection: Upgrade");
+            expectHeader(requestHeaders, "Upgrade", "websocket");
+            response.add("Upgrade: websocket");
+            expectHeader(requestHeaders, "Sec-WebSocket-Version", "13");
+            String key = requestHeaders.get("Sec-WebSocket-Key");
+            if (key == null) {
+                throw new IllegalStateException("Sec-WebSocket-Key is missing");
+            }
+            MessageDigest sha1 = null;
+            try {
+                sha1 = MessageDigest.getInstance("SHA-1");
+            } catch (NoSuchAlgorithmException e) {
+                throw new InternalError(e);
+            }
+            String x = key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+            sha1.update(x.getBytes(StandardCharsets.ISO_8859_1));
+            String v = Base64.getEncoder().encodeToString(sha1.digest());
+            response.add("Sec-WebSocket-Accept: " + v);
+            return response;
+        });
+    }
+
+    private String expectHeader(Map<String, String> headers,
+                                String name,
+                                String value) {
+        String v = headers.get(name);
+        if (!value.equals(v)) {
+            throw new IllegalStateException(
+                    format("Expected '%s: %s', actual: '%s: %s'",
+                            name, value, name, v)
+            );
+        }
+        return v;
+    }
+
+    URI getURI() {
+        InetSocketAddress a;
+        try {
+            a = (InetSocketAddress) ssc.getLocalAddress();
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+        return URI.create("ws://" + a.getHostName() + ":" + a.getPort());
+    }
+
+    private int read(SocketChannel socketChannel, ByteBuffer buffer) {
+        try {
+            int num = socketChannel.read(buffer);
+            if (num == -1) {
+                throw new IllegalStateException("Unexpected EOF");
+            }
+            assert socketChannel.isBlocking() && num > 0;
+            return num;
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    private SocketChannel accept() {
+        SocketChannel socketChannel = null;
+        try {
+            socketChannel = ssc.accept();
+            socketChannel.configureBlocking(true);
+        } catch (IOException e) {
+            if (socketChannel != null) {
+                try {
+                    socketChannel.close();
+                } catch (IOException ignored) { }
+            }
+            throw new UncheckedIOException(e);
+        }
+        return socketChannel;
+    }
+
+    private boolean readRequest(SocketChannel socketChannel,
+                                StringBuilder request) {
+        ByteBuffer buffer = ByteBuffer.allocateDirect(512);
+        read(socketChannel, buffer);
+        CharBuffer decoded;
+        buffer.flip();
+        try {
+            decoded =
+                    StandardCharsets.ISO_8859_1.newDecoder().decode(buffer);
+        } catch (CharacterCodingException e) {
+            throw new UncheckedIOException(e);
+        }
+        request.append(decoded);
+        return Pattern.compile("\r\n\r\n").matcher(request).find();
+    }
+
+    private void writeResponse(SocketChannel socketChannel,
+                               List<String> response) {
+        String s = response.stream().collect(Collectors.joining("\r\n"))
+                + "\r\n\r\n";
+        ByteBuffer encoded;
+        try {
+            encoded =
+                    StandardCharsets.ISO_8859_1.newEncoder().encode(CharBuffer.wrap(s));
+        } catch (CharacterCodingException e) {
+            throw new UncheckedIOException(e);
+        }
+        write(socketChannel, encoded);
+    }
+
+    private void write(SocketChannel socketChannel, ByteBuffer buffer) {
+        try {
+            while (buffer.hasRemaining()) {
+                socketChannel.write(buffer);
+            }
+        } catch (IOException e) {
+            try {
+                socketChannel.close();
+            } catch (IOException ignored) { }
+            throw new UncheckedIOException(e);
+        }
+    }
+}
--- a/jdk/test/java/net/httpclient/security/Security.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/net/httpclient/security/Security.java	Thu May 12 11:03:07 2016 -0700
@@ -68,6 +68,8 @@
 import java.util.logging.ConsoleHandler;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import java.lang.reflect.InvocationTargetException;
+import java.net.BindException;
 
 /**
  * Security checks test
@@ -142,8 +144,12 @@
         }
     }
 
-    static Object getProxy(int port, boolean b) throws Exception {
-        return proxyConstructor.newInstance(port, b);
+    static Object getProxy(int port, boolean b) throws Throwable {
+        try {
+            return proxyConstructor.newInstance(port, b);
+        } catch (InvocationTargetException e) {
+            throw e.getTargetException();
+        }
     }
 
     static Class<?> proxyClass;
@@ -319,10 +325,10 @@
         Object proxy = null;
         try {
             proxy = getProxy(proxyPort, true);
-        } catch (IOException e) {
-            System.out.println("Cannot bind. Not running test");
-            throw new SecurityException("test not run");
-        } catch (Exception ee) {
+        } catch (BindException e) {
+            System.out.println("Bind failed");
+            throw e;
+        } catch (Throwable ee) {
             throw new RuntimeException(ee);
         }
         System.out.println("Proxy port = " + proxyPort);
--- a/jdk/test/java/nio/channels/SocketChannel/AdaptSocket.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/nio/channels/SocketChannel/AdaptSocket.java	Thu May 12 11:03:07 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
@@ -22,6 +22,7 @@
  */
 
 /* @test
+ * @bug 8156002
  * @summary Unit test for socket-channel adaptors
  * @library ..
  */
@@ -29,6 +30,7 @@
 import java.io.*;
 import java.net.*;
 import java.nio.channels.*;
+import java.util.Arrays;
 
 
 public class AdaptSocket {
@@ -100,10 +102,15 @@
         try {
             byte[] b = new byte[100];
             int n = is.read(b);
-            if (n != 5)
+            if (shouldTimeout) {
+                throw new Exception("Should time out, but not, data: " + Arrays.toString(b));
+            }
+            if (n != 5) {
                 throw new Exception("Incorrect number of bytes read: " + n);
-            if (!dataString.equals(new String(b, 0, n, "US-ASCII")))
+            }
+            if (!dataString.equals(new String(b, 0, n, "US-ASCII"))) {
                 throw new Exception("Incorrect data read: " + n);
+            }
         } catch (SocketTimeoutException x) {
             if (shouldTimeout) {
                 out.println("Read timed out, as expected");
@@ -135,6 +142,7 @@
 
         testRead(so, shouldTimeout);
         for (int i = 0; i < 4; i++) {
+            out.println("loop: " + i);
             testRead(so, shouldTimeout);
         }
 
@@ -163,9 +171,9 @@
             testRead(echoServer, 8000, false);
         }
 
-        try (TestServers.EchoServer lingerEchoServer
-                = TestServers.EchoServer.startNewServer(100)) {
-            testRead(lingerEchoServer, 10, true);
+        try (TestServers.NoResponseServer noResponseServer
+                = TestServers.NoResponseServer.startNewServer()) {
+            testRead(noResponseServer, 10, true);
         }
     }
 }
--- a/jdk/test/java/nio/channels/TestServers.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/nio/channels/TestServers.java	Thu May 12 11:03:07 2016 -0700
@@ -340,7 +340,7 @@
      * exactly matches the RFC - the only purpose of this server is to have
      * something that responds to nio tests...
      */
-    static final class EchoServer extends AbstractTcpServer {
+    static class EchoServer extends AbstractTcpServer {
 
         public EchoServer() {
             this(0L);
@@ -400,6 +400,21 @@
     }
 
     /**
+     * A small TCP Server that accept connections but does not response to any input.
+     */
+    static final class NoResponseServer extends EchoServer {
+        public NoResponseServer() {
+            super(Long.MAX_VALUE);
+        }
+
+        public static NoResponseServer startNewServer() throws IOException {
+            final NoResponseServer noResponseServer = new NoResponseServer();
+            noResponseServer.start();
+            return noResponseServer;
+        }
+    }
+
+    /**
      * A small TCP server that emulates the Day & Time service for tests
      * purposes. See http://en.wikipedia.org/wiki/Daytime_Protocol This server
      * uses an anonymous port - NOT the standard port 13. We don't guarantee
--- a/jdk/test/java/rmi/transport/httpSocket/HttpSocketTest.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 1999, 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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please 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 HttpSocket functionality test
- * @author Dana Burns
- *
- * @library ../../testlibrary
- * @modules java.rmi/sun.rmi.registry
- *          java.rmi/sun.rmi.server
- *          java.rmi/sun.rmi.transport
- *          java.rmi/sun.rmi.transport.proxy
- *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary HttpSocketTest HttpSocketTest_Stub
- * @run main/othervm/policy=security.policy HttpSocketTest
- */
-
-/*
- *  This test assures remote methods can be carried out over RMI.
- *  After setting the RMI runtime socket factory to the http proxy version,
- *  a registry is created, a remote object (an instance of this class) is
- *  registered with it, and then it is exercised.
- */
-
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.rmi.Naming;
-import java.rmi.RMISecurityManager;
-import java.rmi.registry.LocateRegistry;
-import java.rmi.registry.Registry;
-import java.rmi.server.RMISocketFactory;
-import java.rmi.server.UnicastRemoteObject;
-import sun.rmi.transport.proxy.RMIHttpToPortSocketFactory;
-
-interface MyRemoteInterface extends Remote {
-    void setRemoteObject( Remote r ) throws RemoteException;
-    Remote getRemoteObject() throws RemoteException;
-}
-
-public class HttpSocketTest extends UnicastRemoteObject
-    implements MyRemoteInterface
-{
-    private static final String NAME = "HttpSocketTest";
-
-    public HttpSocketTest() throws RemoteException{}
-
-    private Remote ro;
-
-    public static void main(String[] args)
-        throws Exception
-    {
-
-        Registry registry = null;
-
-        TestLibrary.suggestSecurityManager(null);
-
-        // Set the socket factory.
-        System.err.println("installing socket factory");
-        RMISocketFactory.setSocketFactory(new RMIHttpToPortSocketFactory());
-        int registryPort = -1;
-
-        try {
-            System.err.println("Starting registry");
-            registry = TestLibrary.createRegistryOnUnusedPort();
-            registryPort = TestLibrary.getRegistryPort(registry);
-        } catch (Exception e) {
-            TestLibrary.bomb(e);
-        }
-
-        try {
-            registry.rebind( NAME, new HttpSocketTest() );
-            MyRemoteInterface httpTest =
-                (MyRemoteInterface)Naming.lookup("//:" + registryPort + "/" + NAME);
-            httpTest.setRemoteObject( new HttpSocketTest() );
-            Remote r = httpTest.getRemoteObject();
-
-        } catch (Exception e) {
-            TestLibrary.bomb(e);
-        }
-
-
-    }
-
-    public void setRemoteObject( Remote ro ) throws RemoteException {
-        this.ro = ro;
-    }
-
-    public Remote getRemoteObject() throws RemoteException {
-        return( this.ro );
-    }
-
-}
--- a/jdk/test/java/rmi/transport/httpSocket/HttpSocketTest_Stub.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,130 +0,0 @@
-/*
- * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// Stub class generated by rmic, do not edit.
-// Contents subject to change without notice.
-
-public final class HttpSocketTest_Stub
-    extends java.rmi.server.RemoteStub
-    implements MyRemoteInterface, java.rmi.Remote
-{
-    private static final java.rmi.server.Operation[] operations = {
-        new java.rmi.server.Operation("java.rmi.Remote getRemoteObject()"),
-        new java.rmi.server.Operation("void setRemoteObject(java.rmi.Remote)")
-    };
-
-    private static final long interfaceHash = 3775375480010579665L;
-
-    private static final long serialVersionUID = 2;
-
-    private static boolean useNewInvoke;
-    private static java.lang.reflect.Method $method_getRemoteObject_0;
-    private static java.lang.reflect.Method $method_setRemoteObject_1;
-
-    static {
-        try {
-            java.rmi.server.RemoteRef.class.getMethod("invoke",
-                new java.lang.Class[] {
-                    java.rmi.Remote.class,
-                    java.lang.reflect.Method.class,
-                    java.lang.Object[].class,
-                    long.class
-                });
-            useNewInvoke = true;
-            $method_getRemoteObject_0 = MyRemoteInterface.class.getMethod("getRemoteObject", new java.lang.Class[] {});
-            $method_setRemoteObject_1 = MyRemoteInterface.class.getMethod("setRemoteObject", new java.lang.Class[] {java.rmi.Remote.class});
-        } catch (java.lang.NoSuchMethodException e) {
-            useNewInvoke = false;
-        }
-    }
-
-    // constructors
-    public HttpSocketTest_Stub() {
-        super();
-    }
-    public HttpSocketTest_Stub(java.rmi.server.RemoteRef ref) {
-        super(ref);
-    }
-
-    // methods from remote interfaces
-
-    // implementation of getRemoteObject()
-    public java.rmi.Remote getRemoteObject()
-        throws java.rmi.RemoteException
-    {
-        try {
-            if (useNewInvoke) {
-                Object $result = ref.invoke(this, $method_getRemoteObject_0, null, -2578437860804964265L);
-                return ((java.rmi.Remote) $result);
-            } else {
-                java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash);
-                ref.invoke(call);
-                java.rmi.Remote $result;
-                try {
-                    java.io.ObjectInput in = call.getInputStream();
-                    $result = (java.rmi.Remote) in.readObject();
-                } catch (java.io.IOException e) {
-                    throw new java.rmi.UnmarshalException("error unmarshalling return", e);
-                } catch (java.lang.ClassNotFoundException e) {
-                    throw new java.rmi.UnmarshalException("error unmarshalling return", e);
-                } finally {
-                    ref.done(call);
-                }
-                return $result;
-            }
-        } catch (java.lang.RuntimeException e) {
-            throw e;
-        } catch (java.rmi.RemoteException e) {
-            throw e;
-        } catch (java.lang.Exception e) {
-            throw new java.rmi.UnexpectedException("undeclared checked exception", e);
-        }
-    }
-
-    // implementation of setRemoteObject(Remote)
-    public void setRemoteObject(java.rmi.Remote $param_Remote_1)
-        throws java.rmi.RemoteException
-    {
-        try {
-            if (useNewInvoke) {
-                ref.invoke(this, $method_setRemoteObject_1, new java.lang.Object[] {$param_Remote_1}, -7518632118115022871L);
-            } else {
-                java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 1, interfaceHash);
-                try {
-                    java.io.ObjectOutput out = call.getOutputStream();
-                    out.writeObject($param_Remote_1);
-                } catch (java.io.IOException e) {
-                    throw new java.rmi.MarshalException("error marshalling arguments", e);
-                }
-                ref.invoke(call);
-                ref.done(call);
-            }
-        } catch (java.lang.RuntimeException e) {
-            throw e;
-        } catch (java.rmi.RemoteException e) {
-            throw e;
-        } catch (java.lang.Exception e) {
-            throw new java.rmi.UnexpectedException("undeclared checked exception", e);
-        }
-    }
-}
--- a/jdk/test/java/rmi/transport/httpSocket/security.policy	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-
-grant {
-    permission java.net.SocketPermission "*:1024-", "accept,connect,listen";
-    permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.registry";
-    permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.server";
-    permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.transport";
-    permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.transport.proxy";
-    permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.transport.tcp";
-    permission java.lang.RuntimePermission "setFactory";
-};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/SecureRandom/MacNativePRNGSetSeed.java	Thu May 12 11:03:07 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.
+ */
+
+import java.security.SecureRandom;
+
+/* @test
+ * @bug 8156709
+ * @summary Cannot call setSeed on NativePRNG on Mac if EGD is /dev/urandom
+ * @requires os.name == "Mac OS X"
+ * @run main/othervm -Djava.security.egd=file:/dev/urandom MacNativePRNGSetSeed
+ */
+public class MacNativePRNGSetSeed {
+    public static void main(String[] args) throws Exception {
+        SecureRandom sr = SecureRandom.getInstance("NativePRNG");
+        sr.setSeed(1);
+    }
+}
--- a/jdk/test/java/time/tck/java/time/temporal/TCKIsoFields.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/time/tck/java/time/temporal/TCKIsoFields.java	Thu May 12 11:03:07 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,12 +71,15 @@
 import java.time.DayOfWeek;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.chrono.ThaiBuddhistDate;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
 import java.time.format.DateTimeParseException;
 import java.time.format.ResolverStyle;
 import java.time.temporal.IsoFields;
 import java.time.temporal.Temporal;
+import java.time.temporal.TemporalField;
+import java.time.temporal.UnsupportedTemporalTypeException;
 import java.time.temporal.ValueRange;
 
 import org.testng.annotations.DataProvider;
@@ -439,6 +442,29 @@
     }
 
     //-----------------------------------------------------------------------
+    // range refinedby
+    //-----------------------------------------------------------------------
+    @DataProvider(name="isofields")
+    Object[][] data_isofields() {
+        return new Object[][] {
+               {IsoFields.DAY_OF_QUARTER},
+               {IsoFields.QUARTER_OF_YEAR},
+               {IsoFields.WEEK_OF_WEEK_BASED_YEAR},
+               {IsoFields.WEEK_BASED_YEAR},
+        };
+    }
+
+    @Test(dataProvider = "isofields")
+    public void test_isofields_rangerefinedby(TemporalField field) {
+        field.rangeRefinedBy(LocalDate.now());
+    }
+
+    @Test(dataProvider = "isofields", expectedExceptions = UnsupportedTemporalTypeException.class)
+    public void test_nonisofields_rangerefinedby(TemporalField field) {
+        field.rangeRefinedBy(ThaiBuddhistDate.now());
+    }
+
+    //-----------------------------------------------------------------------
     public void test_loop() {
         // loop round at least one 400 year cycle, including before 1970
         LocalDate date = LocalDate.of(1960, 1, 5);  // Tuseday of week 1 1960
--- a/jdk/test/java/util/jar/JarFile/MultiReleaseJarAPI.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,210 +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.
- */
-
-/*
- * @test
- * @bug 8132734
- * @summary Test the extended API and the aliasing additions in JarFile that
- *          support multi-release jar files
- * @library /lib/testlibrary/java/util/jar
- * @build Compiler JarBuilder CreateMultiReleaseTestJars
- * @run testng MultiReleaseJarAPI
- */
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.util.Arrays;
-import java.util.jar.JarFile;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-import jdk.Version;
-
-import static java.util.jar.JarFile.Release;
-
-import org.testng.Assert;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
-
-public class MultiReleaseJarAPI {
-
-    static final int MAJOR_VERSION = Version.current().major();
-
-    String userdir = System.getProperty("user.dir",".");
-    CreateMultiReleaseTestJars creator =  new CreateMultiReleaseTestJars();
-    File unversioned = new File(userdir, "unversioned.jar");
-    File multirelease = new File(userdir, "multi-release.jar");
-    File signedmultirelease = new File(userdir, "signed-multi-release.jar");
-    Release[] values = JarFile.Release.values();
-
-
-    @BeforeClass
-    public void initialize() throws Exception {
-        creator.compileEntries();
-        creator.buildUnversionedJar();
-        creator.buildMultiReleaseJar();
-        creator.buildSignedMultiReleaseJar();
-    }
-
-    @AfterClass
-    public void close() throws IOException {
-        Files.delete(unversioned.toPath());
-        Files.delete(multirelease.toPath());
-        Files.delete(signedmultirelease.toPath());
-    }
-
-    @Test
-    public void isMultiReleaseJar() throws Exception {
-        try (JarFile jf = new JarFile(unversioned)) {
-            Assert.assertFalse(jf.isMultiRelease());
-        }
-
-        try (JarFile jf = new JarFile(unversioned, true, ZipFile.OPEN_READ, Release.RUNTIME)) {
-            Assert.assertFalse(jf.isMultiRelease());
-        }
-
-        try (JarFile jf = new JarFile(multirelease)) {
-            Assert.assertFalse(jf.isMultiRelease());
-        }
-
-        try (JarFile jf = new JarFile(multirelease, true, ZipFile.OPEN_READ, Release.RUNTIME)) {
-            Assert.assertTrue(jf.isMultiRelease());
-        }
-
-        testCustomMultiReleaseValue("true", true);
-        testCustomMultiReleaseValue("true\r\nOther: value", true);
-        testCustomMultiReleaseValue("true\nOther: value", true);
-        testCustomMultiReleaseValue("true\rOther: value", true);
-
-        testCustomMultiReleaseValue("false", false);
-        testCustomMultiReleaseValue(" true", false);
-        testCustomMultiReleaseValue("true ", false);
-        testCustomMultiReleaseValue("true\n ", false);
-        testCustomMultiReleaseValue("true\r ", false);
-        testCustomMultiReleaseValue("true\n true", false);
-        testCustomMultiReleaseValue("true\r\n true", false);
-    }
-
-    private void testCustomMultiReleaseValue(String value, boolean expected) throws Exception {
-        creator.buildCustomMultiReleaseJar("custom-mr.jar", value);
-        File custom = new File(userdir, "custom-mr.jar");
-        try (JarFile jf = new JarFile(custom, true, ZipFile.OPEN_READ, Release.RUNTIME)) {
-            Assert.assertEquals(jf.isMultiRelease(), expected);
-        }
-        Files.delete(custom.toPath());
-    }
-
-    @Test
-    public void testVersioning() throws Exception {
-        // multi-release jar
-        JarFile jar = new JarFile(multirelease);
-        Assert.assertEquals(Release.BASE, jar.getVersion());
-        jar.close();
-
-        for (Release value : values) {
-            System.err.println("test versioning for Release " + value);
-            try (JarFile jf = new JarFile(multirelease, true, ZipFile.OPEN_READ, value)) {
-                Assert.assertEquals(value, jf.getVersion());
-            }
-        }
-
-        // regular, unversioned, jar
-        for (Release value : values) {
-            try (JarFile jf = new JarFile(unversioned, true, ZipFile.OPEN_READ, value)) {
-                Assert.assertEquals(Release.BASE, jf.getVersion());
-            }
-        }
-
-        // assure that we have a Release object corresponding to the actual runtime version
-        String version = "VERSION_" + MAJOR_VERSION;
-        boolean runtimeVersionExists = false;
-        for (Release value : values) {
-            if (version.equals(value.name())) runtimeVersionExists = true;
-        }
-        Assert.assertTrue(runtimeVersionExists);
-    }
-
-    @Test
-    public void testAliasing() throws Exception {
-        for (Release value : values) {
-            System.err.println("test aliasing for Release " + value);
-            String name = value.name();
-            String prefix;
-            if (name.equals("BASE")) {
-                prefix = "";
-            } else if (name.equals("RUNTIME")) {
-                prefix = "META-INF/versions/" + MAJOR_VERSION + "/";
-            } else {
-                prefix = "META-INF/versions/" + name.substring(8) + "/";
-            }
-            // test both multi-release jars
-            readAndCompare(multirelease, value, "README", prefix + "README");
-            readAndCompare(multirelease, value, "version/Version.class", prefix + "version/Version.class");
-            // and signed multi-release jars
-            readAndCompare(signedmultirelease, value, "README", prefix + "README");
-            readAndCompare(signedmultirelease, value, "version/Version.class", prefix + "version/Version.class");
-        }
-    }
-
-    private void readAndCompare(File jar, Release version, String name, String realName) throws Exception {
-        byte[] baseBytes;
-        byte[] versionedBytes;
-        try (JarFile jf = new JarFile(jar, true, ZipFile.OPEN_READ, Release.BASE)) {
-            ZipEntry ze = jf.getEntry(realName);
-            try (InputStream is = jf.getInputStream(ze)) {
-                baseBytes = is.readAllBytes();
-            }
-        }
-        assert baseBytes.length > 0;
-
-        try (JarFile jf = new JarFile(jar, true, ZipFile.OPEN_READ, version)) {
-            ZipEntry ze = jf.getEntry(name);
-            try (InputStream is = jf.getInputStream(ze)) {
-                versionedBytes = is.readAllBytes();
-            }
-        }
-        assert versionedBytes.length > 0;
-
-        Assert.assertTrue(Arrays.equals(baseBytes, versionedBytes));
-    }
-
-    @Test
-    public void testNames() throws Exception {
-        String rname = "version/Version.class";
-        String vname = "META-INF/versions/9/version/Version.class";
-        ZipEntry ze1;
-        ZipEntry ze2;
-        try (JarFile jf = new JarFile(multirelease)) {
-            ze1 = jf.getEntry(vname);
-        }
-        Assert.assertEquals(ze1.getName(), vname);
-        try (JarFile jf = new JarFile(multirelease, true, ZipFile.OPEN_READ, Release.VERSION_9)) {
-            ze2 = jf.getEntry(rname);
-        }
-        Assert.assertEquals(ze2.getName(), rname);
-        Assert.assertNotEquals(ze1.getName(), ze2.getName());
-    }
-}
--- a/jdk/test/java/util/jar/JarFile/MultiReleaseJarHttpProperties.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,112 +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.
- */
-
-/*
- * @test
- * @bug 8132734
- * @summary Test the System properties for JarFile that support multi-release jar files
- * @library /lib/testlibrary/java/util/jar
- * @build Compiler JarBuilder CreateMultiReleaseTestJars SimpleHttpServer
- * @run testng MultiReleaseJarHttpProperties
- * @run testng/othervm -Djdk.util.jar.version=0 MultiReleaseJarHttpProperties
- * @run testng/othervm -Djdk.util.jar.version=8 MultiReleaseJarHttpProperties
- * @run testng/othervm -Djdk.util.jar.version=9 MultiReleaseJarHttpProperties
- * @run testng/othervm -Djdk.util.jar.version=10 MultiReleaseJarHttpProperties
- * @run testng/othervm -Djdk.util.jar.version=100 MultiReleaseJarHttpProperties
- * @run testng/othervm -Djdk.util.jar.version=8 -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarHttpProperties
- * @run testng/othervm -Djdk.util.jar.version=9 -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarHttpProperties
- * @run testng/othervm -Djdk.util.jar.version=10 -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarHttpProperties
- * @run testng/othervm -Djdk.util.jar.version=8 -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarHttpProperties
- * @run testng/othervm -Djdk.util.jar.version=9 -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarHttpProperties
- * @run testng/othervm -Djdk.util.jar.version=10 -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarHttpProperties
- * @run testng/othervm -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarHttpProperties
- * @run testng/othervm -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarHttpProperties
- */
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetSocketAddress;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
-import org.testng.Assert;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
-public class MultiReleaseJarHttpProperties extends MultiReleaseJarProperties {
-    private SimpleHttpServer server;
-
-    @BeforeClass
-    public void initialize() throws Exception {
-        server = new SimpleHttpServer();
-        server.start();
-        super.initialize();
-    }
-
-    @Override
-    protected void initializeClassLoader() throws Exception {
-        URL[] urls = new URL[]{
-                new URL("http://localhost:" + server.getPort() + "/multi-release.jar")
-        };
-        cldr = new URLClassLoader(urls);
-        // load any class, Main is convenient and in the root entries
-        rootClass = cldr.loadClass("version.Main");
-    }
-
-    @AfterClass
-    public void close() throws IOException {
-        // Windows requires server to stop before file is deleted
-        if (server != null)
-            server.stop();
-        super.close();
-    }
-
-    /*
-     * jdk.util.jar.enableMultiRelease=force is a no-op for URLClassLoader
-     */
-
-    @Test
-    public void testURLClassLoader() throws Throwable {
-        Class<?> vcls = cldr.loadClass("version.Version");
-        invokeMethod(vcls, rtVersion);
-    }
-
-    @Test
-    public void testGetResourceAsStream() throws Exception {
-        String resource = rtVersion == 9 ? "/version/PackagePrivate.java" : "/version/Version.java";
-        // use rootClass as a base for getting resources
-        getResourceAsStream(rootClass, resource);
-    }
-
-    @Test
-    public void testGetResource() throws Exception {
-        String resource = rtVersion == 9 ? "/version/PackagePrivate.java" : "/version/Version.java";
-        // use rootClass as a base for getting resources
-        getResource(rootClass, resource);
-    }
-}
--- a/jdk/test/java/util/jar/JarFile/MultiReleaseJarIterators.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,231 +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.
- */
-
-/*
- * @test
- * @bug 8132734
- * @summary Test the extended API and the aliasing additions in JarFile that
- *          support multi-release jar files
- * @library /lib/testlibrary/java/util/jar
- * @build Compiler JarBuilder CreateMultiReleaseTestJars
- * @run testng MultiReleaseJarIterators
- */
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-import java.util.stream.Collectors;
-import java.util.zip.ZipFile;
-import jdk.Version;
-
-import static java.util.jar.JarFile.Release;
-
-import org.testng.Assert;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
-
-public class MultiReleaseJarIterators {
-
-    static final int MAJOR_VERSION = Version.current().major();
-
-    String userdir = System.getProperty("user.dir", ".");
-    File unversioned = new File(userdir, "unversioned.jar");
-    File multirelease = new File(userdir, "multi-release.jar");
-    Map<String,JarEntry> uvEntries = new HashMap<>();
-    Map<String,JarEntry> mrEntries = new HashMap<>();
-    Map<String,JarEntry> baseEntries = new HashMap<>();
-    Map<String,JarEntry> v9Entries = new HashMap<>();
-    Map<String, JarEntry> v10Entries = new HashMap<>();
-
-    @BeforeClass
-    public void initialize() throws Exception {
-        CreateMultiReleaseTestJars creator = new CreateMultiReleaseTestJars();
-        creator.compileEntries();
-        creator.buildUnversionedJar();
-        creator.buildMultiReleaseJar();
-
-        try (JarFile jf = new JarFile(multirelease)) {
-            for (Enumeration<JarEntry> e = jf.entries(); e.hasMoreElements(); ) {
-                JarEntry je = e.nextElement();
-                String name = je.getName();
-                mrEntries.put(name, je);
-                if (name.startsWith("META-INF/versions/")) {
-                    if (name.startsWith("META-INF/versions/9/")) {
-                        v9Entries.put(name.substring(20), je);
-                    } else if (name.startsWith("META-INF/versions/10/")) {
-                        v10Entries.put(name.substring(21), je);
-                    }
-                } else {
-                    baseEntries.put(name, je);
-                }
-            }
-        }
-        Assert.assertEquals(mrEntries.size(), 14);
-        Assert.assertEquals(baseEntries.size(), 6);
-        Assert.assertEquals(v9Entries.size(), 5);
-        Assert.assertEquals(v10Entries.size(), 3);
-
-        try (JarFile jf = new JarFile(unversioned)) {
-            jf.entries().asIterator().forEachRemaining(je -> uvEntries.put(je.getName(), je));
-        }
-        Assert.assertEquals(uvEntries.size(), 6);
-    }
-
-    @AfterClass
-    public void close() throws IOException {
-        Files.delete(unversioned.toPath());
-        Files.delete(multirelease.toPath());
-    }
-
-    @Test
-    public void testMultiReleaseJar() throws IOException {
-        try (JarFile jf = new JarFile(multirelease, true, ZipFile.OPEN_READ)) {
-            testEnumeration(jf, mrEntries);
-            testStream(jf, mrEntries);
-        }
-
-        try (JarFile jf = new JarFile(multirelease, true, ZipFile.OPEN_READ, Release.BASE)) {
-            testEnumeration(jf, baseEntries);
-            testStream(jf, baseEntries);
-        }
-
-        try (JarFile jf = new JarFile(multirelease, true, ZipFile.OPEN_READ, Release.VERSION_9)) {
-            testEnumeration(jf, v9Entries);
-            testStream(jf, v9Entries);
-        }
-
-        try (JarFile jf = new JarFile(multirelease, true, ZipFile.OPEN_READ, Release.RUNTIME)) {
-            Map<String,JarEntry> expectedEntries;
-            switch (MAJOR_VERSION) {
-                case 9:
-                    expectedEntries = v9Entries;
-                    break;
-                case 10:  // won't get here until JDK 10
-                    expectedEntries = v10Entries;
-                    break;
-                default:
-                    expectedEntries = baseEntries;
-                    break;
-            }
-
-            testEnumeration(jf, expectedEntries);
-            testStream(jf, expectedEntries);
-        }
-    }
-
-    @Test
-    public void testUnversionedJar() throws IOException {
-        try (JarFile jf = new JarFile(unversioned, true, ZipFile.OPEN_READ)) {
-            testEnumeration(jf, uvEntries);
-            testStream(jf, uvEntries);
-        }
-
-        try (JarFile jf = new JarFile(unversioned, true, ZipFile.OPEN_READ, Release.BASE)) {
-            testEnumeration(jf, uvEntries);
-            testStream(jf, uvEntries);
-        }
-
-        try (JarFile jf = new JarFile(unversioned, true, ZipFile.OPEN_READ, Release.VERSION_9)) {
-            testEnumeration(jf, uvEntries);
-            testStream(jf, uvEntries);
-        }
-
-        try (JarFile jf = new JarFile(unversioned, true, ZipFile.OPEN_READ, Release.RUNTIME)) {
-            testEnumeration(jf, uvEntries);
-            testStream(jf, uvEntries);
-        }
-    }
-
-    private void testEnumeration(JarFile jf, Map<String,JarEntry> expectedEntries) {
-        Map<String, JarEntry> actualEntries = new HashMap<>();
-        for (Enumeration<JarEntry> e = jf.entries(); e.hasMoreElements(); ) {
-            JarEntry je = e.nextElement();
-            actualEntries.put(je.getName(), je);
-        }
-
-        testEntries(jf, actualEntries, expectedEntries);
-    }
-
-
-    private void testStream(JarFile jf, Map<String,JarEntry> expectedEntries) {
-        Map<String,JarEntry> actualEntries = jf.stream().collect(Collectors.toMap(je -> je.getName(), je -> je));
-
-        testEntries(jf, actualEntries, expectedEntries);
-    }
-
-    private void testEntries(JarFile jf, Map<String,JarEntry> actualEntries, Map<String,JarEntry> expectedEntries) {
-        /* For multi-release jar files constructed with a Release object,
-         * actualEntries contain versionedEntries that are considered part of the
-         * public API.  They have a 1-1 correspondence with baseEntries,
-         * so entries that are not part of the public API won't be present,
-         * i.e. those entries with a name that starts with version/PackagePrivate
-         * in this particular jar file (multi-release.jar)
-         */
-
-        Map<String,JarEntry> entries;
-        if (expectedEntries == mrEntries) {
-            Assert.assertEquals(actualEntries.size(), mrEntries.size());
-            entries = mrEntries;
-        } else if (expectedEntries == uvEntries) {
-            Assert.assertEquals(actualEntries.size(), uvEntries.size());
-            entries = uvEntries;
-        } else {
-            Assert.assertEquals(actualEntries.size(), baseEntries.size());  // this is correct
-            entries = baseEntries;
-        }
-
-        entries.keySet().forEach(name -> {
-            JarEntry ee = expectedEntries.get(name);
-            if (ee == null) ee = entries.get(name);
-            JarEntry ae = actualEntries.get(name);
-            try {
-                compare(jf, ae, ee);
-            } catch (IOException x) {
-                throw new RuntimeException(x);
-            }
-        });
-    }
-
-    private void compare(JarFile jf, JarEntry actual, JarEntry expected) throws IOException {
-        byte[] abytes;
-        byte[] ebytes;
-
-        try (InputStream is = jf.getInputStream(actual)) {
-            abytes = is.readAllBytes();
-        }
-
-        try (InputStream is = jf.getInputStream(expected)) {
-            ebytes = is.readAllBytes();
-        }
-
-        Assert.assertEquals(abytes, ebytes);
-    }
-}
--- a/jdk/test/java/util/jar/JarFile/MultiReleaseJarProperties.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,202 +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.
- */
-
-/*
- * @test
- * @bug 8132734
- * @summary Test the System properties for JarFile that support multi-release jar files
- * @library /lib/testlibrary/java/util/jar
- * @build Compiler JarBuilder CreateMultiReleaseTestJars
- * @run testng MultiReleaseJarProperties
- * @run testng/othervm -Djdk.util.jar.version=0 MultiReleaseJarProperties
- * @run testng/othervm -Djdk.util.jar.version=8 MultiReleaseJarProperties
- * @run testng/othervm -Djdk.util.jar.version=9 MultiReleaseJarProperties
- * @run testng/othervm -Djdk.util.jar.version=10 MultiReleaseJarProperties
- * @run testng/othervm -Djdk.util.jar.version=100 MultiReleaseJarProperties
- * @run testng/othervm -Djdk.util.jar.version=8 -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarProperties
- * @run testng/othervm -Djdk.util.jar.version=9 -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarProperties
- * @run testng/othervm -Djdk.util.jar.version=10 -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarProperties
- * @run testng/othervm -Djdk.util.jar.version=8 -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarProperties
- * @run testng/othervm -Djdk.util.jar.version=9 -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarProperties
- * @run testng/othervm -Djdk.util.jar.version=10 -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarProperties
- * @run testng/othervm -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarProperties
- * @run testng/othervm -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarProperties
- */
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.nio.file.Files;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-import jdk.Version;
-
-import org.testng.Assert;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
-public class MultiReleaseJarProperties {
-
-    static final int MAJOR_VERSION = Version.current().major();
-
-    final static int ROOTVERSION = 8; // magic number from knowledge of internals
-    final static String userdir = System.getProperty("user.dir", ".");
-    final static File multirelease = new File(userdir, "multi-release.jar");
-    protected int rtVersion;
-    boolean force;
-    protected ClassLoader cldr;
-    protected Class<?> rootClass;
-
-    @BeforeClass
-    public void initialize() throws Exception {
-        CreateMultiReleaseTestJars creator =  new CreateMultiReleaseTestJars();
-        creator.compileEntries();
-        creator.buildMultiReleaseJar();
-
-        rtVersion = Integer.getInteger("jdk.util.jar.version", MAJOR_VERSION);
-        String mrprop = System.getProperty("jdk.util.jar.enableMultiRelease", "");
-        if (mrprop.equals("false")) {
-            rtVersion = ROOTVERSION;
-        } else if (rtVersion < ROOTVERSION) {
-            rtVersion = ROOTVERSION;
-        } else if (rtVersion > MAJOR_VERSION) {
-            rtVersion = MAJOR_VERSION;
-        }
-        force = mrprop.equals("force");
-
-        initializeClassLoader();
-    }
-
-    protected void initializeClassLoader() throws Exception {
-        URL[] urls = new URL[]{multirelease.toURI().toURL()};
-        cldr = new URLClassLoader(urls);
-        // load any class, Main is convenient and in the root entries
-        rootClass = cldr.loadClass("version.Main");
-    }
-
-    @AfterClass
-    public void close() throws IOException {
-        ((URLClassLoader)cldr).close();
-        Files.delete(multirelease.toPath());
-    }
-
-    /*
-     * jdk.util.jar.enableMultiRelease=force is a no-op for URLClassLoader
-     */
-    @Test
-    public void testURLClassLoader() throws Throwable {
-        Class<?> vcls = cldr.loadClass("version.Version");
-        invokeMethod(vcls, rtVersion);
-    }
-
-    protected void invokeMethod(Class<?> vcls, int expected) throws Throwable {
-        MethodType mt = MethodType.methodType(int.class);
-        MethodHandle mh = MethodHandles.lookup().findVirtual(vcls, "getVersion", mt);
-        Assert.assertEquals(expected, (int) mh.invoke(vcls.newInstance()));
-    }
-
-    /*
-     * jdk.util.jar.enableMultiRelease=force should affect a custom class loader
-     */
-    @Test
-    public void testClassLoader() throws Throwable {
-        try (JarFile jf = new JarFile(multirelease)) {  // do not set runtime versioning
-            ClassLoader cldr = new CustomClassLoader(jf);
-            Class<?> vcls = cldr.loadClass("version.Version");
-            if (rtVersion == 9) {
-                try {
-                    cldr.loadClass("version.PackagePrivate");
-                } catch (ClassNotFoundException x) {
-                    if (force) throw x;
-                }
-            }
-            invokeMethod(vcls, force ? rtVersion : ROOTVERSION);
-        }
-    }
-
-    private static class CustomClassLoader extends ClassLoader {
-        private final JarFile jf;
-
-        CustomClassLoader(JarFile jf) throws Exception {
-            super(null);
-            this.jf = jf;
-        }
-
-        protected Class<?> findClass(String name) throws ClassNotFoundException {
-            try {
-                byte[] b;
-                String entryName = name.replace(".", "/") + ".class";
-                JarEntry je = jf.getJarEntry(entryName);
-                if (je != null) {
-                    try (InputStream is = jf.getInputStream(je)) {
-                        b = new byte[(int) je.getSize()];
-                        is.read(b);
-                    }
-                    return defineClass(name, b, 0, b.length);
-                }
-                throw new ClassNotFoundException(name);
-            } catch (IOException x) {
-                throw new ClassNotFoundException(x.getMessage());
-            }
-        }
-    }
-
-    @Test
-    public void testGetResourceAsStream() throws Exception {
-        String resource = rtVersion == 9 ? "/version/PackagePrivate.java" : "/version/Version.java";
-        // use fileRootClass as a base for getting resources
-        getResourceAsStream(rootClass, resource);
-    }
-
-    protected void getResourceAsStream(Class<?> rootClass, String resource) throws Exception {
-        try (InputStream is = rootClass.getResourceAsStream(resource)) {
-            byte[] bytes = is.readAllBytes();
-            resource = new String(bytes);
-        }
-        String match = "return " + rtVersion + ";";
-        Assert.assertTrue(resource.contains(match));
-    }
-
-    @Test
-    public void testGetResource() throws Exception {
-        String resource = rtVersion == 9 ? "/version/PackagePrivate.java" : "/version/Version.java";
-        // use rootClass as a base for getting resources
-        getResource(rootClass, resource);
-    }
-
-    protected void getResource(Class<?> rootClass, String resource) throws Exception {
-        URL url = rootClass.getResource(resource);
-        try (InputStream is = url.openStream()) {
-            byte[] bytes = is.readAllBytes();
-            resource = new String(bytes);
-        }
-        String match = "return " + rtVersion + ";";
-        Assert.assertTrue(resource.contains(match));
-    }
-}
--- a/jdk/test/java/util/jar/JarFile/MultiReleaseJarSecurity.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +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.
- */
-
-/*
- * @test
- * @bug 8132734
- * @summary Test potential security related issues
- * @library /lib/testlibrary/java/util/jar
- * @build Compiler JarBuilder CreateMultiReleaseTestJars
- * @run testng MultiReleaseJarSecurity
- */
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.security.CodeSigner;
-import java.security.cert.Certificate;
-import java.util.Arrays;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-import java.util.zip.ZipFile;
-import jdk.Version;
-
-import org.testng.Assert;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
-public class MultiReleaseJarSecurity {
-
-    static final int MAJOR_VERSION = Version.current().major();
-
-    String userdir = System.getProperty("user.dir",".");
-    File multirelease = new File(userdir, "multi-release.jar");
-    File signedmultirelease = new File(userdir, "signed-multi-release.jar");
-
-    @BeforeClass
-    public void initialize() throws Exception {
-        CreateMultiReleaseTestJars creator =  new CreateMultiReleaseTestJars();
-        creator.compileEntries();
-        creator.buildMultiReleaseJar();
-        creator.buildSignedMultiReleaseJar();
-    }
-
-    @AfterClass
-    public void close() throws IOException {
-        Files.delete(multirelease.toPath());
-        Files.delete(signedmultirelease.toPath());
-    }
-
-    @Test
-    public void testCertsAndSigners() throws IOException {
-        try (JarFile jf = new JarFile(signedmultirelease, true, ZipFile.OPEN_READ, JarFile.Release.RUNTIME)) {
-            CertsAndSigners vcas = new CertsAndSigners(jf, jf.getJarEntry("version/Version.class"));
-            CertsAndSigners rcas = new CertsAndSigners(jf, jf.getJarEntry("META-INF/versions/" + MAJOR_VERSION + "/version/Version.class"));
-            Assert.assertTrue(Arrays.equals(rcas.getCertificates(), vcas.getCertificates()));
-            Assert.assertTrue(Arrays.equals(rcas.getCodeSigners(), vcas.getCodeSigners()));
-        }
-    }
-
-    private static class CertsAndSigners {
-        final private JarFile jf;
-        final private JarEntry je;
-        private boolean readComplete;
-
-        CertsAndSigners(JarFile jf, JarEntry je) {
-            this.jf = jf;
-            this.je = je;
-        }
-
-        Certificate[] getCertificates() throws IOException {
-            readEntry();
-            return je.getCertificates();
-        }
-
-        CodeSigner[] getCodeSigners() throws IOException {
-            readEntry();
-            return je.getCodeSigners();
-        }
-
-        private void readEntry() throws IOException {
-            if (!readComplete) {
-                try (InputStream is = jf.getInputStream(je)) {
-                    is.readAllBytes();
-                }
-                readComplete = true;
-            }
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/jar/JarFile/mrjar/MultiReleaseJarAPI.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,210 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8132734
+ * @summary Test the extended API and the aliasing additions in JarFile that
+ *          support multi-release jar files
+ * @library /lib/testlibrary/java/util/jar
+ * @build Compiler JarBuilder CreateMultiReleaseTestJars
+ * @run testng MultiReleaseJarAPI
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.util.Arrays;
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import jdk.Version;
+
+import static java.util.jar.JarFile.Release;
+
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+
+public class MultiReleaseJarAPI {
+
+    static final int MAJOR_VERSION = Version.current().major();
+
+    String userdir = System.getProperty("user.dir",".");
+    CreateMultiReleaseTestJars creator =  new CreateMultiReleaseTestJars();
+    File unversioned = new File(userdir, "unversioned.jar");
+    File multirelease = new File(userdir, "multi-release.jar");
+    File signedmultirelease = new File(userdir, "signed-multi-release.jar");
+    Release[] values = JarFile.Release.values();
+
+
+    @BeforeClass
+    public void initialize() throws Exception {
+        creator.compileEntries();
+        creator.buildUnversionedJar();
+        creator.buildMultiReleaseJar();
+        creator.buildSignedMultiReleaseJar();
+    }
+
+    @AfterClass
+    public void close() throws IOException {
+        Files.delete(unversioned.toPath());
+        Files.delete(multirelease.toPath());
+        Files.delete(signedmultirelease.toPath());
+    }
+
+    @Test
+    public void isMultiReleaseJar() throws Exception {
+        try (JarFile jf = new JarFile(unversioned)) {
+            Assert.assertFalse(jf.isMultiRelease());
+        }
+
+        try (JarFile jf = new JarFile(unversioned, true, ZipFile.OPEN_READ, Release.RUNTIME)) {
+            Assert.assertFalse(jf.isMultiRelease());
+        }
+
+        try (JarFile jf = new JarFile(multirelease)) {
+            Assert.assertFalse(jf.isMultiRelease());
+        }
+
+        try (JarFile jf = new JarFile(multirelease, true, ZipFile.OPEN_READ, Release.RUNTIME)) {
+            Assert.assertTrue(jf.isMultiRelease());
+        }
+
+        testCustomMultiReleaseValue("true", true);
+        testCustomMultiReleaseValue("true\r\nOther: value", true);
+        testCustomMultiReleaseValue("true\nOther: value", true);
+        testCustomMultiReleaseValue("true\rOther: value", true);
+
+        testCustomMultiReleaseValue("false", false);
+        testCustomMultiReleaseValue(" true", false);
+        testCustomMultiReleaseValue("true ", false);
+        testCustomMultiReleaseValue("true\n ", false);
+        testCustomMultiReleaseValue("true\r ", false);
+        testCustomMultiReleaseValue("true\n true", false);
+        testCustomMultiReleaseValue("true\r\n true", false);
+    }
+
+    private void testCustomMultiReleaseValue(String value, boolean expected) throws Exception {
+        creator.buildCustomMultiReleaseJar("custom-mr.jar", value);
+        File custom = new File(userdir, "custom-mr.jar");
+        try (JarFile jf = new JarFile(custom, true, ZipFile.OPEN_READ, Release.RUNTIME)) {
+            Assert.assertEquals(jf.isMultiRelease(), expected);
+        }
+        Files.delete(custom.toPath());
+    }
+
+    @Test
+    public void testVersioning() throws Exception {
+        // multi-release jar
+        JarFile jar = new JarFile(multirelease);
+        Assert.assertEquals(Release.BASE, jar.getVersion());
+        jar.close();
+
+        for (Release value : values) {
+            System.err.println("test versioning for Release " + value);
+            try (JarFile jf = new JarFile(multirelease, true, ZipFile.OPEN_READ, value)) {
+                Assert.assertEquals(value, jf.getVersion());
+            }
+        }
+
+        // regular, unversioned, jar
+        for (Release value : values) {
+            try (JarFile jf = new JarFile(unversioned, true, ZipFile.OPEN_READ, value)) {
+                Assert.assertEquals(Release.BASE, jf.getVersion());
+            }
+        }
+
+        // assure that we have a Release object corresponding to the actual runtime version
+        String version = "VERSION_" + MAJOR_VERSION;
+        boolean runtimeVersionExists = false;
+        for (Release value : values) {
+            if (version.equals(value.name())) runtimeVersionExists = true;
+        }
+        Assert.assertTrue(runtimeVersionExists);
+    }
+
+    @Test
+    public void testAliasing() throws Exception {
+        for (Release value : values) {
+            System.err.println("test aliasing for Release " + value);
+            String name = value.name();
+            String prefix;
+            if (name.equals("BASE")) {
+                prefix = "";
+            } else if (name.equals("RUNTIME")) {
+                prefix = "META-INF/versions/" + MAJOR_VERSION + "/";
+            } else {
+                prefix = "META-INF/versions/" + name.substring(8) + "/";
+            }
+            // test both multi-release jars
+            readAndCompare(multirelease, value, "README", prefix + "README");
+            readAndCompare(multirelease, value, "version/Version.class", prefix + "version/Version.class");
+            // and signed multi-release jars
+            readAndCompare(signedmultirelease, value, "README", prefix + "README");
+            readAndCompare(signedmultirelease, value, "version/Version.class", prefix + "version/Version.class");
+        }
+    }
+
+    private void readAndCompare(File jar, Release version, String name, String realName) throws Exception {
+        byte[] baseBytes;
+        byte[] versionedBytes;
+        try (JarFile jf = new JarFile(jar, true, ZipFile.OPEN_READ, Release.BASE)) {
+            ZipEntry ze = jf.getEntry(realName);
+            try (InputStream is = jf.getInputStream(ze)) {
+                baseBytes = is.readAllBytes();
+            }
+        }
+        assert baseBytes.length > 0;
+
+        try (JarFile jf = new JarFile(jar, true, ZipFile.OPEN_READ, version)) {
+            ZipEntry ze = jf.getEntry(name);
+            try (InputStream is = jf.getInputStream(ze)) {
+                versionedBytes = is.readAllBytes();
+            }
+        }
+        assert versionedBytes.length > 0;
+
+        Assert.assertTrue(Arrays.equals(baseBytes, versionedBytes));
+    }
+
+    @Test
+    public void testNames() throws Exception {
+        String rname = "version/Version.class";
+        String vname = "META-INF/versions/9/version/Version.class";
+        ZipEntry ze1;
+        ZipEntry ze2;
+        try (JarFile jf = new JarFile(multirelease)) {
+            ze1 = jf.getEntry(vname);
+        }
+        Assert.assertEquals(ze1.getName(), vname);
+        try (JarFile jf = new JarFile(multirelease, true, ZipFile.OPEN_READ, Release.VERSION_9)) {
+            ze2 = jf.getEntry(rname);
+        }
+        Assert.assertEquals(ze2.getName(), rname);
+        Assert.assertNotEquals(ze1.getName(), ze2.getName());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/jar/JarFile/mrjar/MultiReleaseJarHttpProperties.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,115 @@
+/*
+ * 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 8132734
+ * @summary Test the System properties for JarFile that support multi-release jar files
+ * @library /lib/testlibrary/java/util/jar
+ * @modules jdk.jartool
+ *          jdk.compiler
+ *          jdk.httpserver
+ * @build Compiler JarBuilder CreateMultiReleaseTestJars SimpleHttpServer
+ * @run testng MultiReleaseJarHttpProperties
+ * @run testng/othervm -Djdk.util.jar.version=0 MultiReleaseJarHttpProperties
+ * @run testng/othervm -Djdk.util.jar.version=8 MultiReleaseJarHttpProperties
+ * @run testng/othervm -Djdk.util.jar.version=9 MultiReleaseJarHttpProperties
+ * @run testng/othervm -Djdk.util.jar.version=10 MultiReleaseJarHttpProperties
+ * @run testng/othervm -Djdk.util.jar.version=100 MultiReleaseJarHttpProperties
+ * @run testng/othervm -Djdk.util.jar.version=8 -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarHttpProperties
+ * @run testng/othervm -Djdk.util.jar.version=9 -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarHttpProperties
+ * @run testng/othervm -Djdk.util.jar.version=10 -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarHttpProperties
+ * @run testng/othervm -Djdk.util.jar.version=8 -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarHttpProperties
+ * @run testng/othervm -Djdk.util.jar.version=9 -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarHttpProperties
+ * @run testng/othervm -Djdk.util.jar.version=10 -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarHttpProperties
+ * @run testng/othervm -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarHttpProperties
+ * @run testng/othervm -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarHttpProperties
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class MultiReleaseJarHttpProperties extends MultiReleaseJarProperties {
+    private SimpleHttpServer server;
+
+    @BeforeClass
+    public void initialize() throws Exception {
+        server = new SimpleHttpServer();
+        server.start();
+        super.initialize();
+    }
+
+    @Override
+    protected void initializeClassLoader() throws Exception {
+        URL[] urls = new URL[]{
+                new URL("http://localhost:" + server.getPort() + "/multi-release.jar")
+        };
+        cldr = new URLClassLoader(urls);
+        // load any class, Main is convenient and in the root entries
+        rootClass = cldr.loadClass("version.Main");
+    }
+
+    @AfterClass
+    public void close() throws IOException {
+        // Windows requires server to stop before file is deleted
+        if (server != null)
+            server.stop();
+        super.close();
+    }
+
+    /*
+     * jdk.util.jar.enableMultiRelease=force is a no-op for URLClassLoader
+     */
+
+    @Test
+    public void testURLClassLoader() throws Throwable {
+        Class<?> vcls = cldr.loadClass("version.Version");
+        invokeMethod(vcls, rtVersion);
+    }
+
+    @Test
+    public void testGetResourceAsStream() throws Exception {
+        String resource = rtVersion == 9 ? "/version/PackagePrivate.java" : "/version/Version.java";
+        // use rootClass as a base for getting resources
+        getResourceAsStream(rootClass, resource);
+    }
+
+    @Test
+    public void testGetResource() throws Exception {
+        String resource = rtVersion == 9 ? "/version/PackagePrivate.java" : "/version/Version.java";
+        // use rootClass as a base for getting resources
+        getResource(rootClass, resource);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/jar/JarFile/mrjar/MultiReleaseJarIterators.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,231 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8132734
+ * @summary Test the extended API and the aliasing additions in JarFile that
+ *          support multi-release jar files
+ * @library /lib/testlibrary/java/util/jar
+ * @build Compiler JarBuilder CreateMultiReleaseTestJars
+ * @run testng MultiReleaseJarIterators
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.stream.Collectors;
+import java.util.zip.ZipFile;
+import jdk.Version;
+
+import static java.util.jar.JarFile.Release;
+
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+
+public class MultiReleaseJarIterators {
+
+    static final int MAJOR_VERSION = Version.current().major();
+
+    String userdir = System.getProperty("user.dir", ".");
+    File unversioned = new File(userdir, "unversioned.jar");
+    File multirelease = new File(userdir, "multi-release.jar");
+    Map<String,JarEntry> uvEntries = new HashMap<>();
+    Map<String,JarEntry> mrEntries = new HashMap<>();
+    Map<String,JarEntry> baseEntries = new HashMap<>();
+    Map<String,JarEntry> v9Entries = new HashMap<>();
+    Map<String, JarEntry> v10Entries = new HashMap<>();
+
+    @BeforeClass
+    public void initialize() throws Exception {
+        CreateMultiReleaseTestJars creator = new CreateMultiReleaseTestJars();
+        creator.compileEntries();
+        creator.buildUnversionedJar();
+        creator.buildMultiReleaseJar();
+
+        try (JarFile jf = new JarFile(multirelease)) {
+            for (Enumeration<JarEntry> e = jf.entries(); e.hasMoreElements(); ) {
+                JarEntry je = e.nextElement();
+                String name = je.getName();
+                mrEntries.put(name, je);
+                if (name.startsWith("META-INF/versions/")) {
+                    if (name.startsWith("META-INF/versions/9/")) {
+                        v9Entries.put(name.substring(20), je);
+                    } else if (name.startsWith("META-INF/versions/10/")) {
+                        v10Entries.put(name.substring(21), je);
+                    }
+                } else {
+                    baseEntries.put(name, je);
+                }
+            }
+        }
+        Assert.assertEquals(mrEntries.size(), 14);
+        Assert.assertEquals(baseEntries.size(), 6);
+        Assert.assertEquals(v9Entries.size(), 5);
+        Assert.assertEquals(v10Entries.size(), 3);
+
+        try (JarFile jf = new JarFile(unversioned)) {
+            jf.entries().asIterator().forEachRemaining(je -> uvEntries.put(je.getName(), je));
+        }
+        Assert.assertEquals(uvEntries.size(), 6);
+    }
+
+    @AfterClass
+    public void close() throws IOException {
+        Files.delete(unversioned.toPath());
+        Files.delete(multirelease.toPath());
+    }
+
+    @Test
+    public void testMultiReleaseJar() throws IOException {
+        try (JarFile jf = new JarFile(multirelease, true, ZipFile.OPEN_READ)) {
+            testEnumeration(jf, mrEntries);
+            testStream(jf, mrEntries);
+        }
+
+        try (JarFile jf = new JarFile(multirelease, true, ZipFile.OPEN_READ, Release.BASE)) {
+            testEnumeration(jf, baseEntries);
+            testStream(jf, baseEntries);
+        }
+
+        try (JarFile jf = new JarFile(multirelease, true, ZipFile.OPEN_READ, Release.VERSION_9)) {
+            testEnumeration(jf, v9Entries);
+            testStream(jf, v9Entries);
+        }
+
+        try (JarFile jf = new JarFile(multirelease, true, ZipFile.OPEN_READ, Release.RUNTIME)) {
+            Map<String,JarEntry> expectedEntries;
+            switch (MAJOR_VERSION) {
+                case 9:
+                    expectedEntries = v9Entries;
+                    break;
+                case 10:  // won't get here until JDK 10
+                    expectedEntries = v10Entries;
+                    break;
+                default:
+                    expectedEntries = baseEntries;
+                    break;
+            }
+
+            testEnumeration(jf, expectedEntries);
+            testStream(jf, expectedEntries);
+        }
+    }
+
+    @Test
+    public void testUnversionedJar() throws IOException {
+        try (JarFile jf = new JarFile(unversioned, true, ZipFile.OPEN_READ)) {
+            testEnumeration(jf, uvEntries);
+            testStream(jf, uvEntries);
+        }
+
+        try (JarFile jf = new JarFile(unversioned, true, ZipFile.OPEN_READ, Release.BASE)) {
+            testEnumeration(jf, uvEntries);
+            testStream(jf, uvEntries);
+        }
+
+        try (JarFile jf = new JarFile(unversioned, true, ZipFile.OPEN_READ, Release.VERSION_9)) {
+            testEnumeration(jf, uvEntries);
+            testStream(jf, uvEntries);
+        }
+
+        try (JarFile jf = new JarFile(unversioned, true, ZipFile.OPEN_READ, Release.RUNTIME)) {
+            testEnumeration(jf, uvEntries);
+            testStream(jf, uvEntries);
+        }
+    }
+
+    private void testEnumeration(JarFile jf, Map<String,JarEntry> expectedEntries) {
+        Map<String, JarEntry> actualEntries = new HashMap<>();
+        for (Enumeration<JarEntry> e = jf.entries(); e.hasMoreElements(); ) {
+            JarEntry je = e.nextElement();
+            actualEntries.put(je.getName(), je);
+        }
+
+        testEntries(jf, actualEntries, expectedEntries);
+    }
+
+
+    private void testStream(JarFile jf, Map<String,JarEntry> expectedEntries) {
+        Map<String,JarEntry> actualEntries = jf.stream().collect(Collectors.toMap(je -> je.getName(), je -> je));
+
+        testEntries(jf, actualEntries, expectedEntries);
+    }
+
+    private void testEntries(JarFile jf, Map<String,JarEntry> actualEntries, Map<String,JarEntry> expectedEntries) {
+        /* For multi-release jar files constructed with a Release object,
+         * actualEntries contain versionedEntries that are considered part of the
+         * public API.  They have a 1-1 correspondence with baseEntries,
+         * so entries that are not part of the public API won't be present,
+         * i.e. those entries with a name that starts with version/PackagePrivate
+         * in this particular jar file (multi-release.jar)
+         */
+
+        Map<String,JarEntry> entries;
+        if (expectedEntries == mrEntries) {
+            Assert.assertEquals(actualEntries.size(), mrEntries.size());
+            entries = mrEntries;
+        } else if (expectedEntries == uvEntries) {
+            Assert.assertEquals(actualEntries.size(), uvEntries.size());
+            entries = uvEntries;
+        } else {
+            Assert.assertEquals(actualEntries.size(), baseEntries.size());  // this is correct
+            entries = baseEntries;
+        }
+
+        entries.keySet().forEach(name -> {
+            JarEntry ee = expectedEntries.get(name);
+            if (ee == null) ee = entries.get(name);
+            JarEntry ae = actualEntries.get(name);
+            try {
+                compare(jf, ae, ee);
+            } catch (IOException x) {
+                throw new RuntimeException(x);
+            }
+        });
+    }
+
+    private void compare(JarFile jf, JarEntry actual, JarEntry expected) throws IOException {
+        byte[] abytes;
+        byte[] ebytes;
+
+        try (InputStream is = jf.getInputStream(actual)) {
+            abytes = is.readAllBytes();
+        }
+
+        try (InputStream is = jf.getInputStream(expected)) {
+            ebytes = is.readAllBytes();
+        }
+
+        Assert.assertEquals(abytes, ebytes);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/jar/JarFile/mrjar/MultiReleaseJarProperties.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,202 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8132734
+ * @summary Test the System properties for JarFile that support multi-release jar files
+ * @library /lib/testlibrary/java/util/jar
+ * @build Compiler JarBuilder CreateMultiReleaseTestJars
+ * @run testng MultiReleaseJarProperties
+ * @run testng/othervm -Djdk.util.jar.version=0 MultiReleaseJarProperties
+ * @run testng/othervm -Djdk.util.jar.version=8 MultiReleaseJarProperties
+ * @run testng/othervm -Djdk.util.jar.version=9 MultiReleaseJarProperties
+ * @run testng/othervm -Djdk.util.jar.version=10 MultiReleaseJarProperties
+ * @run testng/othervm -Djdk.util.jar.version=100 MultiReleaseJarProperties
+ * @run testng/othervm -Djdk.util.jar.version=8 -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarProperties
+ * @run testng/othervm -Djdk.util.jar.version=9 -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarProperties
+ * @run testng/othervm -Djdk.util.jar.version=10 -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarProperties
+ * @run testng/othervm -Djdk.util.jar.version=8 -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarProperties
+ * @run testng/othervm -Djdk.util.jar.version=9 -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarProperties
+ * @run testng/othervm -Djdk.util.jar.version=10 -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarProperties
+ * @run testng/othervm -Djdk.util.jar.enableMultiRelease=false MultiReleaseJarProperties
+ * @run testng/othervm -Djdk.util.jar.enableMultiRelease=force MultiReleaseJarProperties
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.Files;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import jdk.Version;
+
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class MultiReleaseJarProperties {
+
+    static final int MAJOR_VERSION = Version.current().major();
+
+    final static int ROOTVERSION = 8; // magic number from knowledge of internals
+    final static String userdir = System.getProperty("user.dir", ".");
+    final static File multirelease = new File(userdir, "multi-release.jar");
+    protected int rtVersion;
+    boolean force;
+    protected ClassLoader cldr;
+    protected Class<?> rootClass;
+
+    @BeforeClass
+    public void initialize() throws Exception {
+        CreateMultiReleaseTestJars creator =  new CreateMultiReleaseTestJars();
+        creator.compileEntries();
+        creator.buildMultiReleaseJar();
+
+        rtVersion = Integer.getInteger("jdk.util.jar.version", MAJOR_VERSION);
+        String mrprop = System.getProperty("jdk.util.jar.enableMultiRelease", "");
+        if (mrprop.equals("false")) {
+            rtVersion = ROOTVERSION;
+        } else if (rtVersion < ROOTVERSION) {
+            rtVersion = ROOTVERSION;
+        } else if (rtVersion > MAJOR_VERSION) {
+            rtVersion = MAJOR_VERSION;
+        }
+        force = mrprop.equals("force");
+
+        initializeClassLoader();
+    }
+
+    protected void initializeClassLoader() throws Exception {
+        URL[] urls = new URL[]{multirelease.toURI().toURL()};
+        cldr = new URLClassLoader(urls);
+        // load any class, Main is convenient and in the root entries
+        rootClass = cldr.loadClass("version.Main");
+    }
+
+    @AfterClass
+    public void close() throws IOException {
+        ((URLClassLoader)cldr).close();
+        Files.delete(multirelease.toPath());
+    }
+
+    /*
+     * jdk.util.jar.enableMultiRelease=force is a no-op for URLClassLoader
+     */
+    @Test
+    public void testURLClassLoader() throws Throwable {
+        Class<?> vcls = cldr.loadClass("version.Version");
+        invokeMethod(vcls, rtVersion);
+    }
+
+    protected void invokeMethod(Class<?> vcls, int expected) throws Throwable {
+        MethodType mt = MethodType.methodType(int.class);
+        MethodHandle mh = MethodHandles.lookup().findVirtual(vcls, "getVersion", mt);
+        Assert.assertEquals(expected, (int) mh.invoke(vcls.newInstance()));
+    }
+
+    /*
+     * jdk.util.jar.enableMultiRelease=force should affect a custom class loader
+     */
+    @Test
+    public void testClassLoader() throws Throwable {
+        try (JarFile jf = new JarFile(multirelease)) {  // do not set runtime versioning
+            ClassLoader cldr = new CustomClassLoader(jf);
+            Class<?> vcls = cldr.loadClass("version.Version");
+            if (rtVersion == 9) {
+                try {
+                    cldr.loadClass("version.PackagePrivate");
+                } catch (ClassNotFoundException x) {
+                    if (force) throw x;
+                }
+            }
+            invokeMethod(vcls, force ? rtVersion : ROOTVERSION);
+        }
+    }
+
+    private static class CustomClassLoader extends ClassLoader {
+        private final JarFile jf;
+
+        CustomClassLoader(JarFile jf) throws Exception {
+            super(null);
+            this.jf = jf;
+        }
+
+        protected Class<?> findClass(String name) throws ClassNotFoundException {
+            try {
+                byte[] b;
+                String entryName = name.replace(".", "/") + ".class";
+                JarEntry je = jf.getJarEntry(entryName);
+                if (je != null) {
+                    try (InputStream is = jf.getInputStream(je)) {
+                        b = new byte[(int) je.getSize()];
+                        is.read(b);
+                    }
+                    return defineClass(name, b, 0, b.length);
+                }
+                throw new ClassNotFoundException(name);
+            } catch (IOException x) {
+                throw new ClassNotFoundException(x.getMessage());
+            }
+        }
+    }
+
+    @Test
+    public void testGetResourceAsStream() throws Exception {
+        String resource = rtVersion == 9 ? "/version/PackagePrivate.java" : "/version/Version.java";
+        // use fileRootClass as a base for getting resources
+        getResourceAsStream(rootClass, resource);
+    }
+
+    protected void getResourceAsStream(Class<?> rootClass, String resource) throws Exception {
+        try (InputStream is = rootClass.getResourceAsStream(resource)) {
+            byte[] bytes = is.readAllBytes();
+            resource = new String(bytes);
+        }
+        String match = "return " + rtVersion + ";";
+        Assert.assertTrue(resource.contains(match));
+    }
+
+    @Test
+    public void testGetResource() throws Exception {
+        String resource = rtVersion == 9 ? "/version/PackagePrivate.java" : "/version/Version.java";
+        // use rootClass as a base for getting resources
+        getResource(rootClass, resource);
+    }
+
+    protected void getResource(Class<?> rootClass, String resource) throws Exception {
+        URL url = rootClass.getResource(resource);
+        try (InputStream is = url.openStream()) {
+            byte[] bytes = is.readAllBytes();
+            resource = new String(bytes);
+        }
+        String match = "return " + rtVersion + ";";
+        Assert.assertTrue(resource.contains(match));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/jar/JarFile/mrjar/MultiReleaseJarSecurity.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8132734
+ * @summary Test potential security related issues
+ * @library /lib/testlibrary/java/util/jar
+ * @build Compiler JarBuilder CreateMultiReleaseTestJars
+ * @run testng MultiReleaseJarSecurity
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.security.CodeSigner;
+import java.security.cert.Certificate;
+import java.util.Arrays;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.zip.ZipFile;
+import jdk.Version;
+
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class MultiReleaseJarSecurity {
+
+    static final int MAJOR_VERSION = Version.current().major();
+
+    String userdir = System.getProperty("user.dir",".");
+    File multirelease = new File(userdir, "multi-release.jar");
+    File signedmultirelease = new File(userdir, "signed-multi-release.jar");
+
+    @BeforeClass
+    public void initialize() throws Exception {
+        CreateMultiReleaseTestJars creator =  new CreateMultiReleaseTestJars();
+        creator.compileEntries();
+        creator.buildMultiReleaseJar();
+        creator.buildSignedMultiReleaseJar();
+    }
+
+    @AfterClass
+    public void close() throws IOException {
+        Files.delete(multirelease.toPath());
+        Files.delete(signedmultirelease.toPath());
+    }
+
+    @Test
+    public void testCertsAndSigners() throws IOException {
+        try (JarFile jf = new JarFile(signedmultirelease, true, ZipFile.OPEN_READ, JarFile.Release.RUNTIME)) {
+            CertsAndSigners vcas = new CertsAndSigners(jf, jf.getJarEntry("version/Version.class"));
+            CertsAndSigners rcas = new CertsAndSigners(jf, jf.getJarEntry("META-INF/versions/" + MAJOR_VERSION + "/version/Version.class"));
+            Assert.assertTrue(Arrays.equals(rcas.getCertificates(), vcas.getCertificates()));
+            Assert.assertTrue(Arrays.equals(rcas.getCodeSigners(), vcas.getCodeSigners()));
+        }
+    }
+
+    private static class CertsAndSigners {
+        final private JarFile jf;
+        final private JarEntry je;
+        private boolean readComplete;
+
+        CertsAndSigners(JarFile jf, JarEntry je) {
+            this.jf = jf;
+            this.je = je;
+        }
+
+        Certificate[] getCertificates() throws IOException {
+            readEntry();
+            return je.getCertificates();
+        }
+
+        CodeSigner[] getCodeSigners() throws IOException {
+            readEntry();
+            return je.getCodeSigners();
+        }
+
+        private void readEntry() throws IOException {
+            if (!readComplete) {
+                try (InputStream is = jf.getInputStream(je)) {
+                    is.readAllBytes();
+                }
+                readComplete = true;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/jar/JarFile/mrjar/TEST.properties	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,3 @@
+modules = \
+    jdk.compiler \
+    jdk.jartool
--- a/jdk/test/java/util/regex/RegExTest.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/util/regex/RegExTest.java	Thu May 12 11:03:07 2016 -0700
@@ -33,6 +33,9 @@
  * 6350801 6676425 6878475 6919132 6931676 6948903 6990617 7014645 7039066
  * 7067045 7014640 7189363 8007395 8013252 8013254 8012646 8023647 6559590
  * 8027645 8035076 8039124 8035975 8074678 6854417 8143854 8147531 7071819
+ * 8151481 4867170 7080302 6728861 6995635 6736245 4916384
+ * 6328855 6192895 6345469 6988218 6693451 7006761 8140212
+ *
  * @library /lib/testlibrary
  * @build jdk.testlibrary.*
  * @run main RegExTest
@@ -162,6 +165,7 @@
         patternAsPredicate();
         invalidFlags();
         grapheme();
+        expoBacktracking();
 
         if (failure) {
             throw new
@@ -2659,51 +2663,101 @@
         check(p, "test\u00e4\u0323\u0300", true);
         check(p, "test\u00e4\u0300\u0323", true);
 
-        /*
-         * The following canonical equivalence tests don't work. Bug id: 4916384.
-         *
+        Object[][] data = new Object[][] {
+
+        // JDK-4867170
+        { "[\u1f80-\u1f82]", "ab\u1f80cd",             "f", true },
+        { "[\u1f80-\u1f82]", "ab\u1f81cd",             "f", true },
+        { "[\u1f80-\u1f82]", "ab\u1f82cd",             "f", true },
+        { "[\u1f80-\u1f82]", "ab\u03b1\u0314\u0345cd", "f", true },
+        { "[\u1f80-\u1f82]", "ab\u03b1\u0345\u0314cd", "f", true },
+        { "[\u1f80-\u1f82]", "ab\u1f01\u0345cd",       "f", true },
+        { "[\u1f80-\u1f82]", "ab\u1f00\u0345cd",       "f", true },
+
+        { "\\p{IsGreek}",    "ab\u1f80cd",             "f", true },
+        { "\\p{IsGreek}",    "ab\u1f81cd",             "f", true },
+        { "\\p{IsGreek}",    "ab\u1f82cd",             "f", true },
+        { "\\p{IsGreek}",    "ab\u03b1\u0314\u0345cd", "f", true },
+        { "\\p{IsGreek}",    "ab\u1f01\u0345cd",       "f", true },
+
+        // backtracking, force to match "\u1f80", instead of \u1f82"
+        { "ab\\p{IsGreek}\u0300cd", "ab\u03b1\u0313\u0345\u0300cd", "m", true },
+
+        { "[\\p{IsGreek}]",  "\u03b1\u0314\u0345",     "m", true },
+        { "\\p{IsGreek}",    "\u03b1\u0314\u0345",     "m", true },
+
+        { "[^\u1f80-\u1f82]","\u1f81",                 "m", false },
+        { "[^\u1f80-\u1f82]","\u03b1\u0314\u0345",     "m", false },
+        { "[^\u1f01\u0345]", "\u1f81",                 "f", false },
+
+        { "[^\u1f81]+",      "\u1f80\u1f82",           "f", true },
+        { "[\u1f80]",        "ab\u1f80cd",             "f", true },
+        { "\u1f80",          "ab\u1f80cd",             "f", true },
+        { "\u1f00\u0345\u0300",  "\u1f82", "m", true },
+        { "\u1f80",          "-\u1f00\u0345\u0300-",   "f", true },
+        { "\u1f82",          "\u1f00\u0345\u0300",     "m", true },
+        { "\u1f82",          "\u1f80\u0300",           "m", true },
+
+        // JDK-7080302       # compile failed
+        { "a(\u0041\u0301\u0328)", "a\u0041\u0301\u0328", "m", true},
+
+        // JDK-6728861, same cause as above one
+        { "\u00e9\u00e9n", "e\u0301e\u0301n", "m", true},
+
+        // JDK-6995635
+        { "(\u00e9)", "e\u0301", "m", true },
+
+        // JDK-6736245
+        // intereting special case, nfc(u2add+u0338) -> u2add+u0338) NOT u2adc
+        { "\u2ADC", "\u2ADC", "m", true},          // NFC
+        { "\u2ADC", "\u2ADD\u0338", "m", true},    // NFD
+
+        //  4916384.
+        // Decomposed hangul (jamos) works inside clazz
+        { "[\u1100\u1161]", "\u1100\u1161", "m", true},
+        { "[\u1100\u1161]", "\uac00", "m", true},
+
+        { "[\uac00]", "\u1100\u1161", "m", true},
+        { "[\uac00]", "\uac00", "m", true},
+
         // Decomposed hangul (jamos)
-        p = Pattern.compile("\u1100\u1161", Pattern.CANON_EQ);
-        m = p.matcher("\u1100\u1161");
-        if (!m.matches())
-            failCount++;
-
-        m.reset("\uac00");
-        if (!m.matches())
-            failCount++;
+        { "\u1100\u1161", "\u1100\u1161", "m", true},
+        { "\u1100\u1161", "\uac00", "m", true},
 
         // Composed hangul
-        p = Pattern.compile("\uac00", Pattern.CANON_EQ);
-        m = p.matcher("\u1100\u1161");
-        if (!m.matches())
-            failCount++;
-
-        m.reset("\uac00");
-        if (!m.matches())
-            failCount++;
+        { "\uac00",  "\u1100\u1161", "m", true },
+        { "\uac00",  "\uac00", "m", true },
+
+        /* Need a NFDSlice to nfd the source to solve this issue
+           u+1d1c0 -> nfd: <u+1d1ba><u+1d165><u+1d16f>  -> nfc: <u+1d1ba><u+1d165><u+1d16f>
+           u+1d1bc -> nfd: <u+1d1ba><u+1d165>           -> nfc: <u+1d1ba><u+1d165>
+           <u+1d1bc><u+1d16f> -> nfd: <u+1d1ba><u+1d165><u+1d16f> -> nfc: <u+1d1ba><u+1d165><u+1d16f>
 
         // Decomposed supplementary outside char classes
-        p = Pattern.compile("test\ud834\uddbc\ud834\udd6f", Pattern.CANON_EQ);
-        m = p.matcher("test\ud834\uddc0");
-        if (!m.matches())
-            failCount++;
-
-        m.reset("test\ud834\uddbc\ud834\udd6f");
-        if (!m.matches())
-            failCount++;
-
+        // { "test\ud834\uddbc\ud834\udd6f", "test\ud834\uddc0", "m", true },
         // Composed supplementary outside char classes
-        p = Pattern.compile("test\ud834\uddc0", Pattern.CANON_EQ);
-        m.reset("test\ud834\uddbc\ud834\udd6f");
-        if (!m.matches())
-            failCount++;
-
-        m = p.matcher("test\ud834\uddc0");
-        if (!m.matches())
-            failCount++;
-
+        // { "test\ud834\uddc0", "test\ud834\uddbc\ud834\udd6f", "m", true },
         */
-
+        { "test\ud834\uddbc\ud834\udd6f", "test\ud834\uddbc\ud834\udd6f", "m", true },
+        { "test\ud834\uddc0",             "test\ud834\uddbc\ud834\udd6f", "m", true },
+
+        { "test\ud834\uddc0",             "test\ud834\uddc0",             "m", true },
+        { "test\ud834\uddbc\ud834\udd6f", "test\ud834\uddc0",             "m", true },
+        };
+
+        int failCount = 0;
+        for (Object[] d : data) {
+            String pn = (String)d[0];
+            String tt = (String)d[1];
+            boolean isFind = "f".equals(((String)d[2]));
+            boolean expected = (boolean)d[3];
+            boolean ret = isFind ? Pattern.compile(pn, Pattern.CANON_EQ).matcher(tt).find()
+                                 : Pattern.compile(pn, Pattern.CANON_EQ).matcher(tt).matches();
+            if (ret != expected) {
+                failCount++;
+                continue;
+            }
+        }
         report("Canonical Equivalence");
     }
 
@@ -3846,7 +3900,6 @@
         if (!patternString.startsWith("'")) {
             return Pattern.compile(patternString);
         }
-
         int break1 = patternString.lastIndexOf("'");
         String flagString = patternString.substring(
                                           break1+1, patternString.length());
@@ -4092,10 +4145,11 @@
         report("NamedGroupCapture");
     }
 
-    // This is for bug 6969132
+    // This is for bug 6919132
     private static void nonBmpClassComplementTest() throws Exception {
         Pattern p = Pattern.compile("\\P{Lu}");
         Matcher m = p.matcher(new String(new int[] {0x1d400}, 0, 1));
+
         if (m.find() && m.start() == 1)
             failCount++;
 
@@ -4113,6 +4167,11 @@
         if (m.find() && m.start() == 1)
             failCount++;
 
+        p = Pattern.compile("\\P{sc=GRANTHA}");
+        m = p.matcher(new String(new int[] {0x11350}, 0, 1));
+        if (m.find() && m.start() == 1)
+            failCount++;
+
         report("NonBmpClassComplement");
     }
 
@@ -4662,4 +4721,92 @@
             failCount++;
         report("Unicode extended grapheme cluster");
     }
+
+    // hangup/timeout if go into exponential backtracking
+    private static void expoBacktracking() throws Exception {
+
+        Object[][] patternMatchers = {
+            // 6328855
+            { "(.*\n*)*",
+              "this little fine string lets\r\njava.lang.String.matches\r\ncrash\r\n(We don't know why but adding \r* to the regex makes it work again)",
+              false },
+            // 6192895
+            { " *([a-zA-Z0-9/\\-\\?:\\(\\)\\.,'\\+\\{\\}]+ *)+",
+              "Hello World this is a test this is a test this is a test A",
+              true },
+            { " *([a-zA-Z0-9/\\-\\?:\\(\\)\\.,'\\+\\{\\}]+ *)+",
+              "Hello World this is a test this is a test this is a test \u4e00 ",
+              false },
+            { " *([a-z0-9]+ *)+",
+              "hello world this is a test this is a test this is a test A",
+              false },
+            // 4771934 [FIXED] #5013651?
+            { "^(\\w+([\\.-]?\\w+)*@\\w+([\\.-]?\\w+)*(\\.\\w{2,4})+[,;]?)+$",
+              "abc@efg.abc,efg@abc.abc,abc@xyz.mno;abc@sdfsd.com",
+              true },
+            // 4866249 [FIXED]
+            { "<\\s*" + "(meta|META)" + "(\\s|[^>])+" + "(CHARSET|charset)=" + "(\\s|[^>])+>",
+              "<META http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-5\">",
+              true },
+            { "^(\\w+([\\.-]?\\w+)*@\\w+([\\.-]?\\w+)*(\\.\\w{2,4})+[,;]?)+$",
+              "abc@efg.abc,efg@abc.abc,abc@xyz.mno;sdfsd.com",
+              false },
+            // 6345469
+            { "((<[^>]+>)?(((\\s)?)*(\\&nbsp;)?)*((\\s)?)*)+",
+              "&nbsp;&nbsp; < br/> &nbsp; < / p> <p> <html> <adfasfdasdf>&nbsp; </p>",
+              true }, // --> matched
+            { "((<[^>]+>)?(((\\s)?)*(\\&nbsp;)?)*((\\s)?)*)+",
+              "&nbsp;&nbsp; < br/> &nbsp; < / p> <p> <html> <adfasfdasdf>&nbsp; p </p>",
+              false },
+            // 5026912
+            { "^\\s*" + "(\\w|\\d|[\\xC0-\\xFF]|/)+" + "\\s+|$",
+              "156580451111112225588087755221111111566969655555555",
+              false},
+            // 6988218
+            { "^([+-]?((0[xX](\\p{XDigit}+))|(((\\p{Digit}+)(\\.)?((\\p{Digit}+)?)([eE][+-]?(\\p{Digit}+))?)|(\\.((\\p{Digit}+))([eE][+-]?(\\p{Digit}+))?)))|[n|N]?'([^']*(?:'')*[^']*)*')",
+              "'%)) order by ANGEBOT.ID",
+              false},    // find
+            // 6693451
+            { "^(\\s*foo\\s*)*$",
+              "foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo",
+              true },
+            { "^(\\s*foo\\s*)*$",
+              "foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo fo",
+              false
+            },
+            // 7006761
+            { "(([0-9A-Z]+)([_]?+)*)*", "FOOOOO_BAAAR_FOOOOOOOOO_BA_", true},
+            { "(([0-9A-Z]+)([_]?+)*)*", "FOOOOO_BAAAR_FOOOOOOOOO_BA_ ", false},
+            // 8140212
+            { "(?<before>.*)\\{(?<reflection>\\w+):(?<innerMethod>\\w+(\\.?\\w+(\\(((?<args>(('[^']*')|((/|\\w)+))(,(('[^']*')|((/|\\w)+)))*))?\\))?)*)\\}(?<after>.*)",
+              "{CeGlobal:getSodCutoff.getGui.getAmqp.getSimpleModeEnabled()",
+              false
+            },
+            { "^(a+)+$", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", true},
+            { "^(a+)+$", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!", false},
+
+            { "(x+)*y",  "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxy", true },
+            { "(x+)*y",  "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxz", false},
+
+            { "(x+x+)+y", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxy", true},
+            { "(x+x+)+y", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxz", false},
+
+            { "(([0-9A-Z]+)([_]?+)*)*", "--------------------------------------", false},
+
+            /* not fixed
+            //8132141   --->    second level exponential backtracking
+            { "(h|h|ih(((i|a|c|c|a|i|i|j|b|a|i|b|a|a|j))+h)ahbfhba|c|i)*",
+              "hchcchicihcchciiicichhcichcihcchiihichiciiiihhcchicchhcihchcihiihciichhccciccichcichiihcchcihhicchcciicchcccihiiihhihihihichicihhcciccchihhhcchichchciihiicihciihcccciciccicciiiiiiiiicihhhiiiihchccchchhhhiiihchihcccchhhiiiiiiiicicichicihcciciihichhhhchihciiihhiccccccciciihhichiccchhicchicihihccichicciihcichccihhiciccccccccichhhhihihhcchchihihiihhihihihicichihiiiihhhhihhhchhichiicihhiiiiihchccccchichci" },
+            */
+        };
+
+        for (Object[] pm : patternMatchers) {
+            String p = (String)pm[0];
+            String s = (String)pm[1];
+            boolean r = (Boolean)pm[2];
+            if (r != Pattern.compile(p).matcher(s).matches()) {
+                failCount++;
+            }
+        }
+    }
 }
--- a/jdk/test/java/util/regex/TestCases.txt	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/java/util/regex/TestCases.txt	Thu May 12 11:03:07 2016 -0700
@@ -139,6 +139,71 @@
 aaabbbcccdefg
 true defg 0
 
+// Negation with nested char class and intersection
+[^[c]]
+c
+false 0
+
+[^[a-z]]
+e
+false 0
+
+[^[a-z][A-Z]]
+E
+false 0
+
+[^a-d[0-9][m-p]]
+e
+true e 0
+
+[^a-d[0-9][m-p]]
+8
+false 0
+
+[^[a-c]&&[d-f]]
+z
+true z 0
+
+[^a-c&&d-f]
+a
+true a 0
+
+[^a-m&&m-z]
+m
+false 0
+
+[^a-m&&m-z&&a-c]
+m
+true m 0
+
+[^a-cd-f&&[d-f]]
+c
+true c 0
+
+[^[a-c][d-f]&&abc]
+a
+false 0
+
+[^[a-c][d-f]&&abc]
+d
+true d 0
+
+[^[a-c][d-f]&&abc[def]]
+a
+false 0
+
+[^[a-c][d-f]&&abc[def]]
+e
+false 0
+
+[^[a-c]&&[b-d]&&[c-e]]
+a
+true a 0
+
+[^[a-c]&&[b-d]&&[c-e]]
+c
+false 0
+
 // Making sure a ^ not in first position matches literal ^
 [abc^b]
 b
--- a/jdk/test/lib/testlibrary/java/util/jar/Compiler.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/lib/testlibrary/java/util/jar/Compiler.java	Thu May 12 11:03:07 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
@@ -44,7 +44,7 @@
         // so do it the old fashioned way
         // options = Arrays.asList("-release", String.valueOf(release));
         String target = String.valueOf(release);
-        options = Arrays.asList("-source", target, "-target", target);
+        options = Arrays.asList("-source", target, "-target", target, "-classpath", "");
         return this;
     }
 
@@ -53,7 +53,9 @@
         Map<String,ClassFileObject> cfos = createClassFileObjects();
         JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
         JavaFileManager jfm = new CustomFileManager(jc.getStandardFileManager(null, null, null), cfos);
-        jc.getTask(null, jfm, null, options, null, cunits).call();
+        if(!jc.getTask(null, jfm, null, options, null, cunits).call()) {
+            throw new RuntimeException("Compilation failed");
+        }
         return createOutput(cfos);
     }
 
--- a/jdk/test/sun/rmi/transport/proxy/DisableHttpDefaultValue.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please 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 8023862
- * @summary Verify that the default value of the java.rmi.server.disableHttp
- *          has been changed from false to true.
- * @modules java.rmi/sun.rmi.transport.proxy
- * @compile -XDignore.symbol.file DisableHttpDefaultValue.java
- *
- * @run main/othervm                                     DisableHttpDefaultValue true
- * @run main/othervm -Djava.rmi.server.disableHttp       DisableHttpDefaultValue false
- * @run main/othervm -Djava.rmi.server.disableHttp=false DisableHttpDefaultValue false
- * @run main/othervm -Djava.rmi.server.disableHttp=xyzzy DisableHttpDefaultValue false
- * @run main/othervm -Djava.rmi.server.disableHttp=true  DisableHttpDefaultValue true
- */
-
-import sun.rmi.transport.proxy.RMIMasterSocketFactory;
-
-public class DisableHttpDefaultValue {
-    /**
-     * Subclass RMIMasterSocketFactory to get access to
-     * protected field altFactoryList. This list has a
-     * zero size if proxying is disabled.
-     */
-    static class SocketFactory extends RMIMasterSocketFactory {
-        boolean proxyDisabled() {
-            return altFactoryList.size() == 0;
-        }
-    }
-
-    /**
-     * Takes a single arg, which is the expected boolean value of
-     * java.rmi.server.disableHttp.
-     */
-    public static void main(String[] args) throws Exception {
-        // Force there to be a proxy host, so that we are able to
-        // tell whether proxying is enabled or disabled.
-        System.setProperty("http.proxyHost", "proxy.example.com");
-
-        String propval = System.getProperty("java.rmi.server.disableHttp");
-        String propdisp = (propval == null) ? "null" : ("\"" + propval + "\"");
-        boolean expected = Boolean.parseBoolean(args[0]);
-        boolean actual = new SocketFactory().proxyDisabled();
-        System.out.printf("### prop=%s exp=%s act=%s%n", propdisp, expected, actual);
-        if (expected != actual)
-            throw new AssertionError();
-    }
-}
--- a/jdk/test/sun/rmi/transport/proxy/EagerHttpFallback.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2002, 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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please 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 4290727
- * @summary Verify that ConnectException will trigger HTTP fallback if
- *          sun.rmi.transport.proxy.eagerHttpFallback system property is set.
- *
- * @library ../../../../java/rmi/testlibrary
- * @modules java.rmi/sun.rmi.registry
- *          java.rmi/sun.rmi.server
- *          java.rmi/sun.rmi.transport
- *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary
- * @run main/othervm EagerHttpFallback
- */
-
-import java.rmi.*;
-import java.rmi.registry.*;
-
-public class EagerHttpFallback {
-
-    static final int INITIAL_PORT = TestLibrary.getUnusedRandomPort();
-    static final int FALLBACK_PORT = TestLibrary.getUnusedRandomPort();
-
-    public static void main(String[] args) throws Exception {
-        System.setProperty("http.proxyHost", "127.0.0.1");
-        System.setProperty("http.proxyPort", Integer.toString(FALLBACK_PORT));
-        System.setProperty("sun.rmi.transport.proxy.eagerHttpFallback",
-                           "true");
-        LocateRegistry.createRegistry(FALLBACK_PORT);
-
-        /*
-         * The call below should trigger a ConnectException in the
-         * RMIMasterSocketFactory when it attempts a direct connection to
-         * INITIAL_PORT, which no one is listening on.  Since
-         * eagerHttpFallback is set, this ConnectException should trigger HTTP
-         * fallback, which will send a call through the HTTP proxy, which is
-         * configured to be localhost with a port behind which a registry is
-         * listening--so if fallback works properly, the list() call should
-         * succeed.
-         */
-        try {
-            LocateRegistry.getRegistry(INITIAL_PORT).list();
-        } catch (Exception e) {
-            System.err.println(
-                "call on registry stub with port " + INITIAL_PORT +
-                "did not successfully perform HTTP fallback to " +
-                FALLBACK_PORT);
-            throw e;
-        }
-    }
-}
--- a/jdk/test/sun/rmi/transport/tcp/blockAccept/BlockAcceptTest.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,175 +0,0 @@
-/*
- * Copyright (c) 1999, 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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please 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 4203167
- *
- * @summary RMI blocks in HttpAwareServerSocket.accept() if you telnet to it
- * @author Adrian Colley
- *
- * @library ../../../../../java/rmi/testlibrary
- * @modules java.rmi/sun.rmi.transport.proxy
- * @build TestIface TestImpl TestImpl_Stub
- * @run main/othervm/policy=security.policy/timeout=60 BlockAcceptTest
- */
-
-/* This test attempts to stymie the RMI accept loop.  The accept loop in
- * RMI endlessly accepts a connection, spawns a thread for it, and repeats.
- * The accept() call can be replaced by a user-supplied library which
- * might foolishly block indefinitely in its accept() method, which would
- * prevent RMI from accepting other connections on that socket.
- *
- * Unfortunately, HttpAwareServerSocket (default server socket) is/was such
- * a foolish thing.  It reads 4 bytes to see if they're "POST" before
- * returning.  The bug fix is to move the HTTP stuff into the mainloop,
- * which has the side effect of enabling it for non-default socketfactories.
- *
- * This test:
- * 1. Creates an object and exports it.
- * 2. Connects to the listening RMI port and sends nothing, to hold it up.
- * 3. Makes a regular call, using HTTP tunnelling.
- * 4. Fails to deadlock, thereby passing the test.
- *
- * Some runtime dependencies I'm trying to eliminate:
- * 1. We don't know the port number until after exporting the object, but
- *    have to set it in http.proxyPort somehow.  Hopefully http.proxyPort
- *    isn't read too soon or this test will fail with a ConnectException.
- */
-
-import java.rmi.*;
-import java.rmi.server.RMISocketFactory;
-import java.io.*;
-import java.net.*;
-
-import sun.rmi.transport.proxy.RMIMasterSocketFactory;
-import sun.rmi.transport.proxy.RMIHttpToPortSocketFactory;
-
-public class BlockAcceptTest
-{
-    public static void main(String[] args)
-        throws Exception
-    {
-        // Make trouble for ourselves
-        if (System.getSecurityManager() == null)
-            System.setSecurityManager(new RMISecurityManager());
-
-        // HTTP direct to the server port
-        System.setProperty("http.proxyHost", "127.0.0.1");
-
-        // Set the socket factory.
-        System.err.println("(installing HTTP-out socket factory)");
-        HttpOutFactory fac = new HttpOutFactory();
-        RMISocketFactory.setSocketFactory(fac);
-
-        // Create remote object
-        TestImpl impl = new TestImpl();
-
-        // Export and get which port.
-        System.err.println("(exporting remote object)");
-        TestIface stub = impl.export();
-        try {
-            int port = fac.whichPort();
-
-            // Sanity
-            if (port == 0)
-                throw new Error("TEST FAILED: export didn't reserve a port(?)");
-
-            // Set the HTTP port, at last.
-            System.setProperty("http.proxyPort", port+"");
-
-            // Now, connect to that port
-            //Thread.sleep(2000);
-            System.err.println("(connecting to listening port on 127.0.0.1:" +
-                               port + ")");
-            Socket DoS = new Socket("127.0.0.1", port);
-            // we hold the connection open until done with the test.
-
-            // The test itself: make a remote call and see if it's blocked or
-            // if it works
-            //Thread.sleep(2000);
-            System.err.println("(making RMI-through-HTTP call)");
-            System.err.println("(typical test failure deadlocks here)");
-            String result = stub.testCall("dummy load");
-
-            System.err.println(" => " + result);
-            if (!("OK".equals(result)))
-                throw new Error("TEST FAILED: result not OK");
-            System.err.println("Test passed.");
-
-            // Clean up, including writing a byte to that connection just in
-            // case an optimizer thought of optimizing it out of existence
-            try {
-                DoS.getOutputStream().write(0);
-                DoS.getOutputStream().close();
-            } catch (Throwable apathy) {
-            }
-
-        } finally {
-            try {
-                impl.unexport();
-            } catch (Throwable unmatter) {
-            }
-        }
-
-        // Should exit here
-    }
-
-    private static class HttpOutFactory
-        extends RMISocketFactory
-    {
-        private int servport = 0;
-
-        public Socket createSocket(String h, int p)
-            throws IOException
-        {
-            return ((new RMIHttpToPortSocketFactory()).createSocket(h, p));
-        }
-
-        /** Create a server socket and remember which port it's on.
-         * Aborts if createServerSocket(0) is called twice, because then
-         * it doesn't know whether to remember the first or second port.
-         */
-        public ServerSocket createServerSocket(int p)
-            throws IOException
-        {
-            ServerSocket ss;
-            ss = (new RMIMasterSocketFactory()).createServerSocket(p);
-            if (p == 0) {
-                if (servport != 0) {
-                    System.err.println("TEST FAILED: " +
-                                       "Duplicate createServerSocket(0)");
-                    throw new Error("Test aborted (createServerSocket)");
-                }
-                servport = ss.getLocalPort();
-            }
-            return (ss);
-        }
-
-        /** Return which port was reserved by createServerSocket(0).
-         * If the return value was 0, createServerSocket(0) wasn't called.
-         */
-        public int whichPort() {
-            return (servport);
-        }
-    } // end class HttpOutFactory
-}
--- a/jdk/test/sun/rmi/transport/tcp/blockAccept/TestIface.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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.rmi.*;
-
-public interface TestIface
-    extends Remote
-{
-    public String testCall(String ign)
-        throws RemoteException;
-}
--- a/jdk/test/sun/rmi/transport/tcp/blockAccept/TestImpl.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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.rmi.*;
-import java.rmi.server.*;
-
-public class TestImpl
-    extends Object
-    implements TestIface
-{
-    public TestImpl() {
-    }
-
-    public TestIface export()
-        throws RemoteException
-    {
-        return (TestIface)UnicastRemoteObject.exportObject(this);
-    }
-
-    public void unexport()
-        throws NoSuchObjectException
-    {
-        UnicastRemoteObject.unexportObject(this, true);
-    }
-
-    public String testCall(String ign) {
-        return ("OK");
-    }
-}
--- a/jdk/test/sun/rmi/transport/tcp/blockAccept/TestImpl_Stub.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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.
- */
-
-// Stub class generated by rmic, do not edit.
-// Contents subject to change without notice.
-
-public final class TestImpl_Stub
-    extends java.rmi.server.RemoteStub
-    implements TestIface
-{
-    private static final long serialVersionUID = 2;
-
-    private static java.lang.reflect.Method $method_testCall_0;
-
-    static {
-        try {
-            $method_testCall_0 = TestIface.class.getMethod("testCall", new java.lang.Class[] {java.lang.String.class});
-        } catch (java.lang.NoSuchMethodException e) {
-            throw new java.lang.NoSuchMethodError(
-                "stub class initialization failed");
-        }
-    }
-
-    // constructors
-    public TestImpl_Stub(java.rmi.server.RemoteRef ref) {
-        super(ref);
-    }
-
-    // methods from remote interfaces
-
-    // implementation of testCall(String)
-    public java.lang.String testCall(java.lang.String $param_String_1)
-        throws java.rmi.RemoteException
-    {
-        try {
-            Object $result = ref.invoke(this, $method_testCall_0, new java.lang.Object[] {$param_String_1}, -4495720265115653109L);
-            return ((java.lang.String) $result);
-        } catch (java.lang.RuntimeException e) {
-            throw e;
-        } catch (java.rmi.RemoteException e) {
-            throw e;
-        } catch (java.lang.Exception e) {
-            throw new java.rmi.UnexpectedException("undeclared checked exception", e);
-        }
-    }
-}
--- a/jdk/test/sun/rmi/transport/tcp/blockAccept/security.policy	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-grant {
-    // Take this out once we can specify -Djava.security.debug on
-    // the run line and figure out what else is needed
-    permission java.security.AllPermission;
-
-    permission java.net.SocketPermission "*:1024-65535", "connect,listen";
-    permission java.util.PropertyPermission "http.proxyHost", "write";
-    permission java.util.PropertyPermission "http.proxyPort", "write";
-    permission java.lang.RuntimePermission "setFactory";
-};
--- a/jdk/test/sun/security/pkcs11/KeyAgreement/SupportedDHKeys.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/sun/security/pkcs11/KeyAgreement/SupportedDHKeys.java	Thu May 12 11:03:07 2016 -0700
@@ -71,18 +71,19 @@
                     KeyPairGenerator.getInstance("DiffieHellman", provider);
             kpg.initialize(keySize.primeSize);
             KeyPair kp = kpg.generateKeyPair();
-            checkKeyPair(kp, keySize.primeSize);
+            checkKeyPair(kp, keySize.primeSize, provider);
 
             DHPublicKey publicKey = (DHPublicKey)kp.getPublic();
             BigInteger p = publicKey.getParams().getP();
             BigInteger g = publicKey.getParams().getG();
             kpg.initialize(new DHParameterSpec(p, g));
             kp = kpg.generateKeyPair();
-            checkKeyPair(kp, keySize.primeSize);
+            checkKeyPair(kp, keySize.primeSize, provider);
         }
     }
 
-    private static void checkKeyPair(KeyPair kp, int pSize) throws Exception {
+    private static void checkKeyPair(KeyPair kp, int pSize,
+                Provider provider) throws Exception {
 
         DHPrivateKey privateKey = (DHPrivateKey)kp.getPrivate();
         BigInteger p = privateKey.getParams().getP();
@@ -106,18 +107,21 @@
         BigInteger leftOpen = BigInteger.ONE;
         BigInteger rightOpen = p.subtract(BigInteger.ONE);
 
-        BigInteger x = privateKey.getX();
-        if ((x.compareTo(leftOpen) <= 0) ||
-                (x.compareTo(rightOpen) >= 0)) {
-            throw new Exception(
-                "X outside range [2, p - 2]:  x: " + x + " p: " + p);
+        // ignore the private key range checking on Solaris at present
+        if (!provider.getName().equals("SunPKCS11-Solaris")) {
+            BigInteger x = privateKey.getX();
+            if ((x.compareTo(leftOpen) <= 0) ||
+                    (x.compareTo(rightOpen) >= 0)) {
+                throw new Exception(
+                    "X outside range [2, p - 2]:  x: " + x + " p: " + p);
+            }
         }
 
         BigInteger y = publicKey.getY();
         if ((y.compareTo(leftOpen) <= 0) ||
                 (y.compareTo(rightOpen) >= 0)) {
             throw new Exception(
-                "Y outside range [2, p - 2]:  x: " + x + " p: " + p);
+                "Y outside range [2, p - 2]:  y: " + y + " p: " + p);
         }
     }
 
--- a/jdk/test/sun/security/provider/SecureRandom/DRBGAlg.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/sun/security/provider/SecureRandom/DRBGAlg.java	Thu May 12 11:03:07 2016 -0700
@@ -47,7 +47,6 @@
 
         check(null, "Hash_DRBG", "SHA-256", "reseed_only", ",128");
         check("", "Hash_DRBG", "SHA-256", "reseed_only", ",128");
-        check("sha-1", "Hash_DRBG", "SHA-1", "reseed_only", ",128");
         check("sha-256", "Hash_DRBG", "SHA-256", "reseed_only", ",128");
         check("SHA-3");
         check("hash_drbg", "Hash_DRBG", "SHA-256", "reseed_only", ",128");
@@ -61,20 +60,20 @@
                 "Hash_DRBG", "SHA-512", "pr_and_reseed", ",192");
 
         check("Hash_DRBG,Hmac_DRBG");
-        check("SHA-1,SHA-256");
+        check("SHA-224,SHA-256");
         check("128,256");
         check("none,reseed_only");
         check("use_df,no_df");
-        check("Hash_DRBG,,SHA-1");
+        check("Hash_DRBG,,SHA-256");
 
         check(null, DrbgParameters.instantiation(112, PR_AND_RESEED, null),
                 "Hash_DRBG", "SHA-256", "pr_and_reseed", ",112");
         check(null, DrbgParameters.instantiation(256, PR_AND_RESEED, null),
                 "Hash_DRBG", "SHA-256", "pr_and_reseed", ",256");
         check(null, DrbgParameters.instantiation(384, PR_AND_RESEED, null));
-        check("sha-1", DrbgParameters.instantiation(112, PR_AND_RESEED, null),
-                "Hash_DRBG", "SHA-1", "pr_and_reseed", ",112");
-        check("sha-1", DrbgParameters.instantiation(192, PR_AND_RESEED, null));
+        check("sha-224", DrbgParameters.instantiation(112, PR_AND_RESEED, null),
+                "Hash_DRBG", "SHA-224", "pr_and_reseed", ",112");
+        check("sha-224", DrbgParameters.instantiation(256, PR_AND_RESEED, null));
         check("hash_drbg,sha-512,Pr_and_Reseed,192",
                 DrbgParameters.instantiation(112, NONE, null),
                 "Hash_DRBG", "SHA-512", "reseed_only", ",112");
@@ -86,23 +85,23 @@
                 DrbgParameters.instantiation(192, PR_AND_RESEED, null),
                 "Hash_DRBG", "SHA-256", "pr_and_reseed", ",192");
 
-        check("hash_drbg,sha-1", new MoreDrbgParameters(
+        check("hash_drbg,sha-224", new MoreDrbgParameters(
                     null, null, "sha-512", null, false,
                     DrbgParameters.instantiation(-1, NONE, null)),
                 "Hash_DRBG", "SHA-512");
-        check("hash_drbg,sha-1", new MoreDrbgParameters(
+        check("hash_drbg,sha-224", new MoreDrbgParameters(
                     null, null, null, null, false,
                     DrbgParameters.instantiation(-1, NONE, null)),
-                "Hash_DRBG", "SHA-1");
+                "Hash_DRBG", "SHA-224");
         check("hash_drbg", new MoreDrbgParameters(
                     null, "hmac_drbg", null, null, false,
                     DrbgParameters.instantiation(-1, NONE, null)),
                 "HMAC_DRBG", "SHA-256");
 
-        check("hash_drbg,sha-1", new MoreDrbgParameters(
+        check("hash_drbg,sha-224", new MoreDrbgParameters(
                     null, null, "sha-3", null, false,
                     DrbgParameters.instantiation(-1, NONE, null)));
-        check("hash_drbg,sha-1", new MoreDrbgParameters(
+        check("hash_drbg,sha-224", new MoreDrbgParameters(
                     null, "Unknown_DRBG", null, null, false,
                     DrbgParameters.instantiation(-1, NONE, null)));
     }
--- a/jdk/test/sun/security/provider/SecureRandom/DrbgCavp.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/sun/security/provider/SecureRandom/DrbgCavp.java	Thu May 12 11:03:07 2016 -0700
@@ -278,10 +278,13 @@
                                                     ps)),
                                     "SUN");
                         } catch (NoSuchAlgorithmException iae) {
+                            // We don't support SHA-1 and 3KeyTDEA. AES-192 or
                             // AES-256 might not be available. This is OK.
-                            if ((algorithm.equals("AES-192")
+                            if (algorithm.equals("SHA-1") ||
+                                    algorithm.equals("3KeyTDEA") ||
+                                    ((algorithm.equals("AES-192")
                                     || algorithm.equals("AES-256"))
-                                    && AES_LIMIT == 128) {
+                                    && AES_LIMIT == 128)) {
                                 hd = null;
                             } else {
                                 throw iae;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/provider/SecureRandom/SHA1PRNGReseed.java	Thu May 12 11:03:07 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.
+ */
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.security.SecureRandom;
+
+/**
+ * @test
+ * @bug 8154523
+ * @summary SHA1PRNG output should change after setSeed
+ */
+public class SHA1PRNGReseed {
+
+    public static void main(String[] args) throws Exception {
+        SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
+        sr.setSeed(0);
+        sr.nextInt();
+
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        new ObjectOutputStream(bout).writeObject(sr);
+
+        SecureRandom sr2 = (SecureRandom) new ObjectInputStream(
+                new ByteArrayInputStream(bout.toByteArray())).readObject();
+
+        int i1 = sr.nextInt();
+        sr2.setSeed(1);
+        int i2 = sr2.nextInt();
+
+        if (i1 == i2) {
+            throw new Exception("output should not be the same");
+        }
+    }
+}
--- a/jdk/test/tools/jlink/JLinkTest.java	Thu May 12 20:43:37 2016 +0400
+++ b/jdk/test/tools/jlink/JLinkTest.java	Thu May 12 11:03:07 2016 -0700
@@ -162,7 +162,7 @@
         {
             String[] userOptions2 = {"--compress=2:compress-filter=^/java.base/*",
                 "--strip-debug", "--exclude-resources",
-                "*.jcov, */META-INF/*", "--sort-resources",
+                "*.jcov, */META-INF/*", "--order-resources",
                 "*/module-info.class,/sortcomposite2/*,*/javax/management/*"};
             String moduleName = "excludezipfilterskipdebugcomposite2";
             helper.generateDefaultJModule(moduleName, "composite2");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jlink/plugins/OrderResourcesPluginTest.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,144 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary Test sorter plugin
+ * @author Jean-Francois Denise
+ * @modules jdk.jlink/jdk.tools.jlink.internal
+ *          jdk.jlink/jdk.tools.jlink.internal.plugins
+ * @run main OrderResourcesPluginTest
+ */
+
+import java.io.File;
+import java.nio.file.Files;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import jdk.tools.jlink.internal.PoolImpl;
+
+import jdk.tools.jlink.internal.plugins.OrderResourcesPlugin;
+import jdk.tools.jlink.plugin.Pool;
+import jdk.tools.jlink.plugin.Pool.ModuleData;
+import jdk.tools.jlink.plugin.TransformerPlugin;
+
+public class OrderResourcesPluginTest {
+
+    public static void main(String[] args) throws Exception {
+        new OrderResourcesPluginTest().test();
+    }
+
+    public void test() throws Exception {
+        ModuleData[] array = {
+                Pool.newResource("/module1/toto1.class", new byte[0]),
+                Pool.newResource("/module2/toto2.class", new byte[0]),
+                Pool.newResource("/module3/toto3.class", new byte[0]),
+                Pool.newResource("/module3/toto3/module-info.class", new byte[0]),
+                Pool.newResource("/zazou/toto.class", new byte[0]),
+                Pool.newResource("/module4/zazou.class", new byte[0]),
+                Pool.newResource("/module5/toto5.class", new byte[0]),
+                Pool.newResource("/module6/toto6/module-info.class", new byte[0])
+        };
+
+        ModuleData[] sorted = {
+                Pool.newResource("/zazou/toto.class", new byte[0]),
+                Pool.newResource("/module3/toto3/module-info.class", new byte[0]),
+                Pool.newResource("/module6/toto6/module-info.class", new byte[0]),
+                Pool.newResource("/module1/toto1.class", new byte[0]),
+                Pool.newResource("/module2/toto2.class", new byte[0]),
+                Pool.newResource("/module3/toto3.class", new byte[0]),
+                Pool.newResource("/module4/zazou.class", new byte[0]),
+                Pool.newResource("/module5/toto5.class", new byte[0])
+        };
+
+        ModuleData[] sorted2 = {
+            Pool.newResource("/module5/toto5.class", new byte[0]),
+            Pool.newResource("/module6/toto6/module-info.class", new byte[0]),
+            Pool.newResource("/module4/zazou.class", new byte[0]),
+            Pool.newResource("/module3/toto3.class", new byte[0]),
+            Pool.newResource("/module3/toto3/module-info.class", new byte[0]),
+            Pool.newResource("/module1/toto1.class", new byte[0]),
+            Pool.newResource("/module2/toto2.class", new byte[0]),
+            Pool.newResource("/zazou/toto.class", new byte[0])
+        };
+
+        Pool resources = new PoolImpl();
+        for (ModuleData r : array) {
+            resources.add(r);
+        }
+
+        {
+            Pool out = new PoolImpl();
+            Map<String, String> config = new HashMap<>();
+            config.put(OrderResourcesPlugin.NAME, "/zazou/*,*/module-info.class");
+            TransformerPlugin p = new OrderResourcesPlugin();
+            p.configure(config);
+            p.visit(resources, out);
+            check(out.getContent(), sorted);
+        }
+
+        {
+            // Order of resources in the file, then un-ordered resources.
+            File order = new File("resources.order");
+            order.createNewFile();
+            StringBuilder builder = new StringBuilder();
+            // 5 first resources come from file
+            for (int i = 0; i < 5; i++) {
+                String path = sorted2[i].getPath();
+                int index = path.indexOf('/', 1);
+                path = path.substring(index + 1, path.length() - ".class".length());
+                builder.append(path).append("\n");
+            }
+            Files.write(order.toPath(), builder.toString().getBytes());
+
+            Pool out = new PoolImpl();
+            Map<String, String> config = new HashMap<>();
+            config.put(OrderResourcesPlugin.NAME, "@" + order.getAbsolutePath());
+            TransformerPlugin p = new OrderResourcesPlugin();
+            p.configure(config);
+            p.visit(resources, out);
+            check(out.getContent(), sorted2);
+
+        }
+    }
+
+    private void check(Collection<ModuleData> outResources,
+            ModuleData[] sorted) {
+        if (outResources.size() != sorted.length) {
+            throw new AssertionError("Wrong number of resources:\n"
+                    + "expected: " + Arrays.toString(sorted) + ",\n"
+                    + "     got: " + outResources);
+        }
+        int i = 0;
+        for (ModuleData r : outResources) {
+            System.err.println("Resource: " + r);
+            if (!sorted[i].getPath().equals(r.getPath())) {
+                throw new AssertionError("Resource not properly sorted, difference at: " + i + "\n"
+                        + "expected: " + Arrays.toString(sorted) + ",\n"
+                        + "     got: " + outResources);
+            }
+            i++;
+        }
+    }
+}
--- a/jdk/test/tools/jlink/plugins/SorterPluginTest.java	Thu May 12 20:43:37 2016 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +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.
- */
-
-/*
- * @test
- * @summary Test sorter plugin
- * @author Jean-Francois Denise
- * @modules jdk.jlink/jdk.tools.jlink.internal
- *          jdk.jlink/jdk.tools.jlink.internal.plugins
- * @run main SorterPluginTest
- */
-
-import java.io.File;
-import java.nio.file.Files;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import jdk.tools.jlink.internal.PoolImpl;
-
-import jdk.tools.jlink.internal.plugins.SortResourcesPlugin;
-import jdk.tools.jlink.plugin.Pool;
-import jdk.tools.jlink.plugin.Pool.ModuleData;
-import jdk.tools.jlink.plugin.TransformerPlugin;
-
-public class SorterPluginTest {
-
-    public static void main(String[] args) throws Exception {
-        new SorterPluginTest().test();
-    }
-
-    public void test() throws Exception {
-        ModuleData[] array = {
-                Pool.newResource("/module1/toto1", new byte[0]),
-                Pool.newResource("/module2/toto1", new byte[0]),
-                Pool.newResource("/module3/toto1", new byte[0]),
-                Pool.newResource("/module3/toto1/module-info.class", new byte[0]),
-                Pool.newResource("/zazou/toto1", new byte[0]),
-                Pool.newResource("/module4/zazou", new byte[0]),
-                Pool.newResource("/module5/toto1", new byte[0]),
-                Pool.newResource("/module6/toto1/module-info.class", new byte[0])
-        };
-
-        ModuleData[] sorted = {
-                Pool.newResource("/zazou/toto1", new byte[0]),
-                Pool.newResource("/module3/toto1/module-info.class", new byte[0]),
-                Pool.newResource("/module6/toto1/module-info.class", new byte[0]),
-                Pool.newResource("/module1/toto1", new byte[0]),
-                Pool.newResource("/module2/toto1", new byte[0]),
-                Pool.newResource("/module3/toto1", new byte[0]),
-                Pool.newResource("/module4/zazou", new byte[0]),
-                Pool.newResource("/module5/toto1", new byte[0]),
-};
-
-        ModuleData[] sorted2 = {
-            Pool.newResource("/module5/toto1", new byte[0]),
-            Pool.newResource("/module6/toto1/module-info.class", new byte[0]),
-            Pool.newResource("/module4/zazou", new byte[0]),
-            Pool.newResource("/module3/toto1", new byte[0]),
-            Pool.newResource("/module3/toto1/module-info.class", new byte[0]),
-            Pool.newResource("/module1/toto1", new byte[0]),
-            Pool.newResource("/module2/toto1", new byte[0]),
-            Pool.newResource("/zazou/toto1", new byte[0]),};
-
-        Pool resources = new PoolImpl();
-        for (ModuleData r : array) {
-            resources.add(r);
-        }
-
-        {
-            Pool out = new PoolImpl();
-            Map<String, String> config = new HashMap<>();
-            config.put(SortResourcesPlugin.NAME, "/zazou/*,*/module-info.class");
-            TransformerPlugin p = new SortResourcesPlugin();
-            p.configure(config);
-            p.visit(resources, out);
-            check(out.getContent(), sorted);
-        }
-
-        {
-            // Order of resources in the file, then un-ordered resources.
-            File order = new File("resources.order");
-            order.createNewFile();
-            StringBuilder builder = new StringBuilder();
-            // 5 first resources come from file
-            for (int i = 0; i < 5; i++) {
-                builder.append(sorted2[i].getPath()).append("\n");
-            }
-            Files.write(order.toPath(), builder.toString().getBytes());
-
-            Pool out = new PoolImpl();
-            Map<String, String> config = new HashMap<>();
-            config.put(SortResourcesPlugin.NAME, order.getAbsolutePath());
-            TransformerPlugin p = new SortResourcesPlugin();
-            p.configure(config);
-            p.visit(resources, out);
-            check(out.getContent(), sorted2);
-
-        }
-    }
-
-    private void check(Collection<ModuleData> outResources,
-            ModuleData[] sorted) {
-        if (outResources.size() != sorted.length) {
-            throw new AssertionError("Wrong number of resources:\n"
-                    + "expected: " + Arrays.toString(sorted) + ",\n"
-                    + "     got: " + outResources);
-        }
-        int i = 0;
-        for (ModuleData r : outResources) {
-            System.err.println("Resource: " + r);
-            if (!sorted[i].getPath().equals(r.getPath())) {
-                throw new AssertionError("Resource not properly sorted, difference at: " + i + "\n"
-                        + "expected: " + Arrays.toString(sorted) + ",\n"
-                        + "     got: " + outResources);
-            }
-            i++;
-        }
-    }
-}
--- a/langtools/.hgtags	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/.hgtags	Thu May 12 11:03:07 2016 -0700
@@ -359,3 +359,4 @@
 cba09a2e6ae969b029783eb59bb01017b78f8eef jdk-9+114
 31c8b18fdc5b94a2ddd5ea0694f350a2c907e9f7 jdk-9+115
 3e3553ee39d9e081573bc7c88a252214a3152763 jdk-9+116
+59adcdd0cd3b6724b4fc0083c258bf4682689f2f jdk-9+117
--- a/langtools/make/build.xml	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/make/build.xml	Thu May 12 11:03:07 2016 -0700
@@ -83,6 +83,17 @@
     <property name="build.jtreg" location="${build.dir}/jtreg"/>
     <property name="build.prevsrc" location="${build.dir}/prevsrc"/>
 
+    <pathconvert property="modules.names" pathsep=",">
+        <globmapper from="${src.dir}/*" to="*" />
+        <dirset dir="${src.dir}" includes="*.*"/>
+    </pathconvert>
+
+    <pathconvert property="xpatch.rest" pathsep=" -Xpatch:">
+        <regexpmapper from="${file.separator}([^${file.separator}]+)$" to="\1=${build.modules}${file.separator}\1" />
+        <dirset dir="${src.dir}" includes="*.*"/>
+    </pathconvert>
+
+    <property name="xpatch.cmd" value="-Xpatch:${xpatch.rest}"/>
 
     <!-- java.marker is set to a marker file to check for within a Java install dir.
          The best file to check for across Solaris/Linux/Windows/MacOS is one of the
@@ -190,7 +201,7 @@
             <arg line="-source ${javac.source} -target ${javac.target}" />
             <arg value="-d" />
             <arg value="${build.modules}" />
-            <arg line="${javac.opts} -modulesourcepath ${src.dir}${file.separator}*${file.separator}share${file.separator}classes:${build.gensrc} -m java.compiler,jdk.compiler,jdk.javadoc,jdk.jdeps,jdk.jshell" />
+            <arg line="${javac.opts} -modulesourcepath ${src.dir}${file.separator}*${file.separator}share${file.separator}classes:${build.gensrc} -m ${modules.names}" />
         </exec>
         <delete>
             <fileset dir="${build.modules}" includes="**/module-info.class"/>
@@ -229,7 +240,7 @@
         <replace file=".idea/ant.xml" token="@IDEA_JTREG_HOME@" value="${idea.jtreg.home}"/>
         <replace file=".idea/ant.xml" token="@IDEA_TARGET_JDK@" value="${idea.target.jdk}"/>
         <replace file=".idea/workspace.xml" token="@IDEA_TARGET_JDK@" value="${idea.target.jdk}"/>
-        <replace file=".idea/workspace.xml" token="@FILE_SEP@" value="${file.separator}"/>
+        <replace file=".idea/workspace.xml" token="@XPATCH@" value="${xpatch.cmd}"/>
         <replace file=".idea/workspace.xml" token="@PATH_SEP@" value="${path.separator}"/>
         <mkdir dir=".idea/classes"/>
         <javac srcdir="make/intellij/src"
@@ -285,6 +296,7 @@
             <attribute name="bin.dir" default="${build.bin}"/>
             <attribute name="java" default="${launcher.java}"/>
             <attribute name="main.class" default="${tool.@{name}.main.class}"/>
+            <attribute name="xpatch" default="${xpatch.cmd}"/>
             <sequential>
                 <mkdir dir="@{bin.dir}"/>
                 <copy file="${make.dir}/launcher.sh-template" tofile="@{bin.dir}/@{name}">
@@ -292,6 +304,7 @@
                         <filter token="PROGRAM" value="@{main.class}"/>
                         <filter token="TARGET_JAVA" value="@{java}"/>
                         <filter token="PS" value="${path.separator}"/>
+                        <filter token="XPATCH" value="${xpatch.cmd}"/>
                     </filterset>
                 </copy>
                 <chmod file="@{bin.dir}/@{name}" perm="ugo+rx"/>
@@ -330,7 +343,7 @@
                     jdk="@{jdk}"
                     agentvm="@{agentvm}" verbose="@{verbose}"
                     failonerror="false" resultproperty="jtreg.@{name}.result"
-                    vmoptions="${coverage.options} @{extra.jvmargs} -Xpatch:@{build.modules}">
+                    vmoptions="${coverage.options} @{extra.jvmargs} ${xpatch.cmd}">
                     <arg value="-debug:@{jpda.jvmargs}"/>
                     <arg line="@{keywords}"/>
                     <arg line="@{options}"/>
--- a/langtools/make/intellij/workspace.xml	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/make/intellij/workspace.xml	Thu May 12 11:03:07 2016 -0700
@@ -10,7 +10,7 @@
     <!-- javac -->
     <configuration default="false" name="javac" type="Application" factoryName="Application">
       <option name="MAIN_CLASS_NAME" value="com.sun.tools.javac.Main" />
-      <option name="VM_PARAMETERS" value="-Xpatch:build@FILE_SEP@modules" />
+      <option name="VM_PARAMETERS" value="@XPATCH@" />
       <option name="PROGRAM_PARAMETERS" value="" />
       <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
       <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
@@ -30,7 +30,7 @@
     <!-- javadoc -->
     <configuration default="false" name="javadoc" type="Application" factoryName="Application">
       <option name="MAIN_CLASS_NAME" value="com.sun.tools.javadoc.Main" />
-      <option name="VM_PARAMETERS" value="-Xpatch:build@FILE_SEP@modules" />
+      <option name="VM_PARAMETERS" value="@XPATCH@" />
       <option name="PROGRAM_PARAMETERS" value="" />
       <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
       <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
@@ -50,7 +50,7 @@
     <!-- javap -->
     <configuration default="false" name="javap" type="Application" factoryName="Application">
       <option name="MAIN_CLASS_NAME" value="com.sun.tools.javap.Main" />
-      <option name="VM_PARAMETERS" value="-Xpatch:build@FILE_SEP@modules" />
+      <option name="VM_PARAMETERS" value="@XPATCH@" />
       <option name="PROGRAM_PARAMETERS" value="" />
       <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
       <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
@@ -70,7 +70,7 @@
     <!-- javah -->
     <configuration default="false" name="javah" type="Application" factoryName="Application">
       <option name="MAIN_CLASS_NAME" value="com.sun.tools.javah.Main" />
-      <option name="VM_PARAMETERS" value="-Xpatch:build@FILE_SEP@modules" />
+      <option name="VM_PARAMETERS" value="@XPATCH@" />
       <option name="PROGRAM_PARAMETERS" value="" />
       <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
       <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
@@ -90,7 +90,7 @@
     <!-- sjavac -->
     <configuration default="false" name="sjavac" type="Application" factoryName="Application">
       <option name="MAIN_CLASS_NAME" value="com.sun.tools.sjavac.Main" />
-      <option name="VM_PARAMETERS" value="-Xpatch:build@FILE_SEP@modules" />
+      <option name="VM_PARAMETERS" value="@XPATCH@" />
       <option name="PROGRAM_PARAMETERS" value="" />
       <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
       <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
@@ -111,7 +111,7 @@
     <configuration default="false" name="jshell" type="Application" factoryName="Application">
       <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
       <option name="MAIN_CLASS_NAME" value="jdk.internal.jshell.tool.JShellTool" />
-      <option name="VM_PARAMETERS" value="-Xpatch:build@FILE_SEP@modules -XaddExports:jdk.jshell/jdk.internal.jshell.tool=ALL-UNNAMED" />
+      <option name="VM_PARAMETERS" value="@XPATCH@ -XaddExports:jdk.jshell/jdk.internal.jshell.tool=ALL-UNNAMED" />
       <option name="PROGRAM_PARAMETERS" value="" />
       <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
       <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
--- a/langtools/make/launcher.sh-template	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/make/launcher.sh-template	Thu May 12 11:03:07 2016 -0700
@@ -25,17 +25,6 @@
 # questions.
 #
 
-mydir="`dirname $0`"
-case `uname -s` in
-    CYGWIN*)
-      mydir=`cygpath -m $mydir`
-      ;;
-esac
-mylib="$mydir/../modules"
-
-# patch langtools modules
-bcp=-Xpatch:"$mylib"
-
 # tools currently assumes that assertions are enabled in the launcher
 ea=-ea:com.sun.tools...
 
@@ -59,4 +48,4 @@
 unset DUALCASE
 
 IFS=$nl
-"#TARGET_JAVA#" $bcp ${ea} ${javaOpts} #PROGRAM# ${toolOpts}
+"#TARGET_JAVA#" "#XPATCH#" ${ea} ${javaOpts} #PROGRAM# ${toolOpts}
--- a/langtools/make/tools/crules/CodingRulesAnalyzerPlugin.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/make/tools/crules/CodingRulesAnalyzerPlugin.java	Thu May 12 11:03:07 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
@@ -48,6 +48,13 @@
 import com.sun.tools.javac.util.DefinedBy.Api;
 import com.sun.tools.javac.util.Log;
 
+/*
+ * This code must be run in a context that provides
+ * access to the following javac internal packages:
+ *      com.sun.tools.javac.api
+ *      com.sun.tools.javac.tree
+ *      com.sun.tools.javac.util
+ */
 public class CodingRulesAnalyzerPlugin implements Plugin {
 
     protected Log log;
@@ -55,11 +62,6 @@
 
     @DefinedBy(Api.COMPILER_TREE)
     public void init(JavacTask task, String... args) {
-        addExports("jdk.compiler",
-                "com.sun.tools.javac.api",
-                "com.sun.tools.javac.code",
-                "com.sun.tools.javac.tree",
-                "com.sun.tools.javac.util");
         BasicJavacTask impl = (BasicJavacTask)task;
         Context context = impl.getContext();
         log = Log.instance(context);
--- a/langtools/make/tools/crules/MutableFieldsAnalyzer.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/make/tools/crules/MutableFieldsAnalyzer.java	Thu May 12 11:03:07 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2014, 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,8 +25,10 @@
 
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import com.sun.source.util.JavacTask;
 import com.sun.source.util.TaskEvent.Kind;
@@ -48,16 +50,8 @@
     }
 
     private boolean ignoreField(String className, String field) {
-        List<String> currentFieldsToIgnore =
-                classFieldsToIgnoreMap.get(className);
-        if (currentFieldsToIgnore != null) {
-            for (String fieldToIgnore : currentFieldsToIgnore) {
-                if (field.equals(fieldToIgnore)) {
-                    return true;
-                }
-            }
-        }
-        return false;
+        Set<String> fieldsToIgnore = classFieldsToIgnoreMap.get(className);
+        return (fieldsToIgnore) != null && fieldsToIgnore.contains(field);
     }
 
     class MutableFieldsVisitor extends TreeScanner {
@@ -89,34 +83,29 @@
 
     private static final String packageToCheck = "com.sun.tools.javac";
 
-    private static final Map<String, List<String>> classFieldsToIgnoreMap =
+    private static final Map<String, Set<String>> classFieldsToIgnoreMap =
                 new HashMap<>();
 
+    private static void ignoreFields(String className, String... fieldNames) {
+        classFieldsToIgnoreMap.put(className, new HashSet<>(Arrays.asList(fieldNames)));
+    };
+
     static {
-        classFieldsToIgnoreMap.
-                put("com.sun.tools.javac.util.JCDiagnostic",
-                    Arrays.asList("fragmentFormatter"));
-        classFieldsToIgnoreMap.
-                put("com.sun.tools.javac.util.JavacMessages",
-                    Arrays.asList("defaultBundle", "defaultMessages"));
-        classFieldsToIgnoreMap.
-                put("com.sun.tools.javac.file.ZipFileIndexCache",
-                    Arrays.asList("sharedInstance"));
-        classFieldsToIgnoreMap.
-                put("com.sun.tools.javac.file.JRTIndex",
-                    Arrays.asList("sharedInstance"));
-        classFieldsToIgnoreMap.
-                put("com.sun.tools.javac.main.JavaCompiler",
-                    Arrays.asList("versionRB"));
-        classFieldsToIgnoreMap.
-                put("com.sun.tools.javac.code.Type",
-                    Arrays.asList("moreInfo"));
-        classFieldsToIgnoreMap.
-                put("com.sun.tools.javac.util.SharedNameTable",
-                    Arrays.asList("freelist"));
-        classFieldsToIgnoreMap.
-                put("com.sun.tools.javac.util.Log",
-                    Arrays.asList("useRawMessages"));
+        ignoreFields("com.sun.tools.javac.util.JCDiagnostic", "fragmentFormatter");
+        ignoreFields("com.sun.tools.javac.util.JavacMessages", "defaultBundle", "defaultMessages");
+        ignoreFields("com.sun.tools.javac.file.JRTIndex", "sharedInstance");
+        ignoreFields("com.sun.tools.javac.main.JavaCompiler", "versionRB");
+        ignoreFields("com.sun.tools.javac.code.Type", "moreInfo");
+        ignoreFields("com.sun.tools.javac.util.SharedNameTable", "freelist");
+        ignoreFields("com.sun.tools.javac.util.Log", "useRawMessages");
+        ignoreFields("com.sun.tools.javac.util.ModuleWrappers$ModuleFinderHelper",
+                "moduleFinderInterface", "ofMethod", "emptyMethod");
+        ignoreFields("com.sun.tools.javac.util.ModuleWrappers$ConfigurationHelper",
+                "configurationClass", "resolveRequiresAndUsesMethod");
+        ignoreFields("com.sun.tools.javac.util.ModuleWrappers$LayerHelper",
+                "layerClass", "bootMethod", "defineModulesWithOneLoaderMethod", "configurationMethod");
+        ignoreFields("com.sun.tools.javac.util.ModuleHelper",
+                "addExportsMethod", "getUnnamedModuleMethod", "getModuleMethod");
     }
 
 }
--- a/langtools/make/tools/propertiesparser/PropertiesParser.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/make/tools/propertiesparser/PropertiesParser.java	Thu May 12 11:03:07 2016 -0700
@@ -28,24 +28,10 @@
 import propertiesparser.parser.MessageFile;
 import propertiesparser.gen.ClassGenerator;
 
-import java.io.BufferedWriter;
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.lang.RuntimeException;
-import java.lang.Throwable;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collections;
+import java.io.PrintStream;
 import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
 import java.util.Map;
-import java.util.Properties;
 
 /** Translates a .properties file into a .java file containing an enum-like Java class
  *  which defines static factory methods for all resource keys in a given resource file. <P>
@@ -64,13 +50,17 @@
     }
 
     public static void main(String[] args) {
-        PropertiesParser pp = new PropertiesParser(msg -> System.out.println(msg));
-        boolean ok = pp.run(args);
+        boolean ok = run(args, System.out);
         if ( !ok ) {
             System.exit(1);
         }
     }
 
+    public static boolean run(String[] args, PrintStream out) {
+        PropertiesParser pp = new PropertiesParser(msg -> out.println(msg));
+        return pp.run(args);
+    }
+
     public static interface Logger {
         void info(String msg);
     }
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/Elements.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/Elements.java	Thu May 12 11:03:07 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
@@ -49,12 +49,22 @@
     /**
      * Returns a package given its fully qualified name.
      *
-     * @param name  fully qualified package name, or "" for an unnamed package
+     * @param name  fully qualified package name, or an empty string for an unnamed package
      * @return the named package, or {@code null} if it cannot be found
      */
     PackageElement getPackageElement(CharSequence name);
 
     /**
+     * Returns a package given its fully qualified name, as seen from the given module.
+     *
+     * @param name  fully qualified package name, or an empty string for an unnamed package
+     * @param module module relative to which the lookup should happen
+     * @return the named package, or {@code null} if it cannot be found
+     * @since 9
+     */
+    PackageElement getPackageElement(ModuleElement module, CharSequence name);
+
+    /**
      * Returns a type element given its canonical name.
      *
      * @param name  the canonical name
@@ -63,6 +73,16 @@
     TypeElement getTypeElement(CharSequence name);
 
     /**
+     * Returns a type element given its canonical name, as seen from the given module.
+     *
+     * @param name  the canonical name
+     * @param module module relative to which the lookup should happen
+     * @return the named type element, or {@code null} if it cannot be found
+     * @since 9
+     */
+    TypeElement getTypeElement(ModuleElement module, CharSequence name);
+
+    /**
      * Returns a module element given its fully qualified name.
      *
      * @param name  the name
--- a/langtools/src/java.compiler/share/classes/javax/tools/ToolProvider.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/src/java.compiler/share/classes/javax/tools/ToolProvider.java	Thu May 12 11:03:07 2016 -0700
@@ -27,6 +27,8 @@
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.Iterator;
 import java.util.ServiceConfigurationError;
 import java.util.ServiceLoader;
@@ -145,23 +147,26 @@
     }
 
     /**
-     * Determine if this is tho desired tool instance.
+     * Determine if this is the desired tool instance.
      * @param <T>        the interface of the tool
      * @param tool       the instance of the tool
      * @param moduleName the name of the module containing the desired implementation
      * @return true if and only if the tool matches the specified criteria
      */
     private static <T> boolean matches(T tool, String moduleName) {
-        // for now, use reflection to implement
-        //      return moduleName.equals(tool.getClass().getModule().getName());
-        try {
-            Method getModuleMethod = Class.class.getDeclaredMethod("getModule");
-            Object toolModule = getModuleMethod.invoke(tool.getClass());
-            Method getNameMethod = toolModule.getClass().getDeclaredMethod("getName");
-            String toolModuleName = (String) getNameMethod.invoke(toolModule);
-            return moduleName.equals(toolModuleName);
-        } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {
-            return false;
-        }
+        PrivilegedAction<Boolean> pa = () -> {
+            // for now, use reflection to implement
+            //      return moduleName.equals(tool.getClass().getModule().getName());
+            try {
+                Method getModuleMethod = Class.class.getDeclaredMethod("getModule");
+                Object toolModule = getModuleMethod.invoke(tool.getClass());
+                Method getNameMethod = toolModule.getClass().getDeclaredMethod("getName");
+                String toolModuleName = (String) getNameMethod.invoke(toolModule);
+                return moduleName.equals(toolModuleName);
+            } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {
+                return false;
+            }
+        };
+        return AccessController.doPrivileged(pa);
     }
 }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Thu May 12 11:03:07 2016 -0700
@@ -960,12 +960,12 @@
             return n;
         }
 
-        @Override
+        @Override @DefinedBy(Api.LANGUAGE_MODEL)
         public <R, P> R accept(ElementVisitor<R, P> v, P p) {
             return v.visitModule(this, p);
         }
 
-        @Override
+        @Override @DefinedBy(Api.LANGUAGE_MODEL)
         public List<Symbol> getEnclosedElements() {
             List<Symbol> list = List.nil();
             for (Symbol sym : enclosedPackages) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java	Thu May 12 11:03:07 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
@@ -1588,17 +1588,17 @@
             return v.visitModuleType(this, s);
         }
 
-        @Override
+        @Override @DefinedBy(Api.LANGUAGE_MODEL)
         public String toString() {
             return tsym.getQualifiedName().toString();
         }
 
-        @Override
+        @Override @DefinedBy(Api.LANGUAGE_MODEL)
         public TypeKind getKind() {
             return TypeKind.MODULE;
         }
 
-        @Override
+        @Override @DefinedBy(Api.LANGUAGE_MODEL)
         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
             return v.visitNoType(this, p);
         }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Thu May 12 11:03:07 2016 -0700
@@ -102,6 +102,7 @@
 import com.sun.tools.javac.tree.JCTree.Tag;
 
 import static com.sun.tools.javac.code.Flags.ABSTRACT;
+import static com.sun.tools.javac.code.Flags.ENUM;
 import static com.sun.tools.javac.code.Flags.PUBLIC;
 import static com.sun.tools.javac.tree.JCTree.Tag.MODULEDEF;
 
@@ -131,6 +132,9 @@
 
     private final String moduleOverride;
 
+    private final Name java_se;
+    private final Name java_;
+
     ModuleSymbol defaultModule;
 
     private final String addExportsOpt;
@@ -173,6 +177,9 @@
         JNIWriter jniWriter = JNIWriter.instance(context);
         jniWriter.multiModuleMode = multiModuleMode;
 
+        java_se = names.fromString("java.se");
+        java_ = names.fromString("java.");
+
         addExportsOpt = options.get(Option.XADDEXPORTS);
         addReadsOpt = options.get(Option.XADDREADS);
         addModsOpt = options.get(Option.ADDMODS);
@@ -747,7 +754,10 @@
         @Override
         public void visitUses(JCUses tree) {
             Type st = attr.attribType(tree.qualid, env, syms.objectType);
-            if (st.hasTag(CLASS)) {
+            Symbol sym = TreeInfo.symbol(tree.qualid);
+            if ((sym.flags() & ENUM) != 0) {
+                log.error(tree.qualid.pos(), Errors.ServiceDefinitionIsEnum(st.tsym));
+            } else if (st.hasTag(CLASS)) {
                 ClassSymbol service = (ClassSymbol) st.tsym;
                 Directive.UsesDirective d = new Directive.UsesDirective(service);
                 if (!allUses.add(d)) {
@@ -761,17 +771,17 @@
         private void checkForCorrectness() {
             for (Directive.ProvidesDirective provides : allProvides) {
                 JCProvides tree = directiveToTreeMap.get(provides);
-                /** The implementation must be defined in the same module as the provides directive
-                 *  (else, error)
+                /* The implementation must be defined in the same module as the provides directive
+                 * (else, error)
                  */
                 PackageSymbol implementationDefiningPackage = provides.impl.packge();
                 if (implementationDefiningPackage.modle != msym) {
                     log.error(tree.pos(), Errors.ServiceImplementationNotInRightModule(implementationDefiningPackage.modle));
                 }
 
-                /** There is no inherent requirement that module that provides a service should actually
-                 *  use it itself. However, it is a pointless declaration if the service package is not
-                 *  exported and there is no uses for the service.
+                /* There is no inherent requirement that module that provides a service should actually
+                 * use it itself. However, it is a pointless declaration if the service package is not
+                 * exported and there is no uses for the service.
                  */
                 PackageSymbol interfaceDeclaringPackage = provides.service.packge();
                 boolean isInterfaceDeclaredInCurrentModule = interfaceDeclaringPackage.modle == msym;
@@ -826,8 +836,22 @@
         Set<ModuleSymbol> enabledRoot = new LinkedHashSet<>();
 
         if (rootModules.contains(syms.unnamedModule)) {
-            for (ModuleSymbol sym : syms.getAllModules()) {
-                if (systemModulePred.test(sym) && observablePred.test(sym)) {
+            ModuleSymbol javaSE = syms.getModule(java_se);
+            Predicate<ModuleSymbol> jdkModulePred;
+
+            if (javaSE != null && (observable == null || observable.contains(javaSE))) {
+                jdkModulePred = sym -> {
+                    sym.complete();
+                    return   !sym.name.startsWith(java_)
+                           && sym.exports.stream().anyMatch(e -> e.modules == null);
+                };
+                enabledRoot.add(javaSE);
+            } else {
+                jdkModulePred = sym -> true;
+            }
+
+            for (ModuleSymbol sym : new HashSet<>(syms.getAllModules())) {
+                if (systemModulePred.test(sym) && observablePred.test(sym) && jdkModulePred.test(sym)) {
                     enabledRoot.add(sym);
                 }
             }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java	Thu May 12 11:03:07 2016 -0700
@@ -74,6 +74,8 @@
 import com.sun.tools.javac.main.Option;
 import com.sun.tools.javac.resources.CompilerProperties.Errors;
 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
+import com.sun.tools.javac.util.DefinedBy;
+import com.sun.tools.javac.util.DefinedBy.Api;
 import com.sun.tools.javac.util.ListBuffer;
 import com.sun.tools.javac.util.Log;
 import com.sun.tools.javac.util.Pair;
@@ -813,7 +815,7 @@
      * SYSTEM_MODULES and MODULE_PATH.
      *
      * The Location can be specified to accept overriding classes from the
-     * -Xpatch:dir parameter.
+     * {@code -Xpatch:<module>=<path> } parameter.
      */
     private class ModuleLocationHandler extends LocationHandler implements Location {
         protected final String name;
@@ -829,47 +831,27 @@
             this.searchPath = searchPath;
             this.output = output;
 
-            if (allowOverrides) {
-                if (patchMap != null) {
-                    SearchPath mPatch = patchMap.get(moduleName);
-                    if (mPatch != null) {
-                        SearchPath sp = new SearchPath();
-                        sp.addAll(mPatch);
-                        sp.addAll(searchPath);
-                        searchPathWithOverrides = sp;
-                    } else {
-                        searchPathWithOverrides = searchPath;
-                    }
+            if (allowOverrides && patchMap != null) {
+                SearchPath mPatch = patchMap.get(moduleName);
+                if (mPatch != null) {
+                    SearchPath sp = new SearchPath();
+                    sp.addAll(mPatch);
+                    sp.addAll(searchPath);
+                    searchPathWithOverrides = sp;
                 } else {
-                     // for old style patch option; retained for transition
-                    Set<Path> overrides = new LinkedHashSet<>();
-                    if (moduleOverrideSearchPath != null) {
-                       for (Path p: moduleOverrideSearchPath) {
-                           Path o = p.resolve(moduleName);
-                           if (Files.isDirectory(o)) {
-                               overrides.add(o);
-                           }
-                       }
-                    }
-
-                    if (!overrides.isEmpty()) {
-                        overrides.addAll(searchPath);
-                        searchPathWithOverrides = overrides;
-                    } else {
-                        searchPathWithOverrides = searchPath;
-                    }
+                    searchPathWithOverrides = searchPath;
                 }
             } else {
                 searchPathWithOverrides = searchPath;
             }
         }
 
-        @Override // defined by Location
+        @Override @DefinedBy(Api.COMPILER)
         public String getName() {
             return name;
         }
 
-        @Override // defined by Location
+        @Override @DefinedBy(Api.COMPILER)
         public boolean isOutputLocation() {
             return output;
         }
@@ -1522,41 +1504,33 @@
         }
     }
 
-    private SearchPath moduleOverrideSearchPath; // for old style patch option; retained for transition
     private Map<String, SearchPath> patchMap;
 
     boolean handleOption(Option option, String value) {
         switch (option) {
             case XPATCH:
-                if (value.contains("=")) {
-                    Map<String, SearchPath> map = new LinkedHashMap<>();
-                    for (String entry: value.split(",")) {
-                        int eq = entry.indexOf('=');
-                        if (eq > 0) {
-                            String mName = entry.substring(0, eq);
-                            SearchPath mPatchPath = new SearchPath()
-                                    .addFiles(entry.substring(eq + 1));
-                            boolean ok = true;
-                            for (Path p: mPatchPath) {
-                                Path mi = p.resolve("module-info.class");
-                                if (Files.exists(mi)) {
-                                    log.error(Errors.LocnModuleInfoNotAllowedOnPatchPath(mi));
-                                    ok = false;
-                                }
-                            }
-                            if (ok && !mPatchPath.isEmpty()) {
-                                map.computeIfAbsent(mName, (_x) -> new SearchPath())
-                                        .addAll(mPatchPath);
-                            }
-                        } else {
-                            log.error(Errors.LocnInvalidArgForXpatch(entry));
+                Map<String, SearchPath> map = new LinkedHashMap<>();
+                int eq = value.indexOf('=');
+                if (eq > 0) {
+                    String mName = value.substring(0, eq);
+                    SearchPath mPatchPath = new SearchPath()
+                            .addFiles(value.substring(eq + 1));
+                    boolean ok = true;
+                    for (Path p: mPatchPath) {
+                        Path mi = p.resolve("module-info.class");
+                        if (Files.exists(mi)) {
+                            log.error(Errors.LocnModuleInfoNotAllowedOnPatchPath(mi));
+                            ok = false;
                         }
                     }
-                    patchMap = map;
+                    if (ok && !mPatchPath.isEmpty()) {
+                        map.computeIfAbsent(mName, (_x) -> new SearchPath())
+                                .addAll(mPatchPath);
+                    }
                 } else {
-                     // for old style patch option; retained for transition
-                    moduleOverrideSearchPath = new SearchPath().addFiles(value);
+                    log.error(Errors.LocnInvalidArgForXpatch(value));
                 }
+                patchMap = map;
                 return true;
             default:
                 LocationHandler h = handlersForOption.get(option);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java	Thu May 12 11:03:07 2016 -0700
@@ -199,7 +199,7 @@
 
     SYSTEM("-system", "opt.arg.jdk", "opt.system", STANDARD, FILEMANAGER),
 
-    XPATCH("-Xpatch:", "opt.arg.path", "opt.Xpatch", EXTENDED, FILEMANAGER),
+    XPATCH("-Xpatch:", "opt.arg.patch", "opt.patch", EXTENDED, FILEMANAGER),
 
     BOOTCLASSPATH("-bootclasspath", "opt.arg.path", "opt.bootclasspath", STANDARD, FILEMANAGER) {
         @Override
@@ -529,83 +529,21 @@
     XADDEXPORTS("-XaddExports:", "opt.arg.addExports", "opt.addExports", EXTENDED, BASIC) {
         @Override
         public boolean process(OptionHelper helper, String option) {
-            if (option.matches(".*,.*=.*")) { // temporary, for backwards compatibility
-                return processOldStyle(helper, option);
-            }
             String p = option.substring(option.indexOf(':') + 1).trim();
             String prev = helper.get(XADDEXPORTS);
             helper.put(XADDEXPORTS.text, (prev == null) ? p : prev + '\0' + p);
             return false;
         }
-
-        // convert old style option into a series of new-style options
-        private boolean processOldStyle(OptionHelper helper, String option) {
-            String p = option.substring(option.indexOf(':') + 1).trim();
-            String[] entries = p.split("[ ,]+");
-            Map<String, String> map = new LinkedHashMap<>();
-            for (String e: entries) {
-                // Each entry is of the form   module/package=target
-                // we must group values for the same module/package together
-                int eq = e.indexOf('=');
-                if (eq == -1) {
-                    // don't bother with error message for backwards compatible support
-                    continue;
-                }
-                String modPkg = e.substring(0, eq);
-                String target = e.substring(eq + 1);
-                String targets = map.get(modPkg);
-                map.put(modPkg, (targets == null) ? target : targets + "," + target);
-            }
-            boolean ok = true;
-            for (Map.Entry<String, String> e: map.entrySet()) {
-                // process as new-style options
-                String key = e.getKey();
-                String value = e.getValue();
-                ok = ok & process(helper, XADDEXPORTS.text + key + "=" + value);
-            };
-            return ok;
-        }
     },
 
     XADDREADS("-XaddReads:", "opt.arg.addReads", "opt.addReads", EXTENDED, BASIC) {
         @Override
         public boolean process(OptionHelper helper, String option) {
-            if (option.matches(".*,.*=.*")) { // temporary, for backwards compatibility
-                return processOldStyle(helper, option);
-            }
             String p = option.substring(option.indexOf(':') + 1).trim();
             String prev = helper.get(XADDREADS);
             helper.put(XADDREADS.text, (prev == null) ? p : prev + '\0' + p);
             return false;
         }
-
-        // convert old style option into a series of new-style options
-        private boolean processOldStyle(OptionHelper helper, String option) {
-            String p = option.substring(option.indexOf(':') + 1).trim();
-            String[] entries = p.split("[ ,]+");
-            Map<String, String> map = new LinkedHashMap<>();
-            for (String e: entries) {
-                // Each entry is of the form   module=target
-                // we must group values for the same module together
-                int eq = e.indexOf('=');
-                if (eq == -1) {
-                    // don't bother with error message for backwards compatible support
-                    continue;
-                }
-                String modPkg = e.substring(0, eq);
-                String target = e.substring(eq + 1);
-                String targets = map.get(modPkg);
-                map.put(modPkg, (targets == null) ? target : targets + "," + target);
-            }
-            boolean ok = true;
-            for (Map.Entry<String, String> e: map.entrySet()) {
-                // process as new-style options
-                String key = e.getKey();
-                String value = e.getValue();
-                ok = ok & process(helper, XADDEXPORTS.text + key + "=" + value);
-            };
-            return ok;
-        }
     },
 
     XMODULE("-Xmodule:", "opt.arg.module", "opt.module", EXTENDED, BASIC) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java	Thu May 12 11:03:07 2016 -0700
@@ -107,12 +107,13 @@
         return modules.getObservableModule(names.fromString(strName));
     }
 
-    @DefinedBy(Api.LANGUAGE_MODEL)
+    @Override @DefinedBy(Api.LANGUAGE_MODEL)
     public PackageSymbol getPackageElement(CharSequence name) {
         ensureEntered("getPackageElement");
         return getPackageElement(modules.getDefaultModule(), name);
     }
 
+    @Override @DefinedBy(Api.LANGUAGE_MODEL)
     public PackageSymbol getPackageElement(ModuleElement module, CharSequence name) {
         String strName = name.toString();
         if (strName.equals(""))
@@ -122,12 +123,13 @@
             : null;
     }
 
-    @DefinedBy(Api.LANGUAGE_MODEL)
+    @Override @DefinedBy(Api.LANGUAGE_MODEL)
     public ClassSymbol getTypeElement(CharSequence name) {
         ensureEntered("getTypeElement");
         return getTypeElement(modules.getDefaultModule(), name);
     }
 
+    @Override @DefinedBy(Api.LANGUAGE_MODEL)
     public ClassSymbol getTypeElement(ModuleElement module, CharSequence name) {
         String strName = name.toString();
         return SourceVersion.isName(strName)
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Thu May 12 11:03:07 2016 -0700
@@ -2719,6 +2719,10 @@
     the service definition is an inner class: {0}
 
 # 0: symbol
+compiler.err.service.definition.is.enum=\
+    the service definition is an enum: {0}
+
+# 0: symbol
 compiler.err.service.implementation.doesnt.have.a.no.args.constructor=\
     the service implementation does not have a default constructor: {0}
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties	Thu May 12 11:03:07 2016 -0700
@@ -53,12 +53,6 @@
     Override location of system modules
 javac.opt.upgrademodulepath=\
     Override location of upgradeable modules
-javac.opt.Xbootclasspath.p=\
-    Prepend to the bootstrap class path
-javac.opt.Xbootclasspath.a=\
-    Append to the bootstrap class path
-javac.opt.Xpatch=\
-    Specify location of module class files to patch
 javac.opt.endorseddirs=\
     Override location of endorsed standards path
 javac.opt.extdirs=\
@@ -160,6 +154,10 @@
     <pathname>
 javac.opt.arg.file=\
     <filename>
+javac.opt.Xbootclasspath.p=\
+    Prepend to the bootstrap class path
+javac.opt.Xbootclasspath.a=\
+    Append to the bootstrap class path
 javac.opt.Xlint=\
     Enable recommended warnings
 javac.opt.Xlint.all=\
@@ -286,6 +284,11 @@
 \        <other-module> may be ALL-UNNAMED to require the unnamed module.
 javac.opt.arg.addReads=\
     <module>=<other-module>(,<other-module>)*
+javac.opt.patch=\n\
+\        Override or augment a module with classes and resources\n\
+\        in JAR files or directories
+javac.opt.arg.patch=\
+    <module>=<file>(:<file>)*
 javac.opt.module=\
     Specify a module to which the classes being compiled belong.
 javac.opt.arg.module=\
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java	Thu May 12 11:03:07 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
@@ -2626,22 +2626,22 @@
         @Override
         public void accept(Visitor v) { v.visitModuleDef(this); }
 
-        @Override
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public Kind getKind() {
             return Kind.MODULE;
         }
 
-//        @Override
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public JCExpression getName() {
             return qualId;
         }
 
-        @Override
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public List<JCDirective> getDirectives() {
             return directives;
         }
 
-        @Override
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public <R, D> R accept(TreeVisitor<R, D> v, D d) {
             return v.visitModule(this, d);
         }
@@ -2666,22 +2666,22 @@
         @Override
         public void accept(Visitor v) { v.visitExports(this); }
 
-        @Override
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public Kind getKind() {
             return Kind.EXPORTS;
         }
 
-        @Override
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public JCExpression getExportName() {
             return qualid;
         }
 
-        @Override
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public List<JCExpression> getModuleNames() {
             return moduleNames;
         }
 
-        @Override
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public <R, D> R accept(TreeVisitor<R, D> v, D d) {
             return v.visitExports(this, d);
         }
@@ -2705,22 +2705,22 @@
         @Override
         public void accept(Visitor v) { v.visitProvides(this); }
 
-        @Override
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public Kind getKind() {
             return Kind.PROVIDES;
         }
 
-        @Override
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public <R, D> R accept(TreeVisitor<R, D> v, D d) {
             return v.visitProvides(this, d);
         }
 
-        @Override
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public JCExpression getServiceName() {
             return serviceName;
         }
 
-        @Override
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public JCExpression getImplementationName() {
             return implName;
         }
@@ -2745,22 +2745,22 @@
         @Override
         public void accept(Visitor v) { v.visitRequires(this); }
 
-        @Override
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public Kind getKind() {
             return Kind.REQUIRES;
         }
 
-        @Override
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public <R, D> R accept(TreeVisitor<R, D> v, D d) {
             return v.visitRequires(this, d);
         }
 
-        @Override
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public boolean isPublic() {
             return isPublic;
         }
 
-        @Override
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public JCExpression getModuleName() {
             return moduleName;
         }
@@ -2782,17 +2782,17 @@
         @Override
         public void accept(Visitor v) { v.visitUses(this); }
 
-        @Override
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public Kind getKind() {
             return Kind.USES;
         }
 
-        @Override
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public JCExpression getServiceName() {
             return qualid;
         }
 
-        @Override
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public <R, D> R accept(TreeVisitor<R, D> v, D d) {
             return v.visitUses(this, d);
         }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeCopier.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeCopier.java	Thu May 12 11:03:07 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2015, 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
@@ -505,7 +505,7 @@
         return M.at(t.pos).Wildcard(kind, inner);
     }
 
-    @Override
+    @Override @DefinedBy(Api.COMPILER_TREE)
     public JCTree visitModule(ModuleTree node, P p) {
         JCModuleDecl t = (JCModuleDecl) node;
         JCExpression qualId = copy(t.qualId);
@@ -513,7 +513,7 @@
         return M.at(t.pos).ModuleDef(qualId, directives);
     }
 
-    @Override
+    @Override @DefinedBy(Api.COMPILER_TREE)
     public JCExports visitExports(ExportsTree node, P p) {
         JCExports t = (JCExports) node;
         JCExpression qualId = copy(t.qualid, p);
@@ -521,7 +521,7 @@
         return M.at(t.pos).Exports(qualId, moduleNames);
     }
 
-    @Override
+    @Override @DefinedBy(Api.COMPILER_TREE)
     public JCProvides visitProvides(ProvidesTree node, P p) {
         JCProvides t = (JCProvides) node;
         JCExpression serviceName = copy(t.serviceName, p);
@@ -529,14 +529,14 @@
         return M.at(t.pos).Provides(serviceName, implName);
     }
 
-    @Override
+    @Override @DefinedBy(Api.COMPILER_TREE)
     public JCRequires visitRequires(RequiresTree node, P p) {
         JCRequires t = (JCRequires) node;
         JCExpression moduleName = copy(t.moduleName, p);
         return M.at(t.pos).Requires(t.isPublic, moduleName);
     }
 
-    @Override
+    @Override @DefinedBy(Api.COMPILER_TREE)
     public JCUses visitUses(UsesTree node, P p) {
         JCUses t = (JCUses) node;
         JCExpression serviceName = copy(t.qualid, p);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/ModuleWrappers.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/ModuleWrappers.java	Thu May 12 11:03:07 2016 -0700
@@ -25,7 +25,6 @@
 
 package com.sun.tools.javac.util;
 
-import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.nio.file.Path;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SmartFileManager.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SmartFileManager.java	Thu May 12 11:03:07 2016 -0700
@@ -203,7 +203,7 @@
         return file;
     }
 
-    @Override
+    @Override @DefinedBy(Api.COMPILER)
     public Location getModuleLocation(Location location, JavaFileObject fo, String pkgName) throws IOException {
         return super.getModuleLocation(location, locUnwrap(fo), pkgName);
     }
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties	Thu May 12 11:03:07 2016 -0700
@@ -339,7 +339,8 @@
 
 doclet.xusage.xdoclint-package.name=Xdoclint/package:
 doclet.xusage.xdoclint-package.parameters=([-]<packages>)
-doclet.xusage.xdoclint-package.description=Enable or disable checks in specific packages. <packages> is a comma separated\n\
+doclet.xusage.xdoclint-package.description=\n\
+\        Enable or disable checks in specific packages. <packages> is a comma separated\n\
 \        list of package specifiers. Package specifier is either a qualified name of a package\n\
 \        or a package name prefix followed by .*, which expands to all sub-packages of\n\
 \        the given package. Prefix the package specifier with - to disable checks for\n\
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java	Thu May 12 11:03:07 2016 -0700
@@ -1140,7 +1140,7 @@
          */
         @Override
         public String toString() {
-            String opt = name + " " + parameters;
+            String opt = name + (name.endsWith(":") ? "" : " ") + parameters;
             int optlen = opt.length();
             int spaces = 32 - optlen;
             StringBuffer sb = new StringBuffer("  -").append(opt);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties	Thu May 12 11:03:07 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
@@ -73,7 +73,9 @@
 \                                   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:<module>=<file>(:<file>)*\n\
+\                                   Override or augment a module with classes and resources\n\
+\                                   in JAR files or directories\n\
 \  -Xold                            Invoke the legacy javadoc tool\n
 
 main.Xusage.foot=\
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/MemoryFileManager.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/MemoryFileManager.java	Thu May 12 11:03:07 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
@@ -231,6 +231,7 @@
     }
 
     // Make compatible with Jigsaw
+    @DefinedBy(Api.COMPILER)
     public String inferModuleName(Location location) {
         try {
             if (inferModuleNameMethod == null) {
@@ -249,6 +250,7 @@
     }
 
     // Make compatible with Jigsaw
+    @DefinedBy(Api.COMPILER)
     public Iterable<Set<Location>> listModuleLocations(Location location) throws IOException {
         try {
             if (listModuleLocationsMethod == null) {
--- a/langtools/test/ProblemList.txt	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/test/ProblemList.txt	Thu May 12 11:03:07 2016 -0700
@@ -95,5 +95,6 @@
 #
 # jdeps 
 
-tools/jdeps/modules/GenModuleInfo.java                                          8152502    windows-all    fails to clean up files
+tools/jdeps/modules/GenModuleInfo.java                                          8152502,8153481    generic-all    fails to clean up files, java.util.HashMap$Node cannot be cast to java.util.HashMap$TreeNode
+tools/jdeps/modules/ModuleTest.java                                             8153481    generic-all    java.util.HashMap$Node cannot be cast to java.util.HashMap$TreeNode
 
--- a/langtools/test/TEST.ROOT	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/test/TEST.ROOT	Thu May 12 11:03:07 2016 -0700
@@ -14,5 +14,8 @@
 # Group definitions
 groups=TEST.groups
 
-# Tests using jtreg 4.2 b01 features
-requiredVersion=4.2 b01
+# Tests using jtreg 4.2 b02 features
+requiredVersion=4.2 b02
+
+# Use new form of -Xpatch
+useNewXpatch=true
--- a/langtools/test/TEST.groups	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/test/TEST.groups	Thu May 12 11:03:07 2016 -0700
@@ -28,11 +28,13 @@
     jdk \
     lib \
     tools \
-    -jdk/jshell/ToolReloadTest.java
+    -jdk/jshell/ToolReloadTest.java \
+    -jdk/jshell/ToolLocaleMessageTest.java
 
 # (Almost) no langtools tests are tier 2.
 tier2 = \
-    jdk/jshell/ToolReloadTest.java
+    jdk/jshell/ToolReloadTest.java \
+    jdk/jshell/ToolLocaleMessageTest.java
 
 # No langtools tests are tier 3 either.
 tier3 = 
--- a/langtools/test/jdk/jshell/ToolLocaleMessageTest.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/test/jdk/jshell/ToolLocaleMessageTest.java	Thu May 12 11:03:07 2016 -0700
@@ -32,6 +32,7 @@
  *          jdk.jshell/jdk.internal.jshell.tool
  * @build KullaTesting TestingInputStream toolbox.ToolBox Compiler
  * @run testng ToolLocaleMessageTest
+ * @key intermittent
  */
 
 import java.util.Locale;
--- a/langtools/test/tools/all/RunCodingRules.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/test/tools/all/RunCodingRules.java	Thu May 12 11:03:07 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
@@ -25,15 +25,14 @@
  * @test
  * @bug 8043643
  * @summary Run the langtools coding rules over the langtools source code.
- * @modules java.base/sun.reflect.annotation
- *          java.logging
- *          java.xml
- *          jdk.compiler/com.sun.tools.javac.resources
- *          jdk.compiler/com.sun.tools.javac.util
+ * @modules jdk.compiler/com.sun.tools.javac.util
  */
 
 
 import java.io.*;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -58,16 +57,18 @@
 
     public void run() throws Exception {
         Path testSrc = Paths.get(System.getProperty("test.src", "."));
-        Path targetDir = Paths.get(System.getProperty("test.classes", "."));
+        Path targetDir = Paths.get(".");
         List<Path> sourceDirs = null;
         Path crulesDir = null;
+        Path mainSrcDir = null;
         for (Path d = testSrc; d != null; d = d.getParent()) {
             if (Files.exists(d.resolve("TEST.ROOT"))) {
                 d = d.getParent();
                 Path toolsPath = d.resolve("make/tools");
                 if (Files.exists(toolsPath)) {
+                    mainSrcDir = d.resolve("src");
                     crulesDir = toolsPath;
-                    sourceDirs = Files.walk(d.resolve("src"), 1)
+                    sourceDirs = Files.walk(mainSrcDir, 1)
                                       .map(p -> p.resolve("share/classes"))
                                       .filter(p -> Files.isDirectory(p))
                                       .collect(Collectors.toList());
@@ -86,7 +87,10 @@
             DiagnosticListener<JavaFileObject> noErrors = diagnostic -> {
                 Assert.check(diagnostic.getKind() != Diagnostic.Kind.ERROR, diagnostic.toString());
             };
+            String FS = File.separator;
+            String PS = File.pathSeparator;
 
+            //compile crules:
             List<File> crulesFiles = Files.walk(crulesDir)
                                           .filter(entry -> entry.getFileName().toString().endsWith(".java"))
                                           .filter(entry -> entry.getParent().endsWith("crules"))
@@ -96,12 +100,11 @@
             Path crulesTarget = targetDir.resolve("crules");
             Files.createDirectories(crulesTarget);
             List<String> crulesOptions = Arrays.asList(
-                    "-XaddExports:"
-                        + "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED,"
-                        + "jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED,"
-                        + "jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED,"
-                        + "jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED,"
-                        + "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
+                    "-XaddExports:jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
+                    "-XaddExports:jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED",
+                    "-XaddExports:jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED",
+                    "-XaddExports:jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED",
+                    "-XaddExports:jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
                     "-d", crulesTarget.toString());
             javaCompiler.getTask(null, fm, noErrors, crulesOptions, null,
                     fm.getJavaFileObjectsFromFiles(crulesFiles)).call();
@@ -111,6 +114,47 @@
                 metaInfServices.write("crules.CodingRulesAnalyzerPlugin\n");
             }
 
+            //generate CompilerProperties.java:
+            List<File> propertiesParserFiles =
+                    Files.walk(crulesDir.resolve("propertiesparser"))
+                         .filter(entry -> entry.getFileName().toString().endsWith(".java"))
+                         .map(entry -> entry.toFile())
+                         .collect(Collectors.toList());
+
+            Path propertiesParserTarget = targetDir.resolve("propertiesParser");
+            Files.createDirectories(propertiesParserTarget);
+            List<String> propertiesParserOptions = Arrays.asList(
+                    "-d", propertiesParserTarget.toString());
+            javaCompiler.getTask(null, fm, noErrors, propertiesParserOptions, null,
+                    fm.getJavaFileObjectsFromFiles(propertiesParserFiles)).call();
+
+            Path genSrcTarget = targetDir.resolve("gensrc");
+
+            ClassLoader propertiesParserLoader = new URLClassLoader(new URL[] {
+                propertiesParserTarget.toUri().toURL(),
+                crulesDir.toUri().toURL()
+            });
+            Class propertiesParserClass =
+                    Class.forName("propertiesparser.PropertiesParser", false, propertiesParserLoader);
+            Method propertiesParserRun =
+                    propertiesParserClass.getDeclaredMethod("run", String[].class, PrintStream.class);
+            String compilerProperties =
+                    "jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties";
+            Path propertiesPath = mainSrcDir.resolve(compilerProperties.replace("/", FS));
+            Path genSrcTargetDir = genSrcTarget.resolve(mainSrcDir.relativize(propertiesPath.getParent()));
+
+            Files.createDirectories(genSrcTargetDir);
+            String[] propertiesParserRunOptions = new String[] {
+                "-compile", propertiesPath.toString(), genSrcTargetDir.toString()
+            };
+
+            Object result = propertiesParserRun.invoke(null, propertiesParserRunOptions, System.err);
+
+            if (!(result instanceof Boolean) || !(Boolean) result) {
+                throw new AssertionError("Cannot parse properties: " + result);
+            }
+
+            //compile langtools sources with crules enabled:
             List<File> sources = sourceDirs.stream()
                                            .flatMap(dir -> silentFilesWalk(dir))
                                            .filter(entry -> entry.getFileName().toString().endsWith(".java"))
@@ -119,9 +163,13 @@
 
             Path sourceTarget = targetDir.resolve("classes");
             Files.createDirectories(sourceTarget);
-            String processorPath = crulesTarget.toString() + File.pathSeparator + crulesDir.toString();
+            String processorPath = crulesTarget + PS + crulesDir;
+
             List<String> options = Arrays.asList(
                     "-d", sourceTarget.toString(),
+                    "-modulesourcepath", mainSrcDir + FS + "*" + FS + "share" + FS + "classes" + PS
+                                       + genSrcTarget + FS + "*" + FS + "share" + FS + "classes",
+                    "-XDaccessInternalAPI",
                     "-processorpath", processorPath,
                     "-Xplugin:coding_rules");
             javaCompiler.getTask(null, fm, noErrors, options, null,
--- a/langtools/test/tools/javac/T6358024.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/test/tools/javac/T6358024.java	Thu May 12 11:03:07 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2015, 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
@@ -69,10 +69,10 @@
 
         JavacTool tool = JavacTool.create();
         List<String> flags = new ArrayList<String>();
-        flags.add("-XaddExports:"
-                + "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED,"
-                + "jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED,"
-                + "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED");
+        flags.addAll(Arrays.asList(
+                "-XaddExports:jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
+                "-XaddExports:jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED",
+                "-XaddExports:jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED"));
         for (Option opt: opts) {
             flags.add(opt.name);
             for (Object arg : opt.args)
--- a/langtools/test/tools/javac/T6358166.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/test/tools/javac/T6358166.java	Thu May 12 11:03:07 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2015, 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
@@ -42,8 +42,7 @@
 import com.sun.tools.javac.api.JavacTool;
 import com.sun.tools.javac.file.JavacFileManager;
 import com.sun.tools.javac.main.JavaCompiler;
-import com.sun.tools.javac.util.*;
-import com.sun.tools.javac.util.List; // disambiguate
+import com.sun.tools.javac.util.Context;
 
 
 @SupportedAnnotationTypes("*")
@@ -56,22 +55,26 @@
         JavacFileManager fm = new JavacFileManager(new Context(), false, null);
         JavaFileObject f = fm.getJavaFileObject(testSrc + File.separatorChar + self + ".java");
 
-        String addExports = "-XaddExports:"
-                + "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED,"
-                + "jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED,"
-                + "jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED,"
-                + "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED";
+        List<String> addExports = Arrays.asList(
+                "-XaddExports:jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
+                "-XaddExports:jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED",
+                "-XaddExports:jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED",
+                "-XaddExports:jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED");
 
         test(fm, f, addExports, "-verbose", "-d", ".");
 
         test(fm, f, addExports, "-verbose", "-d", ".", "-XprintRounds", "-processorpath", ".", "-processor", self);
     }
 
-    static void test(JavacFileManager fm, JavaFileObject f, String... args) throws Throwable {
+    static void test(JavacFileManager fm, JavaFileObject f, List<String> addExports, String... args) throws Throwable {
+        List<String> allArgs = new ArrayList<>();
+        allArgs.addAll(addExports);
+        allArgs.addAll(Arrays.asList(args));
+
         Context context = new Context();
 
         JavacTool tool = JavacTool.create();
-        JavacTaskImpl task = (JavacTaskImpl) tool.getTask(null, fm, null, Arrays.asList(args), null, List.of(f), context);
+        JavacTaskImpl task = (JavacTaskImpl) tool.getTask(null, fm, null, allArgs, null, List.of(f), context);
         task.call();
 
         JavaCompiler c = JavaCompiler.instance(context);
--- a/langtools/test/tools/javac/T6406771.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/test/tools/javac/T6406771.java	Thu May 12 11:03:07 2016 -0700
@@ -50,9 +50,8 @@
             JavaFileObject f = fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, self+".java"))).iterator().next();
 
             List<String> opts = Arrays.asList(
-                "-XaddExports:"
-                + "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED,"
-                + "jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED",
+                "-XaddExports:jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
+                "-XaddExports:jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED",
                 "-XDaccessInternalAPI",
                 "-d", ".",
                 "-processorpath", testClasses,
--- a/langtools/test/tools/javac/T8010737/ParameterNamesAreNotCopiedToAnonymousInitTest.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/test/tools/javac/T8010737/ParameterNamesAreNotCopiedToAnonymousInitTest.java	Thu May 12 11:03:07 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
@@ -143,12 +143,11 @@
                     Arrays.asList(new File(System.getProperty("test.src"),
                     this.getClass().getName() + ".java")));
             java.util.List<String> options = Arrays.asList(
-                "-XaddExports:"
-                    + "jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED,"
-                    + "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED,"
-                    + "jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED,"
-                    + "jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED,"
-                    + "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
+                "-XaddExports:jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED",
+                "-XaddExports:jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
+                "-XaddExports:jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED",
+                "-XaddExports:jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED",
+                "-XaddExports:jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
                 "-d", System.getProperty("user.dir")
             );
             JavacTask task = (JavacTask) c.getTask(null, fm, null, options, null, fos);
--- a/langtools/test/tools/javac/api/TestJavacTaskScanner.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/test/tools/javac/api/TestJavacTaskScanner.java	Thu May 12 11:03:07 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
@@ -73,11 +73,11 @@
         final Iterable<? extends JavaFileObject> compilationUnits =
             fm.getJavaFileObjects(new File[] {file});
         StandardJavaFileManager fm = getLocalFileManager(tool, null, null);
-        java.util.List<String> options = Arrays.asList("-XaddExports:"
-                + "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED,"
-                + "jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED,"
-                + "jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED,"
-                + "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED");
+        java.util.List<String> options = Arrays.asList(
+                "-XaddExports:jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
+                "-XaddExports:jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED",
+                "-XaddExports:jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED",
+                "-XaddExports:jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED");
         task = (JavacTaskImpl)tool.getTask(null, fm, null, options, null, compilationUnits);
         task.getContext().put(ScannerFactory.scannerFactoryKey,
                 new MyScanner.Factory(task.getContext(), this));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/api/ToolProvider/ToolProviderTest.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,45 @@
+/*
+ * 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.tools.ToolProvider;
+import java.util.Objects;
+
+/**
+ * @test
+ * @bug 8154190
+ * @summary Test javax.tools.ToolProvider running with security manager
+ * @modules java.compiler
+ *          jdk.compiler
+ * @run main/othervm ToolProviderTest
+ */
+
+// run in other vm to ensure the initialization code path is exercised.
+public class ToolProviderTest {
+    public static void main(String... args) {
+        System.setSecurityManager(new SecurityManager());
+
+        Objects.requireNonNull(ToolProvider.getSystemDocumentationTool());
+        Objects.requireNonNull(ToolProvider.getSystemJavaCompiler());
+        Objects.requireNonNull(ToolProvider.getSystemToolClassLoader());
+    }
+}
--- a/langtools/test/tools/javac/api/ToolProvider/ToolProviderTest1.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/test/tools/javac/api/ToolProvider/ToolProviderTest1.java	Thu May 12 11:03:07 2016 -0700
@@ -43,7 +43,7 @@
 public class ToolProviderTest1 {
     public static void main(String... args) throws Exception {
         if (args.length > 0) {
-            System.err.println(Class.forName(args[0], true, null));
+            System.err.println(Class.forName(args[0], true, ClassLoader.getSystemClassLoader()));
             return;
         }
 
--- a/langtools/test/tools/javac/diags/CheckResourceKeys.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/test/tools/javac/diags/CheckResourceKeys.java	Thu May 12 11:03:07 2016 -0700
@@ -294,6 +294,7 @@
             "opt.Xlint.desc.",
             "count.",
             "illegal.",
+            "java.",
             "javac.",
             "verbose.",
             "locn."
--- a/langtools/test/tools/javac/diags/examples.not-yet.txt	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/test/tools/javac/diags/examples.not-yet.txt	Thu May 12 11:03:07 2016 -0700
@@ -146,6 +146,7 @@
 compiler.err.package.in.other.module
 compiler.err.processorpath.no.processormodulepath
 compiler.err.service.definition.is.inner
+compiler.err.service.definition.is.enum
 compiler.err.service.implementation.doesnt.have.a.no.args.constructor
 compiler.err.service.implementation.is.abstract
 compiler.err.service.implementation.is.inner
--- a/langtools/test/tools/javac/file/T7018098.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/test/tools/javac/file/T7018098.java	Thu May 12 11:03:07 2016 -0700
@@ -60,10 +60,9 @@
         _assert(!testDir.exists());
 
         compile(
-            "-XaddExports:"
-                + "jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED,"
-                + "jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED,"
-                + "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
+            "-XaddExports:jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED",
+            "-XaddExports:jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED",
+            "-XaddExports:jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
             "-XDaccessInternalAPI",
             "-proc:only",
             "-processor", myName,
@@ -74,10 +73,9 @@
         _assert(testDir.exists());
 
         compile(
-            "-XaddExports:"
-                + "jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED,"
-                + "jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED,"
-                + "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
+            "-XaddExports:jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED",
+            "-XaddExports:jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED",
+            "-XaddExports:jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
             "-XDaccessInternalAPI",
             "-proc:only",
             "-processor", myName,
--- a/langtools/test/tools/javac/modules/AddLimitMods.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/test/tools/javac/modules/AddLimitMods.java	Thu May 12 11:03:07 2016 -0700
@@ -40,6 +40,7 @@
 import java.io.File;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.util.AbstractMap.SimpleEntry;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -69,7 +70,6 @@
 import toolbox.JavacTask;
 import toolbox.JavaTask;
 import toolbox.Task;
-import toolbox.ToolBox;
 
 public class AddLimitMods extends ModuleTestBase {
 
@@ -176,6 +176,58 @@
     }
 
     @Test
+    public void testObservableForUnnamed(Path base) throws Exception {
+        Path src = base.resolve("src");
+
+        tb.writeJavaFiles(src,
+                          "package test;\n" +
+                          "@javax.annotation.Generated(\"test\")\n" +
+                          "public class Test {\n" +
+                          "    com.sun.tools.javac.Main m;\n" +
+                          "    javax.xml.bind.JAXBException e;\n" +
+                          "}\n");
+
+        Path out = base.resolve("out");
+
+        Files.createDirectories(out);
+
+        for (Entry<String[], String> variant : variants) {
+            System.err.println("running variant: options=" + Arrays.asList(variant.getKey()) + ", expected log: " + variant.getValue());
+
+            List<String> options = new ArrayList<>();
+            options.add("-XDrawDiagnostics");
+            options.addAll(Arrays.asList(variant.getKey()));
+
+            String log = new JavacTask(tb)
+                    .options(options.toArray(new String[0]))
+                    .outdir(out)
+                    .files(findJavaFiles(src))
+                    .run(variant.getValue() == null ? Task.Expect.SUCCESS : Task.Expect.FAIL)
+                    .writeAll()
+                    .getOutput(Task.OutputKind.DIRECT);
+
+            log = log.replace(System.getProperty("line.separator"), "\n");
+
+            if (variant.getValue() != null && !log.equals(variant.getValue())) {
+                throw new AssertionError();
+            }
+        }
+    }
+
+    private static final List<Entry<String[], String>> variants = Arrays.asList(
+            new SimpleEntry<String[], String>(new String[] {},
+                                              "Test.java:2:18: compiler.err.doesnt.exist: javax.annotation\n"
+                                            + "Test.java:5:19: compiler.err.doesnt.exist: javax.xml.bind\n"
+                                            + "2 errors\n"),
+            new SimpleEntry<String[], String>(new String[] {"-addmods", "java.annotations.common,java.xml.bind"},
+                                              null),
+            new SimpleEntry<String[], String>(new String[] {"-limitmods", "java.xml.ws,jdk.compiler"},
+                                              null),
+            new SimpleEntry<String[], String>(new String[] {"-addmods", "ALL-SYSTEM"},
+                                              null)
+    );
+
+    @Test
     public void testAllModulePath(Path base) throws Exception {
         if (Files.isDirectory(base))
             tb.cleanDirectory(base);
--- a/langtools/test/tools/javac/modules/UsesTest.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/test/tools/javac/modules/UsesTest.java	Thu May 12 11:03:07 2016 -0700
@@ -82,6 +82,29 @@
     }
 
     @Test
+    public void testEnumAsAService(Path base) throws Exception {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src,
+                "module m { uses pkg.EnumST; }",
+                "package pkg; public enum EnumST {A, B}");
+        Path classes = base.resolve("classes");
+        Files.createDirectories(classes);
+
+        List<String> output = new JavacTask(tb)
+                .options("-XDrawDiagnostics")
+                .outdir(classes)
+                .files(tb.findJavaFiles(src))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+        List<String> expected = Arrays.asList("module-info.java:1:20: compiler.err.service.definition.is.enum: pkg.EnumST",
+                "1 error");
+        if (!output.containsAll(expected)) {
+            throw new Exception("Expected output not found");
+        }
+    }
+
+    @Test
     public void testSimpleAnnotation(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
--- a/langtools/test/tools/javac/processing/loader/testClose/TestClose.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/test/tools/javac/processing/loader/testClose/TestClose.java	Thu May 12 11:03:07 2016 -0700
@@ -132,9 +132,8 @@
                         new MemFile("AnnoProc.java", annoProc),
                         new MemFile("Callback.java", callback));
                 List<String> options = Arrays.asList(
-                        "-XaddExports:"
-                        + "jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED,"
-                        + "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
+                        "-XaddExports:jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED",
+                        "-XaddExports:jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
                         "-XDaccessInternalAPI");
                 JavacTask task = tool.getTask(null, fm, null, options, null, files);
                 check(task.call());
--- a/langtools/test/tools/javac/processing/loader/testClose/TestClose2.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/test/tools/javac/processing/loader/testClose/TestClose2.java	Thu May 12 11:03:07 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
@@ -92,10 +92,9 @@
         Iterable<? extends JavaFileObject> files =
                 fm.getJavaFileObjects(new File(testSrc, TestClose2.class.getName() + ".java"));
         List<String> options = Arrays.asList(
-                "-XaddExports:"
-                    + "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED,"
-                    + "jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED,"
-                    + "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
+                "-XaddExports:jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
+                "-XaddExports:jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED",
+                "-XaddExports:jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
                 "-processor", TestClose2.class.getName());
 
         JavacTask task = tool.getTask(null, fm, null, options, null, files);
--- a/langtools/test/tools/javac/processing/model/testgetallmembers/Main.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/test/tools/javac/processing/model/testgetallmembers/Main.java	Thu May 12 11:03:07 2016 -0700
@@ -33,7 +33,6 @@
 import java.io.File;
 import java.util.*;
 import java.util.Map.Entry;
-import java.util.stream.StreamSupport;
 
 import javax.lang.model.element.Element;
 import javax.lang.model.element.ElementKind;
@@ -42,14 +41,12 @@
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.util.Elements;
 import javax.tools.*;
-import javax.tools.JavaFileManager.Location;
 
 import com.sun.source.util.JavacTask;
 import com.sun.tools.javac.model.JavacElements;
 
 import static javax.tools.StandardLocation.CLASS_PATH;
 import static javax.tools.StandardLocation.PLATFORM_CLASS_PATH;
-import static javax.tools.StandardLocation.SYSTEM_MODULES;
 import static javax.tools.JavaFileObject.Kind.CLASS;
 
 
@@ -67,11 +64,13 @@
     static JavacTask javac;
     static Elements elements;
 
+    static List<String> addmods_ALL_SYSTEM = Arrays.asList("-addmods", "ALL-SYSTEM");
+
     public static void main(String[] args) throws Exception {
         JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
         try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) {
             fm.setLocation(CLASS_PATH, Collections.<File>emptyList());
-            JavacTask javac = (JavacTask)tool.getTask(null, fm, null, null, null, null);
+            JavacTask javac = (JavacTask)tool.getTask(null, fm, null, addmods_ALL_SYSTEM, null, null);
             Elements elements = javac.getElements();
 
             final Map<String, Set<String>> packages = new LinkedHashMap<>();
@@ -109,11 +108,12 @@
             javac = null;
             elements = null;
 
-            javac = (JavacTask)tool.getTask(null, fm, null, null, null, null);
+            javac = (JavacTask)tool.getTask(null, fm, null, addmods_ALL_SYSTEM, null, null);
             elements = javac.getElements();
 
             for (Entry<String, Set<String>> module2Packages : packages.entrySet()) {
                 ModuleElement me = elements.getModuleElement(module2Packages.getKey());
+                me.getClass();
                 for (String name : module2Packages.getValue()) {
                     PackageElement pe = ((JavacElements) elements).getPackageElement(me, name);
                     for (Element e : pe.getEnclosedElements()) {
--- a/langtools/test/tools/javac/util/T6597678.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/test/tools/javac/util/T6597678.java	Thu May 12 11:03:07 2016 -0700
@@ -59,9 +59,8 @@
         PrintWriter pw = new PrintWriter(sw);
 
         compile(sw, pw,
-            "-XaddExports:"
-                + "jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED,"
-                + "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
+            "-XaddExports:jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED",
+            "-XaddExports:jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
             "-XDaccessInternalAPI",
             "-proc:only",
             "-processor", myName,
--- a/langtools/test/tools/jdeps/APIDeps.java	Thu May 12 20:43:37 2016 +0400
+++ b/langtools/test/tools/jdeps/APIDeps.java	Thu May 12 11:03:07 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
@@ -65,11 +65,9 @@
         for (String s : testModules.split("\\s+")) {
             if (s.isEmpty()) continue;
             if (s.indexOf('/') != -1)
-                addExports.add(s.trim() + "=ALL-UNNAMED");
+                addExports.add("-XaddExports:" + s.trim() + "=ALL-UNNAMED");
         }
-        if (addExports.size() > 0) {
-            options.add(addExports.stream().collect(Collectors.joining(",", "-XaddExports:", "")));
-        }
+        options.addAll(addExports);
 
         for (String dir : srcDirs) {
             Path source = testsrc.resolve(dir);
--- a/make/CompileJavaModules.gmk	Thu May 12 20:43:37 2016 +0400
+++ b/make/CompileJavaModules.gmk	Thu May 12 11:03:07 2016 -0700
@@ -99,7 +99,7 @@
 ################################################################################
 
 java.desktop_ADD_JAVAC_FLAGS := -Xdoclint:all/protected,-reference \
-    '-Xdoclint/package:java.*,javax.*'
+    '-Xdoclint/package:java.*,javax.*' -Xlint:-deprecation 
 java.desktop_COPY := .gif .png .wav .txt .xml .css .pf
 java.desktop_CLEAN := iio-plugin.properties cursors.properties
 
--- a/make/CreateBuildJdkCopy.gmk	Thu May 12 20:43:37 2016 +0400
+++ b/make/CreateBuildJdkCopy.gmk	Thu May 12 11:03:07 2016 -0700
@@ -29,13 +29,15 @@
 include MakeBase.gmk
 include Modules.gmk
 
-MODULES_TO_COPY := $(call FindTransitiveDepsForModule, jdk.jlink) jdk.jlink
+MODULES_TO_COPY := $(sort \
+    $(foreach m, jdk.jlink $(INTERIM_IMAGE_MODULES), \
+      $(call FindTransitiveDepsForModule, $m) $m))
 
 ################################################################################
 # Copy the modules needed to run jlink and jmod. Use bulk copy instead of
 # SetupCopyFiles since there are so many files.
 
-COPY_CLASSES_TARGET := $(BUILDJDK_OUTPUTDIR)/jdk/modules/_buildjdk-copy-maker
+COPY_CLASSES_TARGET := $(BUILDJDK_OUTPUTDIR)/jdk/modules/java.base/_the.buildjdk-copy-marker
 
 $(COPY_CLASSES_TARGET): $(call CacheFind, $(wildcard \
     $(addprefix $(JDK_OUTPUTDIR)/modules/, $(MODULES_TO_COPY))))
@@ -49,15 +51,6 @@
 
 TARGETS += $(COPY_CLASSES_TARGET)
 
-#$(eval $(call SetupCopyFiles, COPY_JDK_MODULES, \
-    SRC := $(BUILD_OUTPUT), \
-    DEST := $(BUILDJDK_OUTPUTDIR), \
-    FILES := $(call DoubleDollar, $(call DoubleDollar, $(call CacheFind, $(wildcard \
-        $(addprefix $(JDK_OUTPUTDIR)/modules/, $(MODULES_TO_COPY)))))), \
-))
-
-#TARGETS += $(COPY_JDK_MODULES)
-
 ################################################################################
 
 $(eval $(call SetupCopyFiles, COPY_SUPPORT_HEADERS, \
--- a/make/CreateJmods.gmk	Thu May 12 20:43:37 2016 +0400
+++ b/make/CreateJmods.gmk	Thu May 12 11:03:07 2016 -0700
@@ -1,4 +1,4 @@
-#
+
 # Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
@@ -35,6 +35,8 @@
 
 ################################################################################
 
+JMODS_DIR := $(IMAGES_OUTPUTDIR)/jmods
+
 LIBS_DIR := $(firstword $(wildcard $(addsuffix /$(MODULE), \
     $(SUPPORT_OUTPUTDIR)/modules_libs-stripped $(IMPORT_MODULES_LIBS))))
 CMDS_DIR := $(firstword $(wildcard $(addsuffix /$(MODULE), \
@@ -64,15 +66,35 @@
   DEPS += $(call CacheFind, $(CLASSES_DIR))
 endif
 
-# Add dependencies on other jmod files
-DEPS += $(patsubst %, $(IMAGES_OUTPUTDIR)/jmods/%.jmod, \
-    $(call FindDepsForModule, $(MODULE)))
+# Add dependencies on other jmod files. Only java.base needs access to other
+# jmods.
+ifeq ($(MODULE), java.base)
+  # When creating a BUILDJDK, we don't need to add hashes to java.base
+  ifneq ($(CREATING_BUILDJDK), true)
+    DEPS += $(patsubst %, $(JMODS_DIR)/%.jmod, \
+        $(filter-out java.base, $(call FindAllModules)))
+
+    # TODO: find modules that directly and indirectly depend on upgradeable
+    # modules
+    EXCLUDE_HASH_MODULES := $(UPGRADEABLE_MODULES) \
+      java.se.ee \
+      jdk.rmic \
+      jdk.xml.bind \
+      jdk.xml.ws \
+      #
+
+    EXCLUDE_PATTERN := $(strip $(subst $(SPACE),|,$(strip $(EXCLUDE_HASH_MODULES))))
+
+    JMOD_FLAGS += --modulepath $(JMODS_DIR) \
+        --hash-modules '^(?!$(EXCLUDE_PATTERN))'
+  endif
+endif
 
 # TODO: What about headers?
 # Create jmods in a temp dir and then move them into place to keep the
 # module path in $(IMAGES_OUTPUTDIR)/jmods valid at all times.
-$(IMAGES_OUTPUTDIR)/jmods/$(MODULE).jmod: $(DEPS)
-	$(call LogWarn, Creating $(notdir $@))
+$(JMODS_DIR)/$(MODULE).jmod: $(DEPS)
+	$(call LogWarn, Creating $(patsubst $(OUTPUT_ROOT)/%, %, $@))
 	$(call MakeDir, $(@D) $(SUPPORT_OUTPUTDIR)/jmods)
 	$(RM) $@ $(SUPPORT_OUTPUTDIR)/jmods/$(notdir $@)
 	$(JMOD) create \
@@ -80,8 +102,7 @@
             --os-name $(REQUIRED_OS_NAME) \
             --os-arch $(OPENJDK_TARGET_CPU_LEGACY) \
             --os-version $(REQUIRED_OS_VERSION) \
-	    --modulepath $(IMAGES_OUTPUTDIR)/jmods\
-            --hash-dependencies '.*' \
+	        --modulepath $(JMODS_DIR) \
             --exclude '**{_the.*,*.diz,*.debuginfo,*.dSYM/**,*.pdb,*.map}' \
 	    $(JMOD_FLAGS) $(SUPPORT_OUTPUTDIR)/jmods/$(notdir $@)
 	$(MV) $(SUPPORT_OUTPUTDIR)/jmods/$(notdir $@) $@
--- a/make/Images.gmk	Thu May 12 20:43:37 2016 +0400
+++ b/make/Images.gmk	Thu May 12 11:03:07 2016 -0700
@@ -56,19 +56,11 @@
 JRE_COMPACT2_MODULES := $(JRE_COMPACT1_MODULES) java.compact2 $(COMPACT2_EXTRA_MODULES)
 JRE_COMPACT3_MODULES := $(JRE_COMPACT2_MODULES) java.compact3 $(COMPACT3_EXTRA_MODULES)
 
-# Replacing double-comma with a single comma is to workaround the issue
-# with some version of make on windows that doesn't substitute spaces
-# with one comma properly as with make 4.0
-SubstComma = \
-    $(strip \
-        $(subst $(COMMA)$(COMMA),$(COMMA),$(subst $(SPACE),$(COMMA),$(strip $1))) \
-    )
-
-JRE_MODULES_LIST := $(call SubstComma, $(JRE_MODULES))
-JDK_MODULES_LIST := $(call SubstComma, $(JDK_MODULES))
-JRE_COMPACT1_MODULES_LIST := $(call SubstComma, $(JRE_COMPACT1_MODULES))
-JRE_COMPACT2_MODULES_LIST := $(call SubstComma, $(JRE_COMPACT2_MODULES))
-JRE_COMPACT3_MODULES_LIST := $(call SubstComma, $(JRE_COMPACT3_MODULES))
+JRE_MODULES_LIST := $(call CommaList, $(JRE_MODULES))
+JDK_MODULES_LIST := $(call CommaList, $(JDK_MODULES))
+JRE_COMPACT1_MODULES_LIST := $(call CommaList, $(JRE_COMPACT1_MODULES))
+JRE_COMPACT2_MODULES_LIST := $(call CommaList, $(JRE_COMPACT2_MODULES))
+JRE_COMPACT3_MODULES_LIST := $(call CommaList, $(JRE_COMPACT3_MODULES))
 
 ################################################################################
 # Release file
@@ -364,6 +356,23 @@
 JDK_TARGETS += $(JDK_IMAGE_DIR)/src.zip
 
 ################################################################################
+# classlist
+
+$(eval $(call SetupCopyFiles, JDK_COPY_CLASSLIST, \
+    FILES := $(SUPPORT_OUTPUTDIR)/classlist/classlist, \
+    DEST := $(JDK_IMAGE_DIR)/lib, \
+))
+
+JDK_TARGETS += $(JDK_COPY_CLASSLIST)
+
+$(eval $(call SetupCopyFiles, JRE_COPY_CLASSLIST, \
+    FILES := $(SUPPORT_OUTPUTDIR)/classlist/classlist, \
+    DEST := $(JRE_IMAGE_DIR)/lib, \
+))
+
+JRE_TARGETS += $(JRE_COPY_CLASSLIST)
+
+################################################################################
 # /demo dir
 ifneq ($(findstring images, $(MAKECMDGOALS)), )
   $(eval $(call SetupCopyFiles, JDK_COPY_DEMOS, \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/InterimImage.gmk	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,60 @@
+#
+# 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.
+#
+
+default: all
+
+include $(SPEC)
+include MakeBase.gmk
+include Modules.gmk
+
+################################################################################
+
+# Use this file inside the image as target for make rule
+JIMAGE_TARGET_FILE := bin/java$(EXE_SUFFIX)
+
+INTERIM_MODULES_LIST := $(call CommaList, $(INTERIM_IMAGE_MODULES))
+
+JMODS := $(patsubst %, $(IMAGES_OUTPUTDIR)/jmods/%.jmod, $(INTERIM_IMAGE_MODULES))
+
+JLINK_TOOL := $(JLINK) \
+    --modulepath $(IMAGES_OUTPUTDIR)/jmods \
+    --endian $(OPENJDK_BUILD_CPU_ENDIAN)
+
+$(INTERIM_IMAGE_DIR)/$(JIMAGE_TARGET_FILE): $(JMODS) \
+    $(call DependOnVariable, INTERIM_MODULES_LIST)
+	$(ECHO) Creating interim jimage
+	$(RM) -r $(INTERIM_IMAGE_DIR)
+	$(JLINK_TOOL) \
+	    --output $(INTERIM_IMAGE_DIR) \
+	    --addmods $(INTERIM_MODULES_LIST)
+	$(TOUCH) $@
+
+TARGETS += $(INTERIM_IMAGE_DIR)/$(JIMAGE_TARGET_FILE)
+
+################################################################################
+
+all: $(TARGETS)
+
+.PHONY: all
--- a/make/Main.gmk	Thu May 12 20:43:37 2016 +0400
+++ b/make/Main.gmk	Thu May 12 11:03:07 2016 -0700
@@ -348,25 +348,35 @@
 ################################################################################
 # Cross compilation support
 
-ifeq ($(CREATE_BUILDJDK), true)
+ifeq ($(CREATING_BUILDJDK), true)
   # This target is only called by the recursive call below.
-  create-buildjdk-compile-hotspot-helper: hotspot
-  create-buildjdk-compile-modules-helper: jdk.jlink-launchers java.base-copy \
-      jdk.jdeps-launchers
+  create-buildjdk-interim-image-helper: interim-image jdk.jlink-launchers \
+      java.base-copy jdk.jdeps-launchers
 endif
 
 create-buildjdk-copy:
 	+($(CD) $(SRC_ROOT)/make && $(MAKE) $(MAKE_ARGS) -f CreateBuildJdkCopy.gmk)
 
-create-buildjdk-compile-hotspot create-buildjdk-compile-modules:
+create-buildjdk-interim-image:
 	+($(CD) $(SRC_ROOT)/make && $(MAKE) $(MAKE_ARGS) -f Main.gmk \
 	    $@-helper \
 	    SPEC=$(dir $(SPEC))buildjdk-spec.gmk \
 	    HOTSPOT_SPEC=$(dir $(SPEC))buildjdk-spec.gmk \
 	    CREATING_BUILDJDK=true)
 
-ALL_TARGETS += create-buildjdk-copy create-buildjdk-compile-hotspot \
-    create-buildjdk-compile-modules
+ALL_TARGETS += create-buildjdk-copy create-buildjdk-interim-image
+
+################################################################################
+# The interim-image is a small jlinked image that is used to generate artifacts 
+# at build time for use when linking the real images.
+
+interim-image:
+	+($(CD) $(SRC_ROOT)/make && $(MAKE) $(MAKE_ARGS) -f InterimImage.gmk)
+
+generate-classlist:
+	+($(CD) $(JDK_TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f GenerateClasslist.gmk)
+
+ALL_TARGETS += interim-image generate-classlist
 
 ################################################################################
 # Build tests
@@ -522,10 +532,11 @@
   $(foreach m, $(RMIC_MODULES), $(eval $m-rmic: $m-java))
 
   # Declare dependencies from <module>-lib to <module>-java
-  # Skip modules that do not have java source. When creating a BUILD_JDK, the
-  # java compilation has already been done by the normal build and copied in.
+  # Skip modules that do not have java source.
+  # When creating a BUILDJDK, the java compilation has already been done by the
+  # normal build and copied in.
   ifneq ($(CREATING_BUILDJDK), true)
-  $(foreach m, $(filter $(JAVA_MODULES), $(LIBS_MODULES)), $(eval $m-libs: $m-java))
+    $(foreach m, $(filter $(JAVA_MODULES), $(LIBS_MODULES)), $(eval $m-libs: $m-java))
   endif
 
   # Declare dependencies from all other <module>-lib to java.base-lib
@@ -562,13 +573,21 @@
   $(foreach m, $(GENDATA_MODULES), $(eval $m-strip: $m-gendata))
   $(foreach m, $(COPY_MODULES), $(eval $m-strip: $m-copy))
 
-  # Declare dependencies between jmod targets
-  $(foreach m, $(JMOD_MODULES), \
-      $(eval $m-jmod: $(addsuffix -jmod, $(call FindDepsForModule,$m))))
+  # Declare dependencies between jmod targets. Only java.base jmod needs access
+  # to the other jmods to be built.
+  # When creating a BUILDJDK, we don't need to add hashes to java.base, thus
+  # we don't need to depend on all other jmods
+  ifneq ($(CREATING_BUILDJDK), true)
+    java.base-jmod: $(filter-out java.base-jmod, $(JMOD_TARGETS))
+  endif
 
   # Declare dependencies from <module>-jmod to all other module targets
   $(foreach m, $(STRIP_MODULES), $(eval $m-jmod: $m-strip))
-  $(foreach m, $(JAVA_MODULES), $(eval $m-jmod: $m-java))
+  # When creating a BUILDJDK, the java compilation has already been done by the
+  # normal build and copied in.
+  ifneq ($(CREATING_BUILDJDK), true)
+    $(foreach m, $(JAVA_MODULES), $(eval $m-jmod: $m-java))
+  endif
   $(foreach m, $(GENDATA_MODULES), $(eval $m-jmod: $m-gendata))
   $(foreach m, $(RMIC_MODULES), $(eval $m-jmod: $m-rmic))
   $(foreach m, $(LIBS_MODULES), $(eval $m-jmod: $m-libs))
@@ -577,10 +596,18 @@
 
   # Jmods cannot be created until we have the jlink tool ready to run, which requires
   # all java modules to be compiled and jdk.jlink-launchers.
-  $(JMOD_TARGETS): java java.base-libs jdk.jlink-launchers
+  $(JMOD_TARGETS): java.base-libs jdk.jlink-launchers
+  # When creating a BUILDJDK, the java compilation has already been done by the
+  # normal build and copied in.
+  ifneq ($(CREATING_BUILDJDK), true)
+    $(JMOD_TARGETS): java
+  endif
 
   ifeq ($(CREATE_BUILDJDK), true)
-    $(JMOD_TARGETS): create-buildjdk
+    # Avoid calling create-buildjdk from within a create-buildjdk call
+    ifneq ($(CREATING_BUILDJDK), true)
+      $(JMOD_TARGETS): create-buildjdk
+    endif
   endif
 
   zip-security: java.base-java java.security.jgss-java java.security.jgss-libs \
@@ -590,7 +617,18 @@
 
   jrtfs-jar: interim-langtools
 
-  jimages: jmods zip-source source-tips demos samples jrtfs-jar
+  ifeq ($(CREATE_BUILDJDK), true)
+    # If creating a buildjdk, the interim image needs to be based on that.
+    generate-classlist: create-buildjdk
+  else ifeq ($(EXTERNAL_BUILDJDK), false)
+    # If an external buildjdk has been provided, we skip generating an
+    # interim-image and just use the external buildjdk for generating
+    # classlist.
+    generate-classlist: interim-image
+  endif
+  generate-classlist: buildtools-jdk
+
+  jimages: jmods zip-source source-tips demos samples jrtfs-jar generate-classlist
 
   profiles: jmods zip-source source-tips jrtfs-jar
 
@@ -606,9 +644,12 @@
 
   test: jimages test-image
 
-  create-buildjdk-copy: jdk.jlink-java java.base-gendata
+  create-buildjdk-copy: jdk.jlink-java java.base-gendata \
+      $(addsuffix -java, $(INTERIM_IMAGE_MODULES))
 
-  create-buildjdk-compile-modules: create-buildjdk-copy create-buildjdk-compile-hotspot
+  create-buildjdk-interim-image: create-buildjdk-copy
+
+  interim-image: $(addsuffix -jmod, $(INTERIM_IMAGE_MODULES))
 
   test-make: clean-test-make
 
@@ -682,8 +723,7 @@
 # The "exploded image" is a locally runnable JDK in $(BUILD_OUTPUT)/jdk.
 exploded-image: $(ALL_MODULES)
 
-create-buildjdk: create-buildjdk-compile-modules create-buildjdk-copy \
-    create-buildjdk-compile-hotspot
+create-buildjdk: create-buildjdk-copy create-buildjdk-interim-image
 
 mac-bundles: mac-bundles-jdk
 
@@ -694,10 +734,14 @@
 # (and possibly other, more specific versions)
 product-images: jimages demos samples zip-security exploded-image
 
-# When cross compiling and building a partial BUILDJDK for the build host,
-# the summary generation cannot be run.
+# The module summary cannot be run when:
+# * Cross compiling and building a partial BUILDJDK for the build host
+# * An external buildjdk has been supplied since it may not match the
+#   module selection of the target jdk
 ifneq ($(CREATE_BUILDJDK), true)
-  product-images: generate-summary
+  ifeq ($(EXTERNAL_BUILDJDK), false)
+    product-images: generate-summary
+  endif
 endif
 
 ifeq ($(OPENJDK_TARGET_OS), macosx)
--- a/make/common/JavaCompilation.gmk	Thu May 12 20:43:37 2016 +0400
+++ b/make/common/JavaCompilation.gmk	Thu May 12 11:03:07 2016 -0700
@@ -181,7 +181,7 @@
   # Extract the info from the java compiler setup.
   $1_JVM := $$($$($1_SETUP)_JVM)
   $1_JAVAC := $$($$($1_SETUP)_JAVAC)
-  $1_FLAGS := $$($$($1_SETUP)_FLAGS) $(JAVAC_FLAGS) $$($1_ADD_JAVAC_FLAGS)
+  $1_FLAGS := $$($$($1_SETUP)_FLAGS) $$($1_ADD_JAVAC_FLAGS) $(JAVAC_FLAGS)
   ifneq ($$($1_CLASSPATH), )
     $1_FLAGS += -cp $$(call PathList, $$($1_CLASSPATH))
   endif
--- a/make/common/MakeBase.gmk	Thu May 12 20:43:37 2016 +0400
+++ b/make/common/MakeBase.gmk	Thu May 12 11:03:07 2016 -0700
@@ -742,6 +742,17 @@
     $(if $(filter $1, $(JVM_VARIANTS)), true, false))
 
 ################################################################################
+# Converts a space separated list to a comma separated list.
+#
+# Replacing double-comma with a single comma is to workaround the issue with
+# some version of make on windows that doesn't substitute spaces with one comma
+# properly.
+CommaList = \
+  $(strip \
+      $(subst $(COMMA)$(COMMA),$(COMMA),$(subst $(SPACE),$(COMMA),$(strip $1))) \
+  )
+
+################################################################################
 
 # Hook to include the corresponding custom file, if present.
 $(eval $(call IncludeCustomExtension, , common/MakeBase.gmk))
--- a/make/common/Modules.gmk	Thu May 12 20:43:37 2016 +0400
+++ b/make/common/Modules.gmk	Thu May 12 11:03:07 2016 -0700
@@ -38,13 +38,12 @@
 BOOT_MODULES :=
 PLATFORM_MODULES :=
 JRE_TOOL_MODULES :=
+UPGRADEABLE_MODULES :=
+AGGREGATOR_MODULES :=
 
 # Hook to include the corresponding custom file, if present.
 $(eval $(call IncludeCustomExtension, , common/Modules.gmk))
 
-UPGRADEABLE_MDOULES :=
-AGGREGATOR_MDOULES :=
-
 BOOT_MODULES += \
     java.base \
     java.datatransfer \
@@ -73,11 +72,9 @@
 
 # to be deprivileged
 BOOT_MODULES += \
-    java.compiler \
     java.scripting \
     java.sql.rowset \
     java.smartcardio \
-    jdk.charsets \
     jdk.naming.rmi \
     #
 
@@ -104,7 +101,9 @@
     #
 
 PLATFORM_MODULES += \
+    java.compiler \
     jdk.accessibility \
+    jdk.charsets \
     jdk.crypto.ec \
     jdk.crypto.pkcs11 \
     jdk.dynalink \
@@ -129,6 +128,10 @@
   PLATFORM_MODULES += jdk.crypto.ucrypto
 endif
 
+# These modules are included in the interim image which is used to run profiling
+# before building the real images.
+INTERIM_IMAGE_MODULES := java.base java.logging
+
 ################################################################################
 # Some platforms don't have the serviceability agent
 
--- a/nashorn/.hgtags	Thu May 12 20:43:37 2016 +0400
+++ b/nashorn/.hgtags	Thu May 12 11:03:07 2016 -0700
@@ -350,3 +350,4 @@
 ba21793a0e4816283cc0ecdab5142a4959363529 jdk-9+114
 295ac208a4443d433214d0c1f32d2ea45a3a32d2 jdk-9+115
 208388a5622dcca8227d6ad6c268f2c88087d283 jdk-9+116
+5267e91811614bac129817e566f730e9d63cf22a jdk-9+117
--- a/nashorn/buildtools/nasgen/build.xml	Thu May 12 20:43:37 2016 +0400
+++ b/nashorn/buildtools/nasgen/build.xml	Thu May 12 11:03:07 2016 -0700
@@ -42,7 +42,7 @@
            destdir="${build.classes.dir}"
            debug="${javac.debug}"
            includeantruntime="false" fork="true">
-      <compilerarg value="-XaddExports:${nasgen.module.imports}"/>
+      <compilerarg line="${nasgen.module.imports}"/>
       <compilerarg value="-Xlint:unchecked"/>
       <compilerarg value="-Xlint:deprecation"/>
       <compilerarg value="-XDignore.symbol.file"/>
--- a/nashorn/buildtools/nasgen/project.properties	Thu May 12 20:43:37 2016 +0400
+++ b/nashorn/buildtools/nasgen/project.properties	Thu May 12 11:03:07 2016 -0700
@@ -40,8 +40,8 @@
 javac.debug=true
 
 nasgen.module.imports=\
-    java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED,\
-    java.base/jdk.internal.org.objectweb.asm.util=ALL-UNNAMED
+    -XaddExports:java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED \
+    -XaddExports:java.base/jdk.internal.org.objectweb.asm.util=ALL-UNNAMED
 
 meta.inf.dir=${src.dir}/META-INF
 run.classpath=\
--- a/nashorn/make/BuildNashorn.gmk	Thu May 12 20:43:37 2016 +0400
+++ b/nashorn/make/BuildNashorn.gmk	Thu May 12 11:03:07 2016 -0700
@@ -76,9 +76,10 @@
 ifeq ($(BOOT_JDK_MODULAR), true)
   NASGEN_OPTIONS := \
       -cp $(BUILDTOOLS_OUTPUTDIR)/nasgen_classes \
-      -Xpatch:$(BUILDTOOLS_OUTPUTDIR)/nasgen_classes \
+      -Xpatch:java.base=$(BUILDTOOLS_OUTPUTDIR)/nasgen_classes \
       -XaddExports:java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED \
-      -XaddExports:java.base/jdk.internal.org.objectweb.asm.util=ALL-UNNAMED
+      -XaddExports:java.base/jdk.internal.org.objectweb.asm.util=ALL-UNNAMED \
+      #
 else
   NASGEN_OPTIONS := \
       -Xbootclasspath/p:$(BUILDTOOLS_OUTPUTDIR)/nasgen_classes
--- a/nashorn/make/build-nasgen.xml	Thu May 12 20:43:37 2016 +0400
+++ b/nashorn/make/build-nasgen.xml	Thu May 12 11:03:07 2016 -0700
@@ -36,7 +36,7 @@
                 <pathelement location="${basedir}/jcov2/lib/jcov_j2se_rt.jar"/>
                 <pathelement location="${basedir}/buildtools/nasgen/dist/nasgen.jar"/>
             </classpath>
-            <jvmarg value="-XaddExports:${nasgen.module.imports}"/>
+            <jvmarg line="${nasgen.module.imports}"/>
             <arg value="${nashorn.module.classes.dir}"/>
             <arg value="jdk.nashorn.internal.objects"/>
             <arg value="${nashorn.module.classes.dir}"/>
--- a/nashorn/make/build.xml	Thu May 12 20:43:37 2016 +0400
+++ b/nashorn/make/build.xml	Thu May 12 11:03:07 2016 -0700
@@ -35,7 +35,6 @@
     <path id="nashorn.jar.path">
          <pathelement location="${nashorn.jar}"/>
     </path>
-    <property name="nashorn.override.option" value="-Xpatch:${build.classes.dir}"/>
     <condition property="svn.executable" value="/usr/local/bin/svn" else="svn">
       <available file="/usr/local/bin/svn"/>
     </condition>
@@ -176,6 +175,10 @@
       <compilerarg value="-Xdiags:verbose"/>
       <compilerarg value="-parameters"/>
     </javac>
+    <!-- -Xpatch does not like module-info.class files! -->
+    <delete>
+      <fileset dir="${build.classes.dir}" includes="**/module-info.class"/>
+    </delete>
     <javac srcdir="${nashorn.module.src.dir}"
            destdir="${nashorn.module.classes.dir}"
            source="${javac.source}"
@@ -187,8 +190,12 @@
       <compilerarg value="-XDignore.symbol.file"/>
       <compilerarg value="-Xdiags:verbose"/>
       <compilerarg value="-parameters"/>
-      <compilerarg value="${nashorn.override.option}"/>
+      <compilerarg line="${nashorn.override.option}"/>
     </javac>
+    <!-- -Xpatch does not like module-info.class files! -->
+    <delete>
+      <fileset dir="${build.classes.dir}" includes="**/module-info.class"/>
+    </delete>
     <javac srcdir="${nashorn.shell.module.src.dir}"
            destdir="${nashorn.shell.module.classes.dir}"
            source="${javac.source}"
@@ -200,7 +207,7 @@
       <compilerarg value="-XDignore.symbol.file"/>
       <compilerarg value="-Xdiags:verbose"/>
       <compilerarg value="-parameters"/>
-      <compilerarg value="${nashorn.override.option}"/>
+      <compilerarg line="${nashorn.override.option}"/>
     </javac>
     <!-- -Xpatch does not like module-info.class files! -->
     <delete>
@@ -348,11 +355,11 @@
            debug="${javac.debug}"
            encoding="${javac.encoding}"
            includeantruntime="false" fork="true">
-        <compilerarg value="${nashorn.override.option}"/>
+        <compilerarg line="${nashorn.override.option}"/>
         <compilerarg value="-Xlint:unchecked"/>
         <compilerarg value="-Xlint:deprecation"/>
         <compilerarg value="-Xdiags:verbose"/>
-        <compilerarg value="-XaddExports:${test.module.imports}"/>
+        <compilerarg line="${test.module.imports}"/>
     </javac>
 
     <copy todir="${build.test.classes.dir}/META-INF/services">
--- a/nashorn/make/project.properties	Thu May 12 20:43:37 2016 +0400
+++ b/nashorn/make/project.properties	Thu May 12 11:03:07 2016 -0700
@@ -47,6 +47,11 @@
 build.zip=${build.dir}/nashorn.zip
 build.gzip=${build.dir}/nashorn.tar.gz
 
+nashorn.override.option=\
+ -Xpatch:jdk.scripting.nashorn=${build.classes.dir}/jdk.scripting.nashorn \
+ -Xpatch:jdk.scripting.nashorn.shell=${build.classes.dir}/jdk.scripting.nashorn.shell \
+ -Xpatch:jdk.dynalink=${build.classes.dir}/jdk.dynalink
+
 # project directory of <nashorn> ant task
 nashorntask.dir=buildtools/nashorntask
 
@@ -57,8 +62,8 @@
 nasgen.tool=jdk.nashorn.internal.tools.nasgen.Main
 
 nasgen.module.imports=\
-    java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED,\
-    java.base/jdk.internal.org.objectweb.asm.util=ALL-UNNAMED
+    -XaddExports:java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED \
+    -XaddExports:java.base/jdk.internal.org.objectweb.asm.util=ALL-UNNAMED
 
 # parallel test runner tool
 parallel.test.runner=jdk.nashorn.internal.test.framework.ParallelTestRunner
@@ -132,19 +137,19 @@
     ${file.reference.snakeyaml.jar}
 
 test.module.imports=\
-    jdk.scripting.nashorn/jdk.nashorn.internal.ir=ALL-UNNAMED,\
-    jdk.scripting.nashorn/jdk.nashorn.internal.codegen=ALL-UNNAMED,\
-    jdk.scripting.nashorn/jdk.nashorn.internal.parser=ALL-UNNAMED,\
-    jdk.scripting.nashorn/jdk.nashorn.internal.objects=ALL-UNNAMED,\
-    jdk.scripting.nashorn/jdk.nashorn.internal.runtime=ALL-UNNAMED,\
-    jdk.scripting.nashorn/jdk.nashorn.internal.runtime.doubleconv=ALL-UNNAMED,\
-    jdk.scripting.nashorn/jdk.nashorn.internal.runtime.linker=ALL-UNNAMED,\
-    jdk.scripting.nashorn/jdk.nashorn.internal.runtime.events=ALL-UNNAMED,\
-    jdk.scripting.nashorn/jdk.nashorn.internal.runtime.options=ALL-UNNAMED,\
-    jdk.scripting.nashorn/jdk.nashorn.internal.runtime.regexp=ALL-UNNAMED,\
-    jdk.scripting.nashorn/jdk.nashorn.internal.runtime.regexp.joni=ALL-UNNAMED,\
-    jdk.scripting.nashorn/jdk.nashorn.tools=ALL-UNNAMED,\
-    java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED
+    -XaddExports:jdk.scripting.nashorn/jdk.nashorn.internal.ir=ALL-UNNAMED \
+    -XaddExports:jdk.scripting.nashorn/jdk.nashorn.internal.codegen=ALL-UNNAMED \
+    -XaddExports:jdk.scripting.nashorn/jdk.nashorn.internal.parser=ALL-UNNAMED \
+    -XaddExports:jdk.scripting.nashorn/jdk.nashorn.internal.objects=ALL-UNNAMED \
+    -XaddExports:jdk.scripting.nashorn/jdk.nashorn.internal.runtime=ALL-UNNAMED \
+    -XaddExports:jdk.scripting.nashorn/jdk.nashorn.internal.runtime.doubleconv=ALL-UNNAMED \
+    -XaddExports:jdk.scripting.nashorn/jdk.nashorn.internal.runtime.linker=ALL-UNNAMED \
+    -XaddExports:jdk.scripting.nashorn/jdk.nashorn.internal.runtime.events=ALL-UNNAMED \
+    -XaddExports:jdk.scripting.nashorn/jdk.nashorn.internal.runtime.options=ALL-UNNAMED \
+    -XaddExports:jdk.scripting.nashorn/jdk.nashorn.internal.runtime.regexp=ALL-UNNAMED \
+    -XaddExports:jdk.scripting.nashorn/jdk.nashorn.internal.runtime.regexp.joni=ALL-UNNAMED \
+    -XaddExports:jdk.scripting.nashorn/jdk.nashorn.tools=ALL-UNNAMED \
+    -XaddExports:java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED
 
 meta.inf.dir=${nashorn.module.src.dir}/META-INF
 
@@ -342,8 +347,8 @@
 
 run.test.jvmargs.common=\
   -server \
-  -XaddExports:${test.module.imports} \
-  -Xpatch:${build.classes.dir} \
+  ${test.module.imports} \
+  ${nashorn.override.option} \
   -Dfile.encoding=UTF-8 \
   -Duser.language=${run.test.user.language} \
   -Duser.country=${run.test.user.country} \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/linker/NashornLinkerExporter.java	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.nashorn.api.linker;
+
+import java.util.List;
+import jdk.dynalink.linker.GuardingDynamicLinker;
+import jdk.dynalink.linker.GuardingDynamicLinkerExporter;
+import jdk.nashorn.internal.runtime.linker.Bootstrap;
+
+/**
+ * This linker exporter is a service provider that exports Nashorn Dynalink
+ * linkers to external users. Other languague runtimes that use Dynalink
+ * can use the linkers exported by this provider to support tight integration
+ * of Nashorn objects.
+ */
+public final class NashornLinkerExporter extends GuardingDynamicLinkerExporter {
+    /**
+     * The default constructor.
+     */
+    public NashornLinkerExporter() {}
+
+    /**
+     * Returns a list of exported nashorn specific linkers.
+     *
+     * @return list of exported nashorn specific linkers
+     */
+    @Override
+    public List<GuardingDynamicLinker> get() {
+        return Bootstrap.getExposedLinkers();
+    }
+}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java	Thu May 12 20:43:37 2016 +0400
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java	Thu May 12 11:03:07 2016 -0700
@@ -4711,7 +4711,7 @@
         expect(ARROW);
 
         final long functionToken = Token.recast(startToken, ARROW);
-        final IdentNode name = new IdentNode(functionToken, Token.descPosition(functionToken), "=>:" + functionLine);
+        final IdentNode name = new IdentNode(functionToken, Token.descPosition(functionToken), NameCodec.encode("=>:") + functionLine);
         final ParserContextFunctionNode functionNode = createParserContextFunctionNode(name, functionToken, FunctionNode.Kind.ARROW, functionLine, null);
         functionNode.setFlag(FunctionNode.IS_ANONYMOUS);
 
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java	Thu May 12 20:43:37 2016 +0400
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java	Thu May 12 11:03:07 2016 -0700
@@ -33,6 +33,8 @@
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodHandles.Lookup;
 import java.lang.invoke.MethodType;
+import java.util.Collections;
+import java.util.List;
 import jdk.dynalink.CallSiteDescriptor;
 import jdk.dynalink.DynamicLinker;
 import jdk.dynalink.DynamicLinkerFactory;
@@ -70,6 +72,7 @@
     private static final BeansLinker beansLinker = new BeansLinker(Bootstrap::createMissingMemberHandler);
     private static final GuardingDynamicLinker[] prioritizedLinkers;
     private static final GuardingDynamicLinker[] fallbackLinkers;
+
     static {
         final NashornBeansLinker nashornBeansLinker = new NashornBeansLinker(beansLinker);
         prioritizedLinkers = new GuardingDynamicLinker[] {
@@ -90,6 +93,19 @@
     }
 
     /**
+     * Returns a list of exposed nashorn dynalink linkers.
+     *
+     * @return a list of exposed nashorn dynalink linkers.
+     */
+    public static List<GuardingDynamicLinker> getExposedLinkers() {
+        // we have to create BeansLinker without nashorn specific missing member handler!
+        // Or else, we'd return values such as 'undefined' to the external world!
+        final NashornBeansLinker nbl = new NashornBeansLinker(new BeansLinker());
+        final JSObjectLinker linker = new JSObjectLinker(nbl);
+        return Collections.singletonList(linker);
+    }
+
+    /**
      * Creates a Nashorn dynamic linker with the given app class loader.
      * @param appLoader the app class loader. It will be used to discover
      * additional language runtime linkers (if any).
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java	Thu May 12 20:43:37 2016 +0400
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java	Thu May 12 11:03:07 2016 -0700
@@ -71,6 +71,9 @@
     public GuardedInvocation getGuardedInvocation(final LinkRequest request, final LinkerServices linkerServices) throws Exception {
         final Object self = request.getReceiver();
         final CallSiteDescriptor desc = request.getCallSiteDescriptor();
+        if (self == null || !canLinkTypeStatic(self.getClass())) {
+            return null;
+        }
 
         GuardedInvocation inv;
         if (self instanceof JSObject) {
@@ -82,7 +85,7 @@
             inv = new GuardedInvocation(beanInv.getInvocation(),
                 NashornGuards.combineGuards(beanInv.getGuard(), NashornGuards.getNotJSObjectGuard()));
         } else {
-            throw new AssertionError(); // Should never reach here.
+            throw new AssertionError("got instanceof: " + self.getClass()); // Should never reach here.
         }
 
         return Bootstrap.asTypeSafeReturn(inv, linkerServices, desc);
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/tools/Shell.java	Thu May 12 20:43:37 2016 +0400
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/tools/Shell.java	Thu May 12 11:03:07 2016 -0700
@@ -541,7 +541,7 @@
             @Override
             protected Expression assignmentExpression(final boolean noIn) {
                 exprStart[0] = this.start;
-                return super.expression();
+                return super.assignmentExpression(noIn);
             }
         };
 
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/module-info.java	Thu May 12 20:43:37 2016 +0400
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/module-info.java	Thu May 12 11:03:07 2016 -0700
@@ -38,6 +38,10 @@
     exports jdk.nashorn.tools to
         jdk.scripting.nashorn.shell;
 
-    provides javax.script.ScriptEngineFactory with jdk.nashorn.api.scripting.NashornScriptEngineFactory;
+    provides javax.script.ScriptEngineFactory
+        with jdk.nashorn.api.scripting.NashornScriptEngineFactory;
+
+    provides jdk.dynalink.linker.GuardingDynamicLinkerExporter
+        with jdk.nashorn.api.linker.NashornLinkerExporter;
 }
 
--- a/nashorn/test/TEST.ROOT	Thu May 12 20:43:37 2016 +0400
+++ b/nashorn/test/TEST.ROOT	Thu May 12 11:03:07 2016 -0700
@@ -8,4 +8,7 @@
 groups=TEST.groups
 
 # Minimum jtreg version
-requiredVersion=4.2 b01
+requiredVersion=4.2 b02
+
+# Use new form of -Xpatch
+useNewXpatch=true
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8144711.js	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,36 @@
+/*
+ * 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-8144711: (x) => x + 1 causes Assertion failure instead of SyntaxError
+ *
+ * @test
+ * @run
+ */
+
+try {
+    eval("(x) => x + 1");
+    throw new Error ("should not reach here");
+} catch (e) {
+    Assert.assertTrue(e instanceof SyntaxError);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/JDK-8156492.js	Thu May 12 11:03:07 2016 -0700
@@ -0,0 +1,35 @@
+/*
+ * 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-8156492: ClassFormatError thrown when arrow function is used
+ *
+ * @test
+ * @run
+ * @option --language=es6
+ */
+
+Assert.assertTrue((x=>x*2)(3) == 6);
+Assert.assertTrue(((x,y)=>x+y)("hello", "world") == "helloworld");
+var arr = [4, 89, 69];
+Assert.assertTrue(arr.map(x=>x+1).toString() == "5,90,70");
--- a/nashorn/test/src/jdk/dynalink/test/DynamicLinkerFactoryTest.java	Thu May 12 20:43:37 2016 +0400
+++ b/nashorn/test/src/jdk/dynalink/test/DynamicLinkerFactoryTest.java	Thu May 12 11:03:07 2016 -0700
@@ -30,10 +30,13 @@
 import java.lang.invoke.MethodType;
 import java.util.List;
 import java.util.ServiceConfigurationError;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
 import jdk.dynalink.CallSiteDescriptor;
 import jdk.dynalink.DynamicLinker;
 import jdk.dynalink.DynamicLinkerFactory;
 import jdk.dynalink.NoSuchDynamicMethodException;
+import jdk.dynalink.NamedOperation;
 import jdk.dynalink.Operation;
 import jdk.dynalink.StandardOperation;
 import jdk.dynalink.linker.GuardingDynamicLinker;
@@ -41,6 +44,7 @@
 import jdk.dynalink.linker.LinkerServices;
 import jdk.dynalink.support.SimpleRelinkableCallSite;
 import jdk.dynalink.linker.GuardedInvocation;
+import jdk.nashorn.api.scripting.AbstractJSObject;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
@@ -254,4 +258,55 @@
 
         Assert.assertTrue(reachedAutoLinker);
     }
+
+    @Test
+    public void nashornExportedLinkerJSObjectTest() {
+        final DynamicLinkerFactory factory = newDynamicLinkerFactory(false);
+        final DynamicLinker linker = factory.createLinker();
+
+        final MethodType mt = MethodType.methodType(Object.class, Object.class);
+        final NamedOperation op = new NamedOperation(StandardOperation.GET_PROPERTY, "foo");
+        final CallSite cs = linker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor(
+                MethodHandles.publicLookup(), op, mt)));
+        final boolean[] reachedGetMember = new boolean[1];
+        // check that the nashorn exported linker can be used for user defined JSObject
+        Object obj = new AbstractJSObject() {
+                @Override
+                public Object getMember(String name) {
+                    reachedGetMember[0] = true;
+                    return name.equals("foo")? "bar" : "<unknown>";
+                }
+            };
+
+        Object value = null;
+        try {
+            value = cs.getTarget().invoke(obj);
+        } catch (Throwable th) {
+            throw new RuntimeException(th);
+        }
+
+        Assert.assertTrue(reachedGetMember[0]);
+        Assert.assertEquals(value, "bar");
+    }
+
+    @Test
+    public void nashornExportedLinkerScriptObjectMirrorTest() {
+        final DynamicLinkerFactory factory = newDynamicLinkerFactory(false);
+        final DynamicLinker linker = factory.createLinker();
+
+        // check that the nashorn exported linker can be used for ScriptObjectMirror
+        final ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
+        final MethodType mt = MethodType.methodType(Object.class, Object.class);
+        final NamedOperation op = new NamedOperation(StandardOperation.GET_PROPERTY, "foo");
+        final CallSite cs = linker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor(
+                MethodHandles.publicLookup(), op, mt)));
+        Object value = null;
+        try {
+            final Object obj = engine.eval("({ foo: 'hello' })");
+            value = cs.getTarget().invoke(obj);
+        } catch (Throwable th) {
+            throw new RuntimeException(th);
+        }
+        Assert.assertEquals(value, "hello");
+    }
 }